mmistakes / minimal-mistakes

:triangular_ruler: Jekyll theme for building a personal site, blog, project documentation, or portfolio.
https://mmistakes.github.io/minimal-mistakes/
MIT License
12.42k stars 25.6k forks source link

Toggle table of contents via front matter #1222

Closed vahid-dan closed 7 years ago

vahid-dan commented 7 years ago

Environment information


Expected behavior

I have imported GitHub wiki pages as a submodule into the Jekyll website. Now I want to automatically add "Table of Contents" to every wiki page without having to add {% include toc %} manually to every page. Wiki pages inside the website are in the wiki directory and have wiki.html layout.

mmistakes commented 7 years ago

I don't think there is any way to do this. The {% include toc %} is a shortcut to print out {:toc} which is used by Kramdown to auto-generate the table of contents based on the headlines of your Markdown file.

{:toc} has to live inside of said Markdown file to be parsed when Kramdown does it thing. There's no way for me to bake this logic into a layout because of this.

There's probably a Jekyll plugin you could leverage to do it, but that wouldn't happen at the theme level.

allejo commented 7 years ago

Might I recommend a solution like this? https://github.com/allejo/jekyll-toc This'll take the generated HTML from the markdown and generate a TOC from that and can be used from inside a layout. It's also written in Liquid, so it's compatible with GH pages since it's not a plug-in and doesn't require JS.

mmistakes commented 7 years ago

Good solution @allejo, I've recommended it before for those who want some more flexibility over what Kramdown's auto TOC or JS solutions provide.

Do you have any stats around the impact of using this include across a ton of post's? Have to think with it looping over all the content to pull out the headings there'll be a hit in jekyll build time.

allejo commented 7 years ago

Haven't really done any extensive testing for stats. Got any suggestions for tests I should do? The only stat I have is for the Docker docs site (through --profile) where the include is being used 813 times at about ~6.5 seconds.

Edit: Just ran --profile again on the current Docker site and it's at ~8 seconds for 1182 hits.

mmistakes commented 7 years ago

--profile is the only one I'm really aware of too. A few seconds doesn't seem too bad. I've used some pure-Liquid methods to do some things related to pagination that completely killed a build and pushed it into minutes/hours territory.

I have a fairly large site myself, when I get a chance I'll give it a test just to compare against.

allejo commented 7 years ago

Oh sweet, I'd definitely be interested in seeing how it performs on your site 👍

mmistakes commented 7 years ago

Did some quick tests using the sample posts in this theme and I didn't really see any impact on build time.

_includes/toc.html                                  |    94 |   29.43K | 0.413

Which is very encouraging. Seems like a valid replacement to me. There's probably a few second hit on a site with hundreds/thousands of posts, but I'm cool with that.

@vahid-dan Looks like what you want to do is something I can bake into the theme. Thinking something like toc: true on a post/page would activate the Liquid TOC. And with YAML Front Matter defaults you could easily set it true for all your posts without having to had any garbage to your .md files.

If I ditch the Kramdown auto-generated TOC it frees me up to move it somewhere more semantic in the HTML layouts too.

mmistakes commented 7 years ago

This feature has been added to the theme. Haven't pushed a new theme gem version yet, but the updates are all on master if you're using the fork method.

I've kept the old Kramdown based method in for now, but plan on removing that in the next version. To enable table of contents on pages using the single layout simply add toc: true to the front matter.

The icon and label title can both be changed per page just like with the old version.

---
toc: true
toc_label: "My Custom Table of Contents Label"
toc_icon: "gear"
---

TOC's can also be set globally for entire section of pages/posts using Front Matter defaults in _config.yml.

Bobinio commented 6 years ago

Hopefully someone can assist... I can generate the Table of Contents for a page which seems to pick up H2 tags etc. This Table of content appears in the right column as expected. However, when I click on a link in the Table of contents nothing happens. In the source code it shows the href="#" for each link. Obviously, this is no good. I expected it to create and use a name tag somehow and so make these clickable links useful. What am I missing? Many thanks.