Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can I process a front matter item like collections processes tags? #1611

Closed
btrem opened this issue Jan 28, 2021 · 5 comments
Closed

Can I process a front matter item like collections processes tags? #1611

btrem opened this issue Jan 28, 2021 · 5 comments

Comments

@btrem
Copy link

btrem commented Jan 28, 2021

11ty collections can process tags whether a post has one tag: foo or whether it has more than one tag: [foo, bar]. I have a front matter variable that might have one value, or more than one, i.e., it might be var: baz or it might bevar: [baz, bat]. Can I use a {% for %} loop to process it either way? In other words, treat var: baz as if var was an array with one item? I tried this:

{% for item in var %}
    // do something with the item 
{% endfor %}

It works when there's more than one value. But when there's only one, in the form var: baz, it processes the value as an array of letters (which makes sense, but it's not what I want). If it can't be done, I can just use

var: [baz]

so not the end of the world. But it'd be nice if I could write it without brackets when there's only 1 item.

@pdehaan
Copy link
Contributor

pdehaan commented Jan 28, 2021

Interesting... Nunjucks or LiquidJS?
I'm thinking you could do it with a custom filter which checks to see if the tag attribute is an Array or not and wrap it if needed.

@pdehaan
Copy link
Contributor

pdehaan commented Jan 28, 2021

Yeah, custom filter should work: https://github.com/pdehaan/11ty-1611

  eleventyConfig.addFilter("toArray", value => {
    if (Array.isArray(value)) {
      return value;
    }
    return [value];
  });

Ref: https://github.com/pdehaan/11ty-1611/blob/fa290cb2d9cb0a8a13fd31acf95986aaf9f26e0e/.eleventy.js#L2-L7

Or, if you want a one-liner:

eleventyConfig.addFilter("toArray", value => Array.isArray(value) ? value : [value]);

<p>Convert the tag to an array using custom <code>toArray</code> filter:</p>
<ol>
  {% for t in (tag | toArray) %}
  <li>{{ t }}</li>
  {% endfor %}
</ol>

Ref: https://github.com/pdehaan/11ty-1611/blob/fa290cb2d9cb0a8a13fd31acf95986aaf9f26e0e/src/pages/single.njk#L18-L23

@pdehaan
Copy link
Contributor

pdehaan commented Jan 28, 2021

Interesting... Nunjucks or LiquidJS?

You must be using Nunjucks, because LiquidJS seems to "just work"(tm) and return a single "single" value instead of splitting by character.

But for future travellers, if you are using liquidjs, you'll need to use the toArray filter in an {% assign %} block before looping, as seen below:

<p>But the <code>toArray</code> filter should still work too:</p>
<ol>
  {% assign tags = tag | toArray %}
  {% for t in tags %}
  <li>{{ t }}</li>
  {% endfor %}
</ol>

@Ryuno-Ki
Copy link
Contributor

I think I've saw Eleventy converting it to an array either way under the hood.
Would need to look up the source code, though.

@btrem
Copy link
Author

btrem commented Jan 28, 2021

The filter works perfectly. I would not have thought to write a custom filter, because I'm new to 11ty. So this resolves the immediate issue, and hopefully will help me solve other problems in the future.

Thanks for your help.

@btrem btrem closed this as completed Jan 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants