Skip to content

Issue 752 add support for slug in collections#3

Closed
nicolam1 wants to merge 2 commits intostrapi:masterfrom
nicolam1:feature/752-slug-support
Closed

Issue 752 add support for slug in collections#3
nicolam1 wants to merge 2 commits intostrapi:masterfrom
nicolam1:feature/752-slug-support

Conversation

@nicolam1
Copy link

@nicolam1 nicolam1 commented Jul 18, 2019

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

@nicolam1 nicolam1 changed the title Issuer 752 add support for slug in collections Issue 752 add support for slug in collections Jul 18, 2019
@Aurelsicoko
Copy link
Member

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:

  • If I have a field title with the value My Super Title.
    I can have a field with a generated value my-super-field. I will use a slug.
  • If I have a field description with the value My super description.
    I can have a field with a generated value 58ce35841c9d0dc47c51d1df7b8fea2b0d2cb617b72fcb08c2ec1f938324e7da. I will use it to compare if my description has changed or if my description is unique.

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

  • Allow adding more options to format the generated as we would like in the future.
  • Allow setting min & max size of the string
  • Allow setting uniqueness (or not)
  • Allow more complex hashing and generated string
  • Allow multiple slug/hashed strings for the same entry
  • Fewer updates in the Content Manager plugin.
  • Dedicated modal to push more options in the future.
  • Easier user flow.

Drawbacks

  • The URL to access to the entry is less clean http://..../movies/slug/title-3 vs http://..../movies?slug=title-3.
  • More complicated approach for creating a slug field.

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

@nicolam1
Copy link
Author

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

  • Allow setting min & max can still be added
  • Allow uniqueness or not doesn't not apply to slug by definition they should always be unique if not they are useless.
  • Updates to the Content Manager are actually minimal
  • Dedicated modal can be added for managing slug extra configuration
  • User flow is arguable we are dealing with less clicks with the proposed flow especially if slugs are enable by default, since they do not have to be used.

About Drawbacks

  • The URL structure is the main SEO advantage, understood that this would most likely be an API called by some UI so it's not a real issue, but now we have to treat slug as a prop rather than a secondary ID, which is what it's for.

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
Copy link
Member

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
Copy link
Author

@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
Copy link
Member

@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
Copy link
Member

Aurelsicoko commented Jul 29, 2019

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
Copy link
Author

nicolam1 commented Jul 29, 2019

@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
Copy link
Member

@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
Copy link
Author

@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
Copy link
Member

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
Copy link
Author

nicolam1 commented Aug 1, 2019

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

@nicolam1
Copy link
Author

nicolam1 commented Aug 8, 2019

@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
Copy link
Member

@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
Copy link

@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
Copy link
Author

@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
Copy link

@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
Copy link
Member

@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
Copy link
Author

nicolam1 commented Sep 5, 2019

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

@alexandrebodin
Copy link
Member

alexandrebodin commented Sep 5, 2019

@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
Copy link
Member

alexandrebodin commented Sep 6, 2019

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:

  • I would prefer the feature to be called uid as it is supposed to be a unique identifier. slug does not convey the same meaning in my opinion. Slug is really focused on press/blog usecases.
  • I would like to know how you plan to add this uid to a model (what would look like the Model.settings.json file after that)
  • As this feature adds a column to the database table I would like to be able to choose the column name.
  • What happens when someone adds a field called uid and then goes in the configuration and wants to enable the uid ? We should have only one way to do one thing (e.g add a field whatever the type it is uid in this case)
  • If a user changes the field the uid is related to, the input changes position. It feels really strange in terms of UX to have a field that changes position without control. @Aurelsicoko Should we make it a field at the top of the page or in the side bard of the edit view ?
  • If the user deletes the field that the uid is related to what happens ?
  • Can someone automate the uid generation in the back so that a content editor doesn't have to see this field in the edit view ?
  • When does the UID uniquness should be verified ?

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
Copy link
Member

@alexandrebodin

  • The UID field will be visible only on the right side of the edit view (see the picture below)
  • Do you really think the UID should be considered as a field?
    IMO, we could consider it as an option. And this makes all the difference. You don't need to see the field in the Model.settings.json file, you can provide a dedicated route (if necessary), you avoid any kind of deletion through files, etc. You have better control over it.
  • The UID generation could be handled by the backend. Do we really need to add it in the current scope of the feature? No, if the UID is SEO-friendly that enough, for now. In any case, thanks to our layout feature in the Edit view (we have to improve it), we could hide the UID input on the right side of the page.

@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
Copy link
Member

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

  • The UID MUST be unique.
  • The UID MUST be URL-friendly (no special characters, no spaces, etc).
  • We SHOULD be able to filter on that field, it doesn't cost anything to do that even if we cannot see a use case.
  • The UID MUST be editable.
  • The UID format SHOULD NOT be configurable for now.
  • WE MUST treat it as a field in the Model.settings.json file.
  • We SHOULD able to custom the model field name and the column name.
  • We SHOULD have a new type UID.
  • We MUST be able to enable the UID feature if there are one or more text fields in the content-type.
  • If the user DELETE the field that the UID relies on, we SHOULD use another field text to generate it. If there is no field text, we MUST generate a UID with the uuid library.
  • We SHOULD verify the uniqueness in the Content Manager when the user saves.

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
Copy link
Member

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
Copy link
Member

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

@cebreus
Copy link

cebreus commented Oct 3, 2019

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
Copy link

cebreus commented Oct 7, 2019

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
Copy link
Author

nicolam1 commented Mar 5, 2020

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

@nicolam1 nicolam1 closed this Mar 5, 2020
@nicolam1 nicolam1 deleted the feature/752-slug-support branch March 5, 2020 13:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants