strapi / rfcs

RFCs for Strapi future changes
70 stars 33 forks source link

Issue 752 add support for slug in collections #3

Closed nicolam1 closed 4 years ago

nicolam1 commented 5 years ago

This PR is to describe the slug functionality that we have built for strapi collections. We have a working version ready for PR though I would like to get the design approved before submitting the code

Edit: Link to see the RFC

Aurelsicoko commented 5 years ago

First of all, thank you so much for opening this RFC! The community is asking for the support of slug for a long time ago. I'm super excited to be able to dig deeper into the problem here.

Context

People ask for the support of a slug field in large part because there have SEO issues. They need an easy way to generate a unique slug for each entry of their content-type. Like you said, sometimes you cannot be satisfied by the generated slug, and you have to be able to customise it following your own needs.

Scope

From my understanding, the slug field can be much more than a generated string with dashes (e.g my-super-slug). To me, the slug field works like a hash. It's another representation of an existing field in the content-type. See the examples below:

That's why I think the slug field is very limited. I would prefer to introduce a new field called "Hash" but limit his scope to be only used as a slug for now.

Proposal

Everything should happen in the Content-Type Builder plugin, not the Content Manager (I understand why you did it though, I'll come back on it after).

User flow

  1. Create a new Content-Type (e.g. Movies) as you will normally do.
  2. Add fields to your Content-Type (title, description, images).
  3. Select the Hash field, and give a name (e.g. slug). Popup - Add New Field@2x
  4. Select the attached field. Popup - Add New Slug Field - Base Settings@2x
  5. Repeat the process, if you want another.

Advantages

Drawbacks

What are your thoughts? Would it be more complicated to implement? I'm looking forward to reading your answer.

nicolam1 commented 5 years ago

Thank you for the comments above I wasn't aware when building the slug of the intent of having it support multiple features. We based our implementation on the initial issue requirements, comments and on the slug implementation from wordpress.

In publishing a slug is defined as a short name given to an article that is in production. The story is labeled with its slug as it makes its way from the reporter through the editorial process. ... In the production process of print advertisements, a slug or slug line, refers to the "name" of a particular advertisement.

This is why we treated as something that can enabled at the Content Type level and changed also at the Content Manager level as it's a unique property for a Content Type.

That said I do like the hash field idea as it could be very useful but I'm not sure mixing it with the slug makes a lot of sense as they solve two different problems. Sure it can solve the slug but it also will end up having a lot more logic to it once we support different hashing rules.

About Advantages

About Drawbacks

Personally I love the idea of the hash and I think it would work better if separated from the slug. Happy to implement that as well if the community wants it.

Aurelsicoko commented 5 years ago

I agree with you. I wanted to explain the global idea behind the slug. At this time, we could name the field type Slug instead of Hash in the Content-Type Builder plugin.

The purpose of my message was to explain a long-term vision. I would prefer to see the slug integrated into the Content-Type Builder plugin to keep the data structure management separated from the layout. Moreover, the user flow (I've proposed) is closer to the one currently being.

I think the best solution is a balance between both solutions.


User flow

  1. Create a new Content-Type (e.g. Movies) as you will normally do.
  2. Add fields to your Content-Type (title, description, images).
  3. Select the Slug field (you cannot set the name, it will be slug).
  4. Select the attached field for the slug field.

Note: the slug field can only be selected once.

nicolam1 commented 5 years ago

@Aurelsicoko sorry for the delay here I've been traveling. So I'm not against this flow but there is one thing that I'm not a big fan of. Currently all the new fields do not have limitations as to how many I can add and when I should use them.

If we follow the approach you suggested slug would be the only field type that gets disabled after one use. Which makes perfect sense as it's a secondary ID at the end of the day. It is also the only type that you cannot set a name for.

That's why I thought having it as a content type settings rather than a property makes more sense. It's like enabling a secondary ID for that specific content type.

Does that make sense?

Aurelsicoko commented 5 years ago

@nicolam1 Yes, I understand your point of view, but as I said, the slug type is temporary and it will be something bigger thereafter (hashes, custom format, composed value, etc). Others CMS have the exact same behaviour, and I'm pretty sure we could find cases when you need more than a single slug.

In any case, I think we should not let the users configure the settings through the Content Manager plugin. Everything should be handled in the Content-Type Builder plugin. The Content Manager settings are limited to display settings, they don't affect the data structure at all, and we should keep it like that.

Aurelsicoko commented 5 years ago

Upon reflection, both solutions work. The difference is the vision behind. I'll try to explain the best as I can. The approach is different... your solution solves the issue. The solution I propose as well but it doesn't implement the slug as a core feature. It means that the slug is only a new field type as the map could be another one. The impacts are different too. Whereas yours will impact the settings of the Content Manager, mine won't. I don't say that mine is better, but I think it's great to explain the difference because it could be a great start writing the product vision behind.

When people are using Strapi, they don't have the feeling to be limited. Everything is agnostic, generic and customisable. It is our motto. By integrating the slug as a core feature, we are breaking that motto. To give you a concrete example, watch the screenshot below.

image

The slug feature is integrated at the heart of the product. The question is: "How many content-types do really need the slug"? If you create a blog, you only need to have slugs for the Article or the Category. The Tags and Comments, or Users don't need the feature.

In other words, we add options in the UI whereas they aren't necessary for each content-type. When we apply this to the long-term vision, we have to take care of the choices we are going to make. Another question is how we will integrate more features like Draft/Archive, Log History, Entry Ownership? Are we going to add more and more options in the modal or can we find another way to integrate them?

The previous example still works for the list of feature listed above.. we will only need to enable the Draft/Archive feature for the Article, and the history of the log for the Article and Comments.

To give another concrete example, it's like disabling the touch bar on your MacBook Pro but the touch bar is still here at its core. Or you can't add the option of the Apple website to add the touch bar to your MacBook Pro because you know you will need it.


My goal is to preserve the product, the ease of use and the product vision applied to Strapi. I don't want to blame you and the solution you proposed. I think that case is very interesting and that's why I want to explain how things have been designed until now. We don't want that Strapi becomes a tank full of features as WordPress, Drupal or other CMSs are. We want to keep it light without adding useless features at its core. I'm not sure the slug should be integrated at its core but I'm not against the idea to do it...

PS: Sorry for the long answer 🙈

nicolam1 commented 5 years ago

@Aurelsicoko actually thank you for the long explanation it gives me more understanding of the overall goal. Now I do have a question and I apologize if I'm not still 100% clear on this. There are two plugins that we touched one is Content Type which to me makes sense to have the slug feature as a setting as it allows me to turn it on and off when i create it.

content type

And then we have the content manager which seems the one you don't want to do, which now that you have explained I agree on the approach content manager

What if we remove it from the content manager plugin? would that do it? or is also the approach on content type wrong?

The other option I see if not is to make it a plugin where you can configure only the content types you want to have a slug that way it doesn't touch any of the existing functionality.

Aurelsicoko commented 5 years ago

@nicolam1 Thank you for your understanding. I think we should find a way to enable the slug feature when the user is defining the structure (fields) of the content-type.

The issue we have with the following implementation is that when you create a new content-type, you don't have defined the fields yet and you cannot select which field to refer to generate the slug. It doesn't make the user flow easy.

image

What if we add a new settings box to enable the slug when the user has added the first field of the content-type? If there are no fields, the settings box isn't visible.

Screenshot 2019-07-30 at 18 21 50

Even if sometimes you'll have to scroll to see the box (if you have a lot of fields), the slug is mostly generated using one of the first fields. The developer won't miss the settings box when defining the fields.


Otherwise, we can add a new step. The first will be the definition of the fields, the second and last one will be the configurations of the option.

Content Type view

Configuration view

What are your thoughts? I think the last one will take more time to implement and could be very useful when we will have many options to configure. The first one seems easy to implement even if the UX (scroll issues, visibility) isn't optimal.

nicolam1 commented 5 years ago

@Aurelsicoko I love the last option with the new step I think that keeps the flow simple and and definitively easier to follow. It also sets the flow for future features as well. I guess the question would be do we do the same when we update a content type? Let me see how long to refactor but should not be a big deal.

Aurelsicoko commented 5 years ago

I think we should not keep the step during the edit because I could be annoying when repeating the process. I would add a "Configure" button at the left of the "Save" button instead when editing.

nicolam1 commented 5 years ago

Sure that works too. Would you like to mock it or should I?

nicolam1 commented 5 years ago

@Aurelsicoko I've updated the rfcs with the latest mocks we did based on your feedback. You can review them here. We also have a code PR ready to go. Let me know how we should proceed with this.

Aurelsicoko commented 5 years ago

@nicolam1 Sorry for the delay. The Content-Type Builder part seems pretty good to me. Excellent work! I still have a concern in the Edit view of the Content Manager. Did you test the edit of the slug field with a more complicated layout?

Why not use the right side which is a bit empty now to let the user edit the slug? FYI, everything (label, input, text) is aligned on a baseline of 18px to make the interface easily readable and avoid "eyes fatigue".

Screenshot 2019-08-28 at 11 27 00

The slug when enabled will always be visible and editable in a separate right container. It will be certainly the container when we will put all the other options like Draft/Publish and ownership. What do you think?

Thank you so much for your commitment, it means a lot to us. I will try my best to be more reactive to be able to merge the feature asap.

soupette commented 5 years ago

@nicolam1 @Aurelsicoko wow! This is really interesting!

Just allow to jump in a little in the discussion; I do really think that the solution found for the Content Type Builder is the best one, I do not really want to see more fields in the modals as they are already really "heavy" and adding a step before saving the modifications will be very useful for later when we add further options.

I also agree with the modifications added to the content manager, adding the slug field in the right column is the best as it does not mess with the layout!

Now I know that you guys are ready to make a PR for this feature however... the codebase of the content manager completely changed: the layout has been fixed and recoded, in fact the entire has been migrated to react-hooks and styled-components, so... I am afraid that most of the work you did has to be re developed again (I am truly sorry about that). The new code is currently merge on the develop branch if you want to take a look.

Let me know if I can be of any help, but I would love to see such contribution in the administration panel!

nicolam1 commented 5 years ago

@soupette how stable is the development branch? I don't mind moving the code we did against that branch if that's stable enough. @Aurelsicoko I don't have an issue with the right side aside from the fact that you lose the context of which property is used for the slug. If that's ok we can refactor it that way.

soupette commented 5 years ago

@nicolam1 it's more stable than master! We did a lot of bugs fix.

I don't have an issue with the right side aside from the fact that you lose the context of which property is used for the slug.

Maybe we can add some information in the field's label or its description?

Aurelsicoko commented 5 years ago

@soupette how stable is the development branch? I don't mind moving the code we did against that branch if that's stable enough. @Aurelsicoko I don't have an issue with the right side aside from the fact that you lose the context of which property is used for the slug. If that's ok we can refactor it that way.

I don't think it is a big deal to lose the context in that case... we could add a popover on the slug label in the right column "Generated from xxxx field".

If you are okay with it, let's do it! I'm so excited about this PR, it's going to be massive for the community 😍

nicolam1 commented 5 years ago

@Aurelsicoko we'll have the PR out today for it.

alexandrebodin commented 5 years ago

@nicolam1 Thank you for this but I am rolling back on what we told you. I'm sorry for that but we need to be more consitent with the rfc process :/

Please do not open the PR as this rfcs hasn't been approved for now. We will not be considering the PR as long as the rfc is not in "active" state as in the RFC process doc.

Thank you for your efforts. I will be making some comments asap to move this forward!

alexandrebodin commented 5 years ago

Hi @nicolam1, I think the functional description is pretty good but I need more informations to be written in the RFC concerning the following points:

API

I don't really like the idea of adding a route specifically to get an entity by uid. The first reason to use the uid is to have use it for url on your final website. I think we have to keep the current API for the initial release of this feature and eventually consider making more changes if it become a pain point.

Aurelsicoko commented 5 years ago

@alexandrebodin

@nicolam1 FYI, I will have a meeting with @alexandrebodin next week to scope a bit better the feature and ensure we have the same vision of what we are trying to achieve here. We will come back to you soon.


image

Aurelsicoko commented 5 years ago

@nicolam1 We made our workshop with @alexandrebodin, please find the specifications we write below:


I would like to apologize for the work you did and that won't be used, especially from an interface point of view. We will work by iteration and the configuration page isn't necessary for now.

It is better to treat the UID as a field and add it in the modal of fields selection. Then, all the options to custom the field itself will follow the same process as it is actually. It will also avoid the users to miss the feature and try to create by themselves a kind of UID field by using a text field, then create by hand a slug. If the UID is a field visible in the modal, the users cannot miss it.

Even in the backend, it means that the field will be added to the Model.settings.json file.

PS: I'm going to provide a design in the next hours to help you to understand the choices made.

Aurelsicoko commented 5 years ago

New UID field.

Screenshot 2019-09-12 at 14 56 31

UID field already added to the content-type, it cannot be selected anymore.

Screenshot 2019-09-12 at 14 00 04

Attach the field to generate the UID and give a name to the UID field. We should give a default value such as uid or slug.

Screenshot 2019-09-12 at 15 12 52

Configure the options to custom the collection name.

Screenshot 2019-09-12 at 15 06 54

Then, it'll look like in the Content Manager. image

Aurelsicoko commented 5 years ago

FYI, the default, required and unique options don't make sense in my screenshot. It's a mistake. However, other validations are valid.

cebreus commented 5 years ago

Hi there, I have some comment on the information posted on this issue.

Uniqueness of the URL slug

I have must disagree with the uniqueness of the URL slug. From the SEO point of the view URL MUST be unique as the whole sentence include the protocol (https). We must be able to have these URLs:

https://www.domain.com/repertoire/shanti-mantra https://www.domain.com/contemporary-dance/shanti-mantra

"shanti-mantra" is the URL slug. We need to have canonical URLs.

Format of the URL slug

URL slug must be webalized (for example)[https://www.npmjs.com/package/webalize#webalize]. In the basics, this means, all non-ASCII characters must be correctly replaced for ASCII (Cyrillic or Arabic alphabet). Using UTF-8 characters is not fully supported.

Example of the replace: »BÝT ČI NEBÝT?« > byt-ci-nebyt Быть или не быть? > byt-ili-ne-byt

More info about URI: Transcription and Reserved Characters

Multiple URL for one content (article)

Allowing multiple URLs for one entry can be done only in case using canonical meta tag as reference. Short info about canonical and URL duplicates.

Allow setting min & max

This technical limit of the maximum length of the URI (as the whole sentence). Please read specification before implementation.

Integrating the slug as a core feature

I think that is must to have functionality. In a normal scenario, URL slug will be prefilled from the Title of the Article and can be changed by the user. In the advanced scenario, the developer will be able to define own structure for automatic prefilling of the slug. For example YYYY-MM-DD-name-of-the-article date and title of the article.

Placement of the URL slug field

We should consider longer slugs and space for error and warning alerts. I do not like placement in the right column.

Where will be data of the URL slug stored?

I love to have them in the Content Type Builder as filed. This field is very important for SEO specialist which we are coworking. They need this field visible and easily readable. Placement in the right column causes worse readability. I the view of the content — URL is the most important thing after the content itself. URL is linked directly to content — the field in the Content Type Builder make me sense.

Draft/Archive

This is a good point because this functionality will bring Strapi more close to the bigger and older CMSs. We need this functionality for the next three projects.

cebreus commented 5 years ago

For a better understanding of the whole SEO setting, see image below. This is actual functionality, what we need to implement into Strapi.

Strapi - Content Manager - SEO

nicolam1 commented 4 years ago

I see the UID implementation on the latest release declining as it's now part of the project. Thank you for the feature