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

Feature: Adding support for more granular controls over the ToC block #69063

Open
wants to merge 2 commits into
base: trunk
Choose a base branch
from

Conversation

gmovr
Copy link

@gmovr gmovr commented Feb 5, 2025

What?

Closes #51605

  • It allows a user more control over the ToC block.
    • They can choose how deep they want the ToC to be (just h2? all the way to h6?)
    • Additionally, we allow the user to explicitly exclude a given heading by giving the heading a class of toc-exclude. This will exclude it from the ToC, even if the given settings for heading level would qualify it.

Why?

On several sites, the ToC block is too rigid, and we're forced to convert it to a static list. This is subpar, as it loses the logic, and a changed heading will lead to a broken link reference.

How?

  • It gives the user simple controls for choosing how many levels they need. This may differ from one page to another.
  • The exclude feature is necessary, as some users may want to include headings for SEO purposes, that are not necessarily wanted in the ToC.

Testing Instructions

  1. Check out the branch.
  2. Open a new post or page.
  3. Add multiple headings of different levels.
  4. Add a ToC block.
  5. Ensure that the settings are correctly picking the right headings.
  6. Test the toc-exclude class on a heading.

Just like a TV cooking show, I've prepared some code you can paste into the editor to test this:

<!-- wp:table-of-contents {"headings":[{"content":"This is the intro","level":2,"link":"http://localhost:8082/?p=5#this-is-the-intro"},{"content":"Another H2","level":2,"link":"http://localhost:8082/?p=5#another-h2"},{"content":"H3 one more time","level":2,"link":"http://localhost:8082/?p=5#h3-one-more-time"}],"includeAllHeadings":false,"maxLevel":2} -->
<nav class="wp-block-table-of-contents"><ol><li><a class="wp-block-table-of-contents__entry" href="http://localhost:8082/?p=5#this-is-the-intro">This is the intro</a></li><li><a class="wp-block-table-of-contents__entry" href="http://localhost:8082/?p=5#another-h2">Another H2</a></li><li><a class="wp-block-table-of-contents__entry" href="http://localhost:8082/?p=5#h3-one-more-time">H3 one more time</a></li></ol></nav>
<!-- /wp:table-of-contents -->

<!-- wp:heading -->
<h2 class="wp-block-heading" id="this-is-the-intro">This is the intro</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading" id="another-heading-here">Another heading here</h3>
<!-- /wp:heading -->

<!-- wp:heading -->
<h2 class="wp-block-heading" id="another-h2">Another H2</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading" id="h3-again">H3 again</h3>
<!-- /wp:heading -->

<!-- wp:heading {"level":4} -->
<h4 class="wp-block-heading" id="what-about-a-h4">What about a h4?</h4>
<!-- /wp:heading -->

<!-- wp:heading -->
<h2 class="wp-block-heading" id="h3-one-more-time">H3 one more time</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":4} -->
<h4 class="wp-block-heading" id="h4-it">h4 it</h4>
<!-- /wp:heading -->

<!-- wp:heading {"level":5} -->
<h5 class="wp-block-heading" id="even-a-h5">Even a h5</h5>
<!-- /wp:heading -->

<!-- wp:heading {"level":6} -->
<h6 class="wp-block-heading" id="or-a-h6">...or a h6</h6>
<!-- /wp:heading -->

<!-- wp:heading {"className":"toc-exclude"} -->
<h2 class="wp-block-heading toc-exclude" id="this-one-is-hidden-though">This one is hidden though</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

Testing Instructions for Keyboard

We use standard components only adding a standard select box.

Screenshots or screencast

CleanShot 2025-02-05 at 20 05 36

Before After

…, such as heading level, and the option for excluding certain headings via a css class
Copy link

github-actions bot commented Feb 5, 2025

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 props-bot label.

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @jodamo5.

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Unlinked contributors: jodamo5.

Co-authored-by: gmovr <[email protected]>
Co-authored-by: swissspidy <[email protected]>
Co-authored-by: mrfoxtalbot <[email protected]>
Co-authored-by: JosVelasco <[email protected]>
Co-authored-by: Mamaduka <[email protected]>
Co-authored-by: jasmussen <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions github-actions bot added the First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository label Feb 5, 2025
Copy link

github-actions bot commented Feb 5, 2025

👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @gmovr! In case you missed it, we'd love to have you join us in our Slack community.

If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information.

@Mamaduka Mamaduka added [Type] Enhancement A suggestion for improvement. [Block] Table of contents (experimental) Affects the Table of contents Block labels Feb 6, 2025
@mrfoxtalbot
Copy link

I tested it using Playgound, and it works as expected.

Kapture.2025-02-06.at.15.50.21.mp4

@swissspidy swissspidy added the Needs Design Feedback Needs general design feedback. label Feb 10, 2025
@swissspidy
Copy link
Member

The last design guidance on #51605 is from 2023, so I think we need a fresh perspective there. The toggle + dropdown seems a bit unnecessary to me.

Either way, I don't think we need two attributes for this. includeAllHeadings: true is equal to maxLevel: 6 anyway, so that's just redundant. If we want to keep the toggle + dropdown combo, then I would simply use maxLevel: null or so for the toggled-on state. In other words: we can implement this with only the maxLevel attribute.

] }
onChange={ ( value ) =>
setAttributes( {
maxLevel: parseInt( value, 10 ),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI passing radix 10 isn't needed and hasn't been for like 10 years. parseInt( value ) is enough

@swissspidy
Copy link
Member

  • Additionally, we allow the user to explicitly exclude a given heading by giving the heading a class of toc-exclude. This will exclude it from the ToC, even if the given settings for heading level would qualify it.

Where is this coming from? I don't see a feature request for it.

IMHO this is better discussed in a new issue first before trying to add this in via this PR.

There might be alternative approaches for this, e.g. with a new attribute on the heading block, or with a different class name or so. Hence best to split this up.

@gmovr
Copy link
Author

gmovr commented Feb 10, 2025

  • Additionally, we allow the user to explicitly exclude a given heading by giving the heading a class of toc-exclude. This will exclude it from the ToC, even if the given settings for heading level would qualify it.

Where is this coming from? I don't see a feature request for it.

IMHO this is better discussed in a new issue first before trying to add this in via this PR.

There might be alternative approaches for this, e.g. with a new attribute on the heading block, or with a different class name or so. Hence best to split this up.

Thanks for the feedback. This is coming from my own use wihin the team that update our blog. Often we do not want certain headings in the ToC, and to accomplish this now, we need to convert it to a static list.

I was considering setting it on the heading block, but it felt a bit inverse in this case, as most pages will have headings while fewer will have the ToC block. So IMO the ToC block should contain ToC logic.

I'm open to either approach, though, or moving it to an issue and a subsequent PR. :)

@gmovr
Copy link
Author

gmovr commented Feb 10, 2025

The last design guidance on #51605 is from 2023, so I think we need a fresh perspective there. The toggle + dropdown seems a bit unnecessary to me.

Either way, I don't think we need two attributes for this. includeAllHeadings: true is equal to maxLevel: 6 anyway, so that's just redundant. If we want to keep the toggle + dropdown combo, then I would simply use maxLevel: null or so for the toggled-on state. In other words: we can implement this with only the maxLevel attribute.

That makes sense! I will change the filtering logic.

@swissspidy
Copy link
Member

  • Additionally, we allow the user to explicitly exclude a given heading by giving the heading a class of toc-exclude. This will exclude it from the ToC, even if the given settings for heading level would qualify it.

Where is this coming from? I don't see a feature request for it.
IMHO this is better discussed in a new issue first before trying to add this in via this PR.
There might be alternative approaches for this, e.g. with a new attribute on the heading block, or with a different class name or so. Hence best to split this up.

Thanks for the feedback. This is coming from my own use within the team that update our blog. Often we do not want certain headings in the ToC, and to accomplish this now, we need to convert it to a static list.

I was considering setting it on the heading block, but it felt a bit inverse in this case, as most pages will have headings while fewer will have the ToC block. So IMO the ToC block should contain ToC logic.

I'm open to either approach, though, or moving it to an issue and a subsequent PR. :)

To clarify, my suggestion was not necessarily to do the inverse, but for example to introduce a proper toggle on the heading block that the TOC block could then use. I would also take a look at how Google Docs does this for example. You can remove a heading from the TOC simply by clicking on an "X" next to it.

That's why I think this needs its own issue & discussion first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Table of contents (experimental) Affects the Table of contents Block First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository Needs Design Feedback Needs general design feedback. [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Table of Contents - Allow Users to Select Which Heading Levels Will Be Included
4 participants