Skip to content

add option to skip rendering child when rendering ToC#439

Open
jamescarr28 wants to merge 5 commits intomainfrom
optional-rendering-of-child-resources-in-toc
Open

add option to skip rendering child when rendering ToC#439
jamescarr28 wants to merge 5 commits intomainfrom
optional-rendering-of-child-resources-in-toc

Conversation

@jamescarr28
Copy link

@jamescarr28 jamescarr28 commented Feb 17, 2026

What’s changed

We have added an optional flag for the multi_page_table_of_contents/render_page_tree helper functions. The table of contents (ToC) currently has limitations when using layouts to group sections and create filtered ToC - e.g. when using header_links and requiring a specific ToC .

Example usage

<% section_index_page = sitemap.resources.find {|resource| resource.path == "section/index.html" } %>
<% content_for :sidebar do %>
   <%= render_page_tree [section_index_page], current_page, config, yield, include_child_resources: false %>
<% end %>

<% wrap_layout :core do %>
  <%= yield %>
  <% content_for(:toc_module, "in-page-navigation") %>
<% end %>

Identifying a user need

This is particularly an issue when we have a directory with an index page, and then sub directories containing nested sections. When trying to organise this structure using header_links to create sections, we want each section to create it's own ToC eg:

source/
├── index.html                   
├── contact.html
├── section/ # this is the link used in the `header_links` href
  └── index.html
       ├── sub-section/
           ├── index.html 
           ├── subpage1.html     
           ├── subpage2.html

The expected result would be:

desired result

This bug has been previously raised here. We are currently unable to publish updated public facing documentation due to the navigation being too painful. This fix allows us to do this, while maintaining backwards compatibility

Existing options that don't generate the right result

Using resource.children

If we use the resource.children call then we loose the section index page altogether. This page can only be found by clicking the link in the navigation (top right). This is a confusing user journey and very unclear.

code example:

<% section_index_page = sitemap.resources.find {|resource| resource.path == "section/index.html" } %> # using a parent resource creates issues similar to those outlined below, and doesn't solve the problem
....
 <%= render_page_tree section_index_page.children, current_page, config, yield %>
just doing children

Including resource in tree builder

If we try to include the the extra resource then the full child tree is rendered below the main section. Result below is the same if we merge into a single array etc

code example:

<%= render_page_tree [section_index_page], current_page, config, yield %>
 <%= render_page_tree section_index_page.children, current_page, config, yield %>

result:

duplicate full tree

Using single page ToC

When using the single page ToC functions the ToC changes when you move to a different page, with the section index missing altogether

<%= single_page_table_of_contents(yield) %>
<%= render_page_tree section_index_page.children, current_page, config, yield %>
single page toc

@huwd
Copy link
Contributor

huwd commented Feb 25, 2026

So the code looks good to me, @NathanD-GDS you raised the initial bug, you wanna give this a look too?

claire-cheuk
claire-cheuk previously approved these changes Mar 3, 2026
@claire-cheuk claire-cheuk self-requested a review March 3, 2026 15:32
Copy link

@claire-cheuk claire-cheuk left a comment

Choose a reason for hiding this comment

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

Looks good!

@claire-cheuk claire-cheuk dismissed their stale review March 3, 2026 15:35

Needs final approval from Huw and Nathan before merging

Copy link

@NathanD-GDS NathanD-GDS left a comment

Choose a reason for hiding this comment

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

Looks good - just a few small suggestions.

README.md Outdated

## Use layouts to structure your Table of Contents

You can use layouts to group pages and customise your Table of Contents (ToC). To create a template create a new ruby file in the `source/layouts` directory, for example `source/layouts/live_support_layout.erb`. You can apply the template by including it in the frontmatter block of your required pages, for example:

Choose a reason for hiding this comment

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

Suggested change
You can use layouts to group pages and customise your Table of Contents (ToC). To create a template create a new ruby file in the `source/layouts` directory, for example `source/layouts/live_support_layout.erb`. You can apply the template by including it in the frontmatter block of your required pages, for example:
You can use layouts to group pages and customise your Table of Contents (ToC). To create a layout, create a new ruby file in the `source/layouts` directory, for example `source/layouts/live_support.erb`.
Apply the template by including it in the frontmatter block of a pages. In this example, we're applying the `live_support` layout to the page:

Just a few changes here. I think 'layout' is probably more appropriate than 'template'.

Removed 'layout' from the file name because it felt unnecessary, but happy for you to add it back in if you think it's needed.

Also added more of an explanation about what the example is.

README.md Outdated
```


This gem has helper functions to render your ToC. You should use:

Choose a reason for hiding this comment

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

Suggested change
This gem has helper functions to render your ToC. You should use:
This gem has helper functions to render your ToC. You can use:

Is it 'should' or 'can'?

Copy link
Author

Choose a reason for hiding this comment

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

Interesting question, it depends on how much leeway we want the gem to have I guess. I'd say that it's should as we're saying, 'if you want to [create a single page table of contents], you should use [the function] as we've tested it and approved it works in the style we expect'

README.md Outdated
```


This gem has helper functions to render your ToC. You should use:

Choose a reason for hiding this comment

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

Given this section is about layouts, is it possible to change this line to make it clearer how this relates to layouts? For example:

This gem has helper functions that you can use in custom layouts. You can use:

README.md Outdated

The `multi_page_table_of_contents` helper function takes [an optional `include_child_resources`](https://github.com/alphagov/tech-docs-gem/pull/439) parameter to help with your custom ToC. The default value of `include_child_resources` is `true`.

Below is an example of using the helper functions in a custom layout:

Choose a reason for hiding this comment

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

Would it be possible to add a bit more of an explainer about what's happening in this example? I've added a suggestion below of the kind of thing I mean, but it's probably wrong so you'll be able to explain it!

Suggested change
Below is an example of using the helper functions in a custom layout:
Below is an example of a custom layout that creates a ToC for a group of pages BLAH BLAH BLAH:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants