Improving the HTML structure of TOC macro output

Hi everyone,

The HTML root element currently generated by the TOC macro has several drawbacks:

  • It has no CSS class, which makes it difficult to style.
  • Is an ul element while a nav element would be more appropriate for a table of contents.

Here’s a new structure proposal:

<nav class="xwiki-toc">
  <ul>
    <li>...</li>
    <li>...</li>
  </ul>
</nav>

What do you think about this proposal? Which other attributes should be added and why? Should we turn the ul element to an ol one since the list is ordered (like EPUB table of contents)? Any HTML API breakage that should be considered/avoided?

I think we need both the NAV element + a specific CSS class.

Here’s what I replied on a chat that was suggesting to use only the NAV element:

interesting indeed, makes it a bit more unofficial i think (for styling) but idk
(I mean less explicit for styling)
if users start to consider the full HTML as API then we’re in trouble :wink: (can’t change anything)
so I think my preference would be for both and to document the CSS class in the TOC macro doc page
(to make it explicit it’s an “api”)

I think the <nav>-element also needs an aria-label for accessibility. Now I’m surprised we don’t have a toc heading already, seems like it usually done manually like here in the user guide. Ideally if that heading exists, it should be inside the toc macro and the toc macro should use it’s text as aria-label or reference the heading using aria-labelledby. Maybe we could add a title-parameter to the toc macro to automatically add a heading and have some fallback for the aria-label-attribute? So basically what I’m saying is that the new feature should allow achieving something like in the user guide with just the toc macro and a few lines of CSS.

I wouldn’t change the list type to <ol> as would completely break styling. It means we would need to manually re-create the list style we currently have which could be customized using CSS.

I would propose xtoc or xToc for the class, to be coherent with Forms Standards: Vertical Layout (XWiki.org) .

Nav looks appropriate indeed, I didn’t yet check if multiple navs are ok or not (we already have one in the global menu) or whether it could have some other impact.

I wouldn’t change the list type either, I think it can be done from CSS if anybody wants it to be numbered (but I’m not sure).

Multiple nav-elements are okay, see usage notes on MDN but when having several <nav>-elements, they should have aria-label-attributes such that screen reader users can distinguish them easily. We already have several of them without labels, I’ve created an issue that label should be added already in February.

Thank you all. I have created XRENDERING-671 to describe the need of the title parameter indeed, and here’s the issue related to the introduction of a nav element with a class.

Here’s a new target structure proposal based on your suggestions:

When a heading is present

<nav class="xtoc" aria-labelledby="xtoc-title">
  <h1 id="xtoc-title">Table of contents</h1>
  <ul>
    <li>...</li>
    <li>...</li>
  </ul>
</nav>

When the heading is empty

<nav class="xtoc" aria-label="Table of contents">
  <ul>
    <li>...</li>
    <li>...</li>
  </ul>
</nav>

Where the aria-label value is a localized string provided by the TOC macro l10n labels.

Please let me know if you have any concern, then let’s proceed with the code.

I think using a “h1” might be a bad choice, in particular if the table of contents is part of the content as this breaks the heading hierarchy. What about defaulting to one level less than the last heading before the table of contents if there is any (you’re analyzing the headings, anyway) and an option to override the heading level? Also, you’ll need to ensure that the id is unique if several tables of contents are included in a page. We already have the id generator in the XDOM, you can probably re-use it.

You’re right, a unique id is needed. Using a heading with one level less than the last heading before the TOC sounds good to me. I added all that to XRENDERING-671.

Cheers & thanks

I just realized that the Rendering API does not support nav blocks at the moment. This means we have to introduce a NavBlock and possily a NavMacro, right?

Hi Stephane. Quick questions: How would that translate when exporting to latex for example? or to other syntaxes? Is it generic enough to have an XDOM block for it? It feels a bit too related to HTML, no?

And indeed, you cannot really issue a RawBlock(syntax=HTML) since that would wrap the whole TOC and thus fail any rendering that doesn’t support HTML content. So using a DIV with a class is indeed a solution. The HTML renderer would then transform that into a NAV element.

Thanks Vincent, I’ll do so.

This means that the HTML renderer should detect div blocks with class="xtoc" and transform them to nav elements, right? Which exact method should perform this processing? Should it be XHTMLChainingRenderer#beginGroup? Would it be ok to introduce a hardcoded rule for class="xtoc" in the Rendering or should we introduce a renderer in xwiki-platform instead, since the xtoc CSS class will be introduced in XWikiTocMacro?

Basically the idea I was raising (needs to be validated by others) was to introduce a way for the HTML Renderer to generate a NAV element by transforming a GroupBlock with a specific parameter (the parameter name should indicate that it represents a NAV). It would not be related to the TOC at all and thus no hardcoding.

1 Like

To be clear, I haven’t thought much about this. It’s just an idea. It’s very possible there are better ways.

OK Vincent, I understand. Let’s see if we can come up with a generic syntax to map GroupBlocks with specific parameters to specific HTML elements, that could be quite useful. I’ll try to propose something in a distinct post.

Proposal posted there: Introducing a way to transform divs to specific HTML elements .