Experiment: Auto fill slug from singular label for taxonomies and post types#77938
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
Size Change: +952 B (+0.01%) Total Size: 7.91 MB 📦 View Changed
ℹ️ View Unchanged
|
|
Flaky tests detected in c09a8df. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/25367568231
|
tyxla
left a comment
There was a problem hiding this comment.
Nice improvement 👍
I think this is shippable as-is, but there are a few things to consider before or after shipping.
Also it's a bummer we're introducing a bunch of duplicated code. Should we start looking at how we reuse it?
| const onFocus = () => { | ||
| if ( data.id !== undefined || data.slug ) { | ||
| return; | ||
| } | ||
| const singular = data.config.labels.singular_name?.trim(); | ||
| if ( ! singular ) { | ||
| return; | ||
| } | ||
| const cleaned = cleanForSlug( singular ); | ||
| // On a fresh record fill the input from the singular label. | ||
| // Skip auto-fill if cleanForSlug retained non-ASCII to match | ||
| // the server's sanitize_key charset. | ||
| if ( /[^a-z0-9_-]/.test( cleaned ) ) { | ||
| return; | ||
| } | ||
| const trimmed = cleaned | ||
| .slice( 0, SLUG_MAX_LENGTH ) | ||
| // Slicing can introduce a trailing hyphen — strip it. | ||
| .replace( /-+$/, '' ); | ||
| if ( trimmed ) { | ||
| handleChange( trimmed ); | ||
| } |
There was a problem hiding this comment.
One of the issues of this logic is that if we use a singular label matching an existing post type (like Post, it will preflll the slug with post and error out since it exists. We might need to improve that handling so we don't suggest a slug that matches an existing one.
There was a problem hiding this comment.
Added it in the tracking issue for a follow up.
There was a problem hiding this comment.
I think we can solve this in one of two ways. First, we can validate before suggesting a slug. This way, if the slug that is about to be suggested is already registered, we can simply leave it blank for the user to fill in.
The second option, which I feel is more practical, is to suffix the suggested slug with a number if it already exists. For example, post could become post-n. This would require multiple validations because, if post has already been used five times, we would end up checking post, post-2, post-3, post-4, and finally post-5, which is what we would eventually suggest to the user. This approach would require us to determine the next available suffix number. Ref
Personally, I would choose the second option if we must suggest a slug. Otherwise, a simpler approach would be to leave it blank and let the user input the slug manually, while we validate it each time they type one in. This would be cleaner to implement, though the UX implications might need some consideration.
I am looking forward to hearing your thoughts. Once we reach some consensus, I would be happy to implement this.
cc: @ntsekouras @tyxla
There was a problem hiding this comment.
@im3dabasia I see you've opened a PR for that, let's discuss there: #78341
| const onFocus = () => { | ||
| if ( data.id !== undefined || data.slug ) { | ||
| return; | ||
| } | ||
| const singular = data.config.labels.singular_name?.trim(); | ||
| if ( ! singular ) { | ||
| return; | ||
| } | ||
| const cleaned = cleanForSlug( singular ); | ||
| // On a fresh record fill the input from the singular label. | ||
| // Skip auto-fill if cleanForSlug retained non-ASCII to match | ||
| // the server's sanitize_key charset. | ||
| if ( /[^a-z0-9_-]/.test( cleaned ) ) { | ||
| return; | ||
| } | ||
| const trimmed = cleaned | ||
| .slice( 0, SLUG_MAX_LENGTH ) | ||
| // Slicing can introduce a trailing hyphen — strip it. | ||
| .replace( /-+$/, '' ); | ||
| if ( trimmed ) { | ||
| handleChange( trimmed ); | ||
| } | ||
| }; |
There was a problem hiding this comment.
Same as above wrt generating a slug that matches an existing taxonomy
| // Surface them in priority order: structural rules first, async slug-taken last. | ||
| // `required` only overrides the native browser message when our rule supplies | ||
| // one of its own. | ||
| function getSlugCustomValidity( validity?: FieldValidity ) { |
There was a problem hiding this comment.
Should we look at reusing some of those when they're literally the same between post types and taxonomies?
There was a problem hiding this comment.
Yeah.. We'll probably need a shared content-types package or something that might contain both user taxonomies and post types. I updated the tracking issue with this.
| : null; | ||
| }, | ||
| }, | ||
| Edit: function SlugEdit( { |
There was a problem hiding this comment.
This entire component also looks pretty reusable, would be nice to see how to avoid the duplication
| import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/private-apis'; | ||
|
|
||
| export const { lock, unlock } = | ||
| __dangerousOptInToUnstableAPIsOnlyForCoreModules( |
There was a problem hiding this comment.
It's a shame we need to do this solely for using ValidatedInputControl.
@mirka are we planning to stabilize the validated form components soon?
There was a problem hiding this comment.
Since the validated components are currently mainly used through @wordpress/dataviews, I was hoping to keep them private, and replace them with validated versions of @wordpress/ui form components when they're available.
What?
Part of #77600
Testing instructions
Content typesexperiment.Settings → Post Typesand go to add a new one.slugfieldslugisn't auto-filledTaxonomies.