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

Enable & disable autogenerated anchors in heading blocks #38171

Closed
s56bouya opened this issue Jan 24, 2022 · 33 comments · Fixed by #38780
Closed

Enable & disable autogenerated anchors in heading blocks #38171

s56bouya opened this issue Jan 24, 2022 · 33 comments · Fixed by #38780
Labels
[Block] Heading Affects the Headings Block Needs Design Needs design efforts. [Type] Enhancement A suggestion for improvement.

Comments

@s56bouya
Copy link

Description

I want to remove the automatic html anchor for the heading block. There are cases where IDs are attached to heading blocks with hooks and plugins.

I also agree with the comments (#30825 (comment)).

Please consider that the html anchor can be enabled / disabled as an option or a filter.

Step-by-step reproduction instructions

  1. Add Heading block
  2. Type any text
  3. Open Advance setting
  4. Delete HTML anchor(hold down delete key)

Screenshots, screen recording, code snippet

2022-01-24.13.34.54.mov

Environment info

WP RC-3
Gutenberg 12.4.1

Please confirm that you have searched existing issues in the repo.

Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

Yes

@carolinan carolinan added the [Block] Heading Affects the Headings Block label Jan 24, 2022
@ddryo
Copy link
Contributor

ddryo commented Jan 24, 2022

I was able to reproduce it as well.

@skorasaurus
Copy link
Member

related #36365

@s56bouya
Copy link
Author

It was also reproduced in the following environment.

  • WP 5.9-RC4
  • Gutenberg 12.4.1

@skorasaurus skorasaurus added Needs Design Needs design efforts. [Type] Enhancement A suggestion for improvement. labels Jan 25, 2022
@annezazu annezazu changed the title Unable to remove HTML anchor for heading block Enable & disable autogenerated anchors in heading blocks Jan 25, 2022
@priethor
Copy link
Contributor

priethor commented Jan 26, 2022

Some implementation approaches that need to be considered to achieve this:

  • Adding a flag to opt-out of the automatic anchor generation.
  • Rolling back the default automatic generation, and making it opt-in.
    • If the automatic generation is disabled by default, enable it if a ToC block exists in the current page/post.

@aristath
Copy link
Member

My 2c:
Cases where a plugin adds IDs to headers, or a script adds IDs are the exception and not the norm. A heading anchor can be extremely helpful in all cases except the exceptions described above, so making the behavior opt-out makes more sense than making it opt-in. Ideally, these plugins would be updated to use the anchors that core adds. However, since most of them will probably not bother updating their code as they should, adding a flag to allow disabling the implementation could be a viable option for these edge-cases. 👍

@dutchanton
Copy link

Before WordPress 5.9 it was possible to leave the HTML anchor empty. Now indeed it is pre-filled, and the anchor cannot be deleted (empty).

I leave anchors empty if and when I do not want a specific heading to be included in the Table of Contents. Many TOC blocks automatically pull in all headings and anchors, without the ability to pick and choose which ones to display.

@dutchanton
Copy link

  • If the automatic generation is disabled by default, enable it if a ToC block exists in the current page/post.

No, because it should be possible to leave specific headings out of the ToC.

Example: if a post has 9 headings but I only want the ToC to display 4 of them. The heading HTML anchor text behaved that way before 5.9.

@ddryo
Copy link
Contributor

ddryo commented Jan 30, 2022

Hello. Thank you very much for your development.

The ability to auto-generate the id of a heading is basically very useful.
However, there are many cases where it is not.

I am selling a WordPress theme in Japan.

Many users of my themes are confused by this "auto-generate id" feature and complain that they cannot turn off the feature.

Even if there is no problem with the operation itself, many people feel that it is simply weird that multi-byte characters such as Japanese are assigned as ids.

Some people are angry with me, mistaking it for a problem with the theme.

From what I've heard from users, there are many cases where this auto-generating feature has a negative impact, especially in classic themes.

Please make it possible to turn it off.

Translated with www.DeepL.com/Translator (free version)

@ram108
Copy link

ram108 commented Feb 1, 2022

The automatic addition of id's for headings is terrible. Especially if the headings are in non-Latin. Plus it broke the auto-table of contents plugins.

@Mamaduka
Copy link
Member

Mamaduka commented Feb 2, 2022

I agree with Ari's comment that ideally, plugins should leverage WP core generated anchors. But, unfortunately, this isn't always the case.

Here're my thoughts on how we can improve the user experience for this feature:

  • Allow users to remove anchors.
  • Add settings to disable the feature.
  • Display notice inside TOC block if the feature is disabled with action to enable it.

Here's my humble mockup for the Preferences modal:
CleanShot 2022-02-02 at 11 47 04

@ram108
Copy link

ram108 commented Feb 2, 2022

This is not a design or options issue.
The current implementation of id generation does not comply with html standards.

  1. id must be unique in the entire html document, not just in the article. How is this uniqueness checked?
  2. id should not contain non-Latin characters. But even Japanese and Russian titles turns into id.

Example:
<h2 id="это-заголовок-2">Это заголовок 2</h2>

Technically, in HTML5, the value for an id attribute may contain any character, except whitespace characters. However, to avoid inadvertent errors, only ASCII letters, digits, '_', and '-' should be used.

Source: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id

The id attribute value must be unique amongst all the IDs in the element's tree

Source: https://html.spec.whatwg.org/multipage/dom.html#global-attributes:the-id-attribute-2

My opinion is that such id generation at least should be disabled by default.

@ram108
Copy link

ram108 commented Feb 2, 2022

Addition to my previous post.

Since ids are generated from headers without any checking for their uniqueness, it's very easy to break the entire html document by simply creating headers like:

<h2 id="main">Main</h2>
<h2 id="content">Content</h2>
<h2 id="site-header">Site Header</h2>

The automatic generation will rewrite existing ids in html document and brake jquery and css.

To prevent this from happening, prefix should be added (for example, "h1-", "h2-", "h3-") to automatic ids.

@s56bouya
Copy link
Author

s56bouya commented Feb 2, 2022

#38171 (comment) Good idea!

I want the setting disabled by default.

Because it takes an additional action to turn off the setting, which is a hassle.

And I can't ignore the fact that some users can't find (or deal with) that the table of contents plugin doesn't work properly because of the HTML anchor.

I thought there were some issues with the current HTML anchors. (As far as I know, the ID cannot be removed, the same ID is assigned when copying the heading block, the ID does not comply with the specification #38171 (comment) )

These issues have a considerable impact on themes, plugin developers, and users.

HTML anchors are enabled and released by default in WordPress 5.9. It may be difficult to disable by default in a future release. I also understand that HTML anchors are useful.

If there is an enable / disable feature, I want it to be disabled by default.

@SiteMods
Copy link

SiteMods commented Feb 10, 2022

This is aggravating. Does anyone have a way to disable this now? I can't wait months on a fix to something that shouldn't have been released.

@RolfKyburz
Copy link

RolfKyburz commented Feb 10, 2022

I couldn't agree more with SiteMods: this is a serious issue that needs an instant fix. I'm currently spending many hours amending existing blog posts (and I have around 600!). I need to retrofit such fixes to countless posts, as I can't risk making a minor amendment and thereby inadvertently screwing the table of contents. My clumsy workaround consists of reverting to a handcrafted table of contents — depending on the type of blog post, this means between 15 minutes and 5 hours of work per post. Not happy, to say the least.

@SiteMods
Copy link

For a fix, I hooked into content_save_pre and did a preg_replace_callback to remove all heading IDs generated by Gutenberg before saving the content to the database. I was already generating heading IDs that were actually unique to all posts.

It was a great idea Gutenberg but you didn't think it through.

@ram108
Copy link

ram108 commented Feb 10, 2022

For a fix

Can you share with the hook to remove headings?

@bryanb
Copy link

bryanb commented Feb 10, 2022 via email

@SiteMods
Copy link

For a fix

Can you share with the hook to remove headings?

This should get you started but will need modification to fit your needs.

// Adds a callback function to a filter hook.
add_filter( 'content_save_pre', 'generate_heading_ids' );

function generate_heading_ids( $content ) {

	// Search and replace.
	$content = preg_replace_callback(
		'|(<h[1-6])([^>]*)>|', // Match all heading elements [1] and their attributes [2].
		function ( $matches ) use ( $content ) {

			// do what needs to be done here...

			return $matches[0];

		},
		$content
	);

	return $content;

}

@ram108
Copy link

ram108 commented Feb 10, 2022

I hope the WordPress development team will be able to solve the problem.

@jasmussen
Copy link
Contributor

An option to disable, as @Mamaduka mocked up could be a good option. The preferences modal could use some restructuring to make it easier to find options, but as an interim solution, a toggle under "Publishing" could work. I'd change the verbiage, though. How about:

Automatically add anchors to headings
Enable linking to sections of a page, useful for a Table of Contents.

It would also be good to revisit this feedback:

I think there's a case for considering a prefix for these auto-generated anchors.

@RolfKyburz
Copy link

I'd like to see something more differentiated than a simple on/off solution, like:

  • disable auto-generated anchors
  • enable auto-generated anchors, but allow disabling in specific titles (e.g., by emptying the anchor field, or with a toggle in the block properties)
  • enforce auto-generated anchors.

For me, the second option should be the default. That's what we had in WP 5.8.x
Note: I don't see why anyone would want the page title to be included in a list of content. With the exception of a content list at the end of a document, titles above a TOC are typically not included in the latter.
What might be useful, though, would be a default internal anchor (such as "page_top") that allows for links returning to the top of a long page.

@Mamaduka
Copy link
Member

Thank you for the feedback, @RolfKyburz.

I think we can start by adding an option for auto-generated anchors and making it opt-in (at least for now). I will have PR ready for this later today or Monday.

@RolfKyburz
Copy link

Thanks, @Mamaduka. I agree, as long as disabling auto-generated anchors on an existing document does not remove anchors already present (auto-generated or not).

@priethor
Copy link
Contributor

I agree we should focus on allowing to disable the automatic anchor generation in a simple way as the first step, and iterate on improving the mechanism with prefixes and other advanced options, more thoroughly considering their impact.

@rudrastyh
Copy link

Well, everything is already well said above, this bug is super-annoying.

I think I will also roll back to a previous version for a while, because this thing makes the editor almost unusable for a couple of my websites.

@RolfKyburz
Copy link

Yes, @rudrastyh, I couldn't agree more — it is by far the worst WP bug/annoyance in a long time. I wish I had the time to spare to roll back. And, of course, I hate the sheer thought of rolling back to an older version. And I don't see signs of a fix in 5.9.1 ...

@Mamaduka
Copy link
Member

Hey, folks

I'm planning to merge #38780 today, which will make this feature opt-in. The fix should ship with 5.9.1.

@SiteMods
Copy link

Good work getting a solution so quickly. It would help tremendously if new features like this could be disabled programmatically (filters). Otherwise, it's the "don't touch that" speech for every button that breaks the theme/plugin.

@s56bouya
Copy link
Author

Thank you for a quick solution.

Confirmed HTML anchor is not autogenerated when creating a new heading block by adding the following code. (Ref: #38780)

add_filter(
	'block_editor_settings_all',
	static function( $settings ) {
		$settings['__experimentalGenerateAnchors'] = false;
		return $settings;
	}
);

Environment info

WP 5.9.1-RC1-52771

Note

HTML anchors that were autogenerated in the past are not removed, so some modification may be required in some cases.

@Mamaduka
Copy link
Member

Thanks for testing, @s56bouya.

The feature should be off by default, and you can enable it by changing settings to true

@s56bouya
Copy link
Author

Hi @Mamaduka, Thank you for the information!

@roeeyossef
Copy link

For a fix

Can you share with the hook to remove headings?

This should get you started but will need modification to fit your needs.

// Adds a callback function to a filter hook.
add_filter( 'content_save_pre', 'generate_heading_ids' );

function generate_heading_ids( $content ) {

	// Search and replace.
	$content = preg_replace_callback(
		'|(<h[1-6])([^>]*)>|', // Match all heading elements [1] and their attributes [2].
		function ( $matches ) use ( $content ) {

			// do what needs to be done here...

			return $matches[0];

		},
		$content
	);

	return $content;

}

Hi @SiteMods - Would HIGHLY appreciate if you can be more specific and show me how i can remove all the current anchor tags on the heading using your code.

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 Needs Design Needs design efforts. [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging a pull request may close this issue.