Search code examples
mustachemetalsmith

How do I set up multiple content areas in metalsmith?


I have a very simple use case for metalsmith that doesn't seem to be covered by any readily available documentation.

In my index.html I want multiple content areas:

<!-- in my index html -- a single page landing site -->
<body>
  <section id="about">
     {{{about}}}
  </section>
  <section id="faq">
     {{{faq}}}
  </section>
...

And I want the contents for about and faq to come from markdown files. I'm happy to change how my files are organised/marked up.

I just can't figure out which plugins to use to make it work, everything seems geared towards generating one output file per source file.

The plugins that seem they would work (metalsmith-in-place and metalsmith-layouts) tell you to come to SO for more elaborate examples, so here we are!


Solution

  • You can do multiple content areas with a language that supports template inheritance, like swig, combined with metalsmith-in-place.

    Without using markdown you could do so like this:

    src/index.swig

    {% extends 'templates/default.swig' %}
    
    {% block about %}
      Content for about
    {% endblock %}
    
    {% block faq %}
      Content for faq
    {% endblock %}
    

    templates/default.swig

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8" />
    </head>
    <body>
      <section id="about">
        {% block about %}{% endblock %}
      </section>
      <section id="faq">
        {% block faq %}{% endblock %}
      </section>
    </body>
    </html>
    

    build.js

    /**
     * Dependencies
     */
    var filenames = require('metalsmith-filenames');
    var inPlace = require('metalsmith-in-place');
    var metalsmith = require('metalsmith');
    
    /**
     * Build
     */
    metalsmith(__dirname)
    
      // Process templates
      .use(filenames())
      .use(inPlace('swig'))
    
      // Build site
      .build(function(err){
        if (err) throw err;
      });
    

    Then run node build.js. Now if you want to use markdown as well this isn't really possible. Marked, the renderer for metalsmith-markdown, will surround your content with <p>s, escape certain characters and so forth. Which would make maintaining the templates a hassle as metalsmith-markdown might break the swig tags. It might still work, but I definitely would not recommend it.

    So what I recommend is the above setup. You would lose the advantage of using markdown, but gain some extra organisation options. It's up to you to decide which you prefer.