Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Heading Block: autogenerate anchors #29561

Closed
aristath opened this issue Mar 4, 2021 · 11 comments · Fixed by #30825
Closed

Heading Block: autogenerate anchors #29561

aristath opened this issue Mar 4, 2021 · 11 comments · Fixed by #30825
Assignees
Labels
[Block] Heading Affects the Headings Block [Block] Table of contents (experimental) Affects the Table of contents Block [Status] In Progress Tracking issues with work in progress [Type] Enhancement A suggestion for improvement.

Comments

@aristath
Copy link
Member

aristath commented Mar 4, 2021

What problem does this address?

Heading blocks are significant structural elements in posts, and being able to link to them is a must-have. There is no downside to having an id in headings, and they are immensely useful:

  • Search engines can link to a section of the post directly
  • Users can share their content more efficiently
  • The Table of Contents block will be able to link to all headings in the content

What is your proposed solution?

This is a proposal to auto-generate anchors for heading blocks.
When the user adds a heading we can generate the anchor from the heading text, so "About Me" gets an anchor about-me.
The user will still be able to customize their anchor from the block's "Advanced" section if they wish.

What happens if the user edits the heading text?

If the heading was About Me with an anchor about-me and they change their heading to About Us, then we can detect that about-me matches the auto-generated anchor for the About Me text, and change the anchor to about-us. If on the other hand the initial anchor doesn't match (for example section-1) then assume it was customized by the user and leave it alone.

What about non-latin languages?

Though not strictly necessary, we could transliterate headings when generating the anchors, just so we get prettier URLs.

@aristath aristath added [Block] Heading Affects the Headings Block [Block] Table of contents (experimental) Affects the Table of contents Block [Type] Enhancement A suggestion for improvement. labels Mar 4, 2021
@mtias
Copy link
Member

mtias commented Mar 4, 2021

Previously: #6182

Let's give this a go! Another case to consider that can make the implementation a bit more complex and costly are the possibility of duplicated IDs when they are autogenerated. So we'd need to guard against that. It can get tricky when we are dealing with FSE content, as a heading in a sidebar can have the same name as a heading in the body.

If we have too many operations running concurrently we need to be careful to not impact the UX of writing text on a heading block. For example, we might want to commit the anchor highly debounced, or even when the block becomes unselected.

If we want to alleviate those cases in the initial roll out, we could make it so that if a "table of contents" blocks is present, then headings auto-generate IDs, otherwise they don't. I think this is worth considering if the implementation gets too tricky.

@ZebulanStanphill
Copy link
Member

ZebulanStanphill commented Mar 4, 2021

Should we even bother trying to generate an id from the heading's content? It would be a lot simpler (and performant) to just have the block generate a (unique) random string of characters upon insertion.

I also think that auto-generated anchors that change along with the heading text may be a bad idea, because any existing links to the those anchors won't work anymore. If the id was only set once upon insertion (and of course the user could change it later themselves if they wanted to), the anchor would remain stable across changes to the wording in the heading.

@jdevalk
Copy link
Contributor

jdevalk commented Mar 4, 2021

a bit more complex and costly are the possibility of duplicated IDs when they are autogenerated.

i think if we do this in the editor as we do in Yoast SEO now you can prevent this. We already know the outline, as the block editor already has that, we can just add a -2 to a heading if needed.

Should we even bother trying to generate an id from the heading's content?

I think you make some good points, and honestly the only reason I'm against auto generating is very simple: it's not as user friendly. It's nice when I can link to #example-code instead of #sifyqw8ev. But indeed you can only do this once and when a heading is updated we probably shouldn't update the ID. We've fixed that in Yoast SEO already though ;)

@ZebulanStanphill
Copy link
Member

@jdevalk Interesting. So how/when does Yoast create the anchors? If I insert a Heading block, when is its anchor generated?

@mtias
Copy link
Member

mtias commented Mar 5, 2021

We already know the outline, as the block editor already has that, we can just add a -2 to a heading if needed.

Yes, for sure, my comment is more towards the fact that all current headings need to be checked, so on a post with 100 headings it can start affecting the typing experience if the anchor is set too often while editing. That's why I mentioned debouncing the operation until after all edits happen.

We'd also need to account for table of contents used outside of post_content. I can see it being useful to have a table of contents block in the sidebar instead of the content. It might be good for the block to support assigning a post-id. If not post id is found it works within its current context (most common case) but if a post-id is set it queries headings on that post.

@ZebulanStanphill
Copy link
Member

I can see it being useful to have a table of contents block in the sidebar instead of the content. It might be good for the block to support assigning a post-id. If not post id is found it works within its current context (most common case) but if a post-id is set it queries headings on that post.

Now that you mention it, that does sound pretty cool. It's definitely possible to implement for the PHP implementation, but I'm not sure about the editor yet. #29394 will take us one step closer, but the next step will be to make the block's PHP implementation work without the $page and $pages globals. (It should probably still use them when displaying the current post's headings, since I imagine that's probably more performant.)

@silkogelman
Copy link

silkogelman commented Mar 6, 2021

Auto-changing anchors along with changing heading text sounds like a bad idea.
It can break backlinks sort of in the same way if url slugs of posts or pages would change along with a changing post/page title. Slugs stay semi-fixed for a reason. And for anchors there isn't a way to do a 301 (auto-)redirect fix like we can with slugs.

Also I believe user-friendliness should be the priority here.
Links to urls that include an anchor are made by humans and shared / received and thus seen by humans.
There is a reason for readable domain names and url slugs, I believe that reasoning extends to anchors.

Adding a -2, -3, etc. to the anchor if needed sounds good to me.

Auto-generating heading IDs is also very valuable when no TOC block is added to a page.
It allows users (like content creators, support agents, forum contributors, etc) and search engines to bring the reader to the exact section that is valuable in that context.
I believe it adds value to a wide range of use cases, and users/ authors should not be forced to use a TOC just to be able to benefit from that.

Auto-generating heading IDs would instantly allow search engines to bring their users to the more detailed, more exact part of the solution that is most valuable to the user. Probably in millions of cases over time.
Not making that available to pages that don't use the TOC block seems like a huge missed opportunity to me.

@mahnunchik
Copy link

+1 for idea to auto-generate anchors by default but don't modify it if it was changed manually.

For example:

  • Initial header About Us -> about-us
  • Header changed to About Company -> about-company
  • Anchor changed manually about-awesome-company
  • Header changed to About blabla - anchor leaved about-awesome-company

As I mentioned before, I'd like to suggest to use module https://github.com/Trott/slug (or similar) to auto-generate anchors.

It allows to slugify not only non-latin languages but also emoji and unicode simbols:

  • i love unicode -> i-love-unicode
  • I ♥ UNICODE -> i-love-unicode
  • Я любою юникод -> ya-lyuboyu-yunikod

@github-actions github-actions bot added the [Status] In Progress Tracking issues with work in progress label Apr 14, 2021
@tedw
Copy link

tedw commented Aug 31, 2021

I’d also love to be able to get the anchor from the block when using parse_blocks(), e.g. $block['attrs']['id']. We can currently get the class name but not the anchor. My use case is dynamically generating a table of contents with jump links.

On a related note, does anyone know why the heading level is omitted for H2s (e.g. $block['attrs']['level'])? Seems odd.

@paaljoachim
Copy link
Contributor

It would be helpful to get some movement on this PR!
Thank you!

I look forward to seeing the Table of Contents block included in the Gutenberg plugin.

@Zodiac1978
Copy link

#36365 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Heading Affects the Headings Block [Block] Table of contents (experimental) Affects the Table of contents Block [Status] In Progress Tracking issues with work in progress [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants