jdsteinbach / eleventy-plugin-toc

11ty plugin to generate a TOC from page content
61 stars 19 forks source link

Followed steps but nothing is displaying #7

Open valzi opened 4 years ago

valzi commented 4 years ago

I did steps 1-3, but {{ content | toc }} doesn't display anything. Any guesses about what I'm doing wrong? My headers all have IDs.

gurpal2000 commented 4 years ago

+1

jdsteinbach commented 4 years ago

Thanks - can you provide any other info to help troubleshoot, like your Eleventy config file?

jdsteinbach commented 4 years ago

A common reason for nothing to display is that headings don't have id attributes on them.

The README has been updated with instructions setting up Eleventy's Markdown compiler to add ids to headings:

https://github.com/jdsteinbach/eleventy-plugin-toc#2-make-sure-your-headings-have-anchor-ids

helmutgranda commented 4 years ago

For some odd reason (and this is happening with other plugins as well), even when my headers have IDs I need to use markdownItAnchor and markdownIt in order for this plugin to work. I am not 100% why but this is a project that needs to be released quickly so I don't have time to investigate further but I thought I would share.

jdsteinbach commented 4 years ago

@helmutgranda As mentioned on #2, version 1.1.0 contains several fixes to options parsing and allows .eleventy.js config.

versipellis commented 2 years ago

Just bumping this that I'm running into the same issue still :(

jdsteinbach commented 2 years ago

Thanks @versipellis - can you provide a simplified test case where you're seeing this problem?

versipellis commented 2 years ago

Thanks @jdsteinbach, this is my .eleventy.js:

const eleventyNavigationPlugin = require("@11ty/eleventy-navigation");
const Image = require("@11ty/eleventy-img");
const path = require('path')
const anchors_plugin = require('@orchidjs/eleventy-plugin-ids');
const pluginTOC = require('eleventy-plugin-nesting-toc');

module.exports = (config) => {
  let pathPrefix = "/classes/863.21/EECS/people/benjtang/";

  config.addPassthroughCopy({ 'public': './' })
  config.setBrowserSyncConfig({
    files: ['dist/**/*'],
    open: true,
    // Tweak for Turbolinks & Browserstack Compatibility
    snippetOptions: {
      rule: {
        match: /<\/head>/i,
        fn: function (snippet, match) {
          return snippet + match;
        }
      }
    }
  })
  config.setDataDeepMerge(true)

  config.addPlugin(eleventyNavigationPlugin);
  config.addPlugin(anchors_plugin, {
    selectors: ['h2','h3','h4','h5','h6'],
    prefix: 'headerid-',
  });
  config.addPlugin(pluginTOC, {tags: ['h2']});

  return {
    markdownTemplateEngine: 'njk',
    dataTemplateEngine: 'njk',
    htmlTemplateEngine: 'njk',
    dir: {
      input: 'src',
      output: 'dist',
    },
    pathPrefix
  }
}

And this is my template I'm using:

---
layout: main.njk
---

{% set previousPost = collections.all | getPreviousCollectionItem(page) %}
{% set nextPost = collections.all | getNextCollectionItem(page) %}

<aside>
    {{content | toc | safe}}
</aside>

<article>
    <div class="grid grid-cols-10">
    <h1 class="text-4xl col-span-8">{{ title }}: {{ subtitle}}</h1>
    <div class="flex text-blue-700 col-span-2 items-end justify-end">
        {% if previousPost %}<a href="{{ previousPost.url | url }}">Previous: {{ previousPost.data.title }}</a>{% endif %}
        {% if previousPost and nextPost %}&nbsp;|&nbsp;{% endif %}
        {% if nextPost %}<a href="{{ nextPost.url | url }}">Next: {{ nextPost.data.title }}</a>{% endif %}
    </div>
    </div>
    <br>

    {{content | safe}}
</article>

I can confirm that the header IDs do show up, as does the <aside> block, but with nothing in it.

versipellis commented 2 years ago

Just wanted to bump here to see if you had any thoughts - thanks!

jdsteinbach commented 2 years ago

Thanks @versipellis - I did a little debugging to find out what's happening. The issue you're seeing is related to the order in which @orchidjs/eleventy-plugin-ids and my eleventy-plugin-toc are run by Eleventy itself. (The same is also true with the similar eleventy-plugin-nesting-toc plugin you currently have in the .eleventy.js you shared above.)

The two TOC plugins run by providing an Eleventy filter - a function that manipulates content during the layout template step(s). However, the IDs plugin runs as an Eleventy transform - a transform isn't run until the very last Eleventy compile stage, so it doesn't add IDs to the HTML until after all the layout steps (including filters) have already finished. This means there aren't any IDs on the headings yet when the toc filter runs. Those IDs aren't added till the final "post-build" step in the Eleventy flow.

Neither this plugin (eleventy-plugin-toc) nor the fork eleventy-plugin-nesting-toc are compatible with the IDs plugin you're using, I'm afraid. These TOC plugins only work when the IDs are present before the toc filter is run on content. I recommend adjusting markdownit to provide IDs at the markdown compile stage so that IDs exist before the toc filter is called.

versipellis commented 2 years ago

Gotcha, thanks a ton @jdsteinbach - that's really helpful to know, and explains why I couldn't figure out what was going on! Do you have any suggestions on something similar to markdownit if I'm using Nunjucks instead of Markdown?