Search code examples
nunjuckseleventy

Eleventy, Nunjucks, and shortcode performance/syntax for arbitrarily many items


I'm creating an Eleventy shortcode (for use mostly in markdown) that takes an arbitrary number of arguments and then applies formatting to them before spitting everything out. It vaguely looks like this:

  eleventyConfig.addShortcode("theShortcode", function(...args) {
    let list = '';
    args.forEach( function( listItem) {
      list += '<li>' + listItem + '</li>';
    });
    return list;
  });

And then you do something like this for an arbitrary number of items:

{% theShortcode "item1" "item2" "item3" %}

So I'm not convinced this is the most user friendly way of generating this content. At the very least, I suspect in the average case, the item list will be pretty long and become painfully unreadable in the editor. Is there a smarter way to achieve the same result, or a better syntax I might use here?


Solution

  • If all your shortcode does is create a list, why not just write those in normal markdown? Markdown has a syntax for ordered and unordered lists, after all:

    - unordered list item 1
    - unordered list item 2
    - unordered list item 3
    
    1. ordered list item 1
    2. ordered list item 2
    3. ordered list item 3
    

    If your example was simplified and you actually need to output custom HTML that's not possible in plain markdown, you could use a paired shortcode instead. It can do the same thing as your regular shortcode, but paired shortcodes allow you to write plain content in between the start and end tag, which is easier to read. As an example, here's your list shortcode as a paired shortcode:

    eleventyConfig.addShortcode("makelist", content => {
        const items = content.split(/\r\n|\r|\n/).filter(Boolean);
        const list = items.map(item => `<li>${item}</li>`);
        return `<ul>${"\n"}${list.join("\n")}${"\n"}</ul>`;
    });
    

    You can add more arguments to the function and pass parameters (like switching between an ordered and an unordered list) in the start tag of the shortcode. Use it like this:

    {% makelist %}
    
    list item 1
    list item 2
    list item 3
    
    {% endmakelist %}