I'm writing some pretty huge articles consisting of multiple (80+) Matrix blocks of various types. They're so long they'd benefit from in-article navigation for skip-links.

WordPress has a plugin called autogen_menu which creates linked navigation from the header hierarchy in a post. You just put in a small snippet where you want the generated nav to go and it generates all the links (and presumably id's on the headers) itself. Has Craft got anything similar, I've not been able to find a plugin that does this?

Or, would this be better outside of Craft entirely and done as JS?

  • Thanks for the answers guys, but they're only doing half of what I mean, and the Matrix route would end up with me having some 140+ blocks on a single page - 80 is already causing slow-down in the UI. Maybe an example is better: See here: mattwilcox.net/archives/… The Menu and links at the top are being automatically generated from the article. That's what I would like. Jun 26, 2014 at 8:39

3 Answers 3


If I'm understanding you correctly, you want users when they visit your site to have a secondary menu that has links to various points in the article. That would actually be very easy to do in Craft. It's also possible for you to paginate a page, but that would be far more in-depth.

For skip links, you would need to run over the matrix twice. You will also need an anchor matrix block. It can either be a dedicated block for anchor tags, or a header block. You run over it the first time to create your menu:

<ul class="article menu">
{% for block in entry.articleMatrix.type('header') %}
    <li><a href="#{{ block.header|slugify }}">{{ block.header }}</a></li>
{% endfor %}

Then later when you are running over your article, you can check for block type and add the id as needed:

{% if block.type == "header" %}
    <h1 id="{{ block.header|slugify }}">{{ block.header }}</h1>
{% endif %}

This is a really basic example. It uses Bob Olde Hampsink's slugify plugin (it uses Craft's built in slug method). It would be better if you could determine (maybe with a drop down field in your block) what level of heading the block is. I suggest you also cache each matrix loop for performance.

  • Nice answer, Bryan! To further improve this, you could exchange the replace filter with Bob Olde Hampsink's slugify filter, which uses Craft's core slug technology.
    – carlcs
    Jun 25, 2014 at 21:20
  • Good idea! It's been added. Jun 25, 2014 at 21:25

If you just mean to create an anchor-link menu, just use this plugin: Anchor


If you want to create a multi-site article pagination, you could do it like this:

  • Add a page-break-block to your matrix.
  • Get your entry by the slug's segment:

    {% set entry = craft.entries.section('section_handle').slug( craft.request.getSegment(2) ) %}
  • Add a route which redirects to the template, if an additional segment is added, for example:


  • You could check with a conditional in your template what lastSegment is passed, and depending on it, show parts of your matrix.

  • I think he's referring to this being on the front-end. I think this because he mentioned a snippet in WordPress (a shortcode methinks). Jun 25, 2014 at 19:42
  • Ah ok, makes sense. I'll edit the answer.
    – Victor
    Jun 25, 2014 at 19:48

I'm not sure I fully understand what you are trying to do, but I think this may apply as an option to consider. Matrix Blocks are Element Types and the {% paginate %} tag works with all Element Types.

So you could treat your blocks as you would a section with entries, and paginate them. A simple example:

{% paginate entry.articleMatrix.limit(3) as blocks %}

  {% for block in blocks %}

    {# Display all your blocks output as needed #}
    <div class="block {{ block.type }}">
      {% include "_partials/blocks/" ~ block.type %}   

    {% if paginate.prevUrl %}
    <a href="{{ paginate.prevUrl }}">Previous Page</a>
    {% endif %}

    {% if paginate.nextUrl %}
        <a href="{{ paginate.nextUrl }}">Next Page</a>
    {% endif %}

  {% endfor %}

{% endpaginate %}

Pagination in the Craft Docs

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.