-
-
Notifications
You must be signed in to change notification settings - Fork 495
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
How to address tags within template or rather how to check with Nunjucks if certain tag exists? #524
Comments
Where does the |
As part of the Front Matter. |
Could you share that part? |
On some pages I use single tags: ---
tags: tag1
--- on some others multiple tags on multiple lines; ---
tags:
- tag1
- tag2
- tag3
--- What I search for is a safe 11ty and Nunjucks solution to check if "tags" contains "tag1" (in Liquid parlance). |
Can't reproduce. Using a directory structure like this:
with ---
---
{% if title === "Home" %}
<div class="home">Home</div>
{% endif %}
{% if tags.includes("tag1") %}
<div class="tag1">
{% else %}
<div>
{% endif %}
Tags: {{ tags }}
{{ content | safe }}
</div>
---
layout: tag
tags: tag1
---
I'm single and ---
layout: tag
tags:
- tag1
- tag2
---
I'm multiple. resp. ---
layout: tag
tags: tag2
---
I don't have tag1 yields the following HTML: <div class="tag1">
Tags: tag1
<p>I'm single</p>
</div> <div class="tag1">
Tags: tag1,tag2
<p>I'm multiple.</p>
</div> <div>
Tags: tag2
<p>I don't have tag1</p>
</div> |
On a side note: |
Thank you very much, @Ryuno-Ki for notes. Back in the house now. Indeed, the deeper I get the stranger things become ... To sum up: {% elseif "tag1" in tags %} {# works #} {% if "tag1" in tags %} {# crashes #} {% elseif tags.includes("tag1") %} {# works #} {% if tags.includes("tag1") %} {# crashes #} But, with both working examples, it seems that any further conditional have to be in the same syntax; for the first example: {% elseif "tag1" in tags %} {# works #}
do something
{% elseif "tag9" in tags %} {# works #}
do something else {% elseif "tag1" in tags %} {# works #}
do something
{% elseif page.outputPath === "output/path/to/file/with/tag9" %} {# crashes #}
do something else |
Hm, I recall that some variables behave differently on the home page vs. all other pages. That is Maybe check for existence of |
Very interesting aspects, @Ryuno-Ki. Given the documentation, I have thought so far that only {# works #}
{% if title === "AnyPageTitle" %} {# to check any page title #}
do something
{% elseif "tag1" in tags %}
do something
{% else %}
do something
{% endif %} {# works not for tags, but works for title also #}
{% for item in collections.all %} {# e.g. looping through all collections #}
{% if item.data.title === "AnyPageTitle" %} {# to check any page title #}
do something
{% elseif item.data.tags === "tag1" %}
do something
{% else %}
do something
{% endif %}
{% endfor %} {# crashes #}
{% for item in collections.all %} {# e.g. looping through all collections #}
{% if item.data.title === "AnyPageTitle" %} {# to check any page title #}
do something
{% elseif "tag1" in tags %}
do something
{% else %}
do something
{% endif %}
{% endfor %} Even though it is expected, the third example does not work for some reasons. these could be:
|
I'm pretty sure Eleventy casts tags as arrays, even if written as strings in front matter yaml. (Can't find that in the docs atm, but quite sure I read it somewhere in there.) Nunjucks isn't straight javascript, so I'd be surprised if
You could set up a nunjucks or universal filter to check if tag exists on the collection item. Or just loop through the items tags and set a flag if the tag in question exists. {% set found = false %}
{% for item in collections.all %}
{% for tag in item.data.tags %}
{% if tag === 'tag1' %}{% set found = true %}{% endif %}
{% endfor %}
{% if found %} here we are tag1 {% endif %}
{% endfor %} |
Very useful hints @jevets. Thank you. The conclusion I draw from this excursion on the whole is that I am tending to get back to where I was starting from, i e. to separate conditions into several layout templates when it comes to produce something concrete. The puzzling thing is that some situations work unexpectedly and some do not work with or without errors. To give some insights from a beginner`s perspective, some reasons for giving up are:
And in addition:
I like Eleventy very much. It is such an elegant and powerful tool. As a beginner, you can achieve success quickly, but you can also fail quickly against the background of the documentation's status quo. Much more transparency is needed here to let the diamond shine. |
I don't think there is a good native way to do this. I use this filter: |
@danfascia: |
@danfascia Is that a private repo, maybe? |
Sorry, it is a private repo, here is the filter code to be placed in
Here is an example of how to use it, since I always find that the missing piece of the 11ty docs.
|
Looks interesting, @danfascia. In this constellation, how would the important Universal filter part look like? I guess: eleventyConfig.addFilter( "INCLUDE_FILTER", function( arr, key, value ) {
return arr.filter( item => {
const keys = key.split( '.' );
const reduce = keys.reduce( ( object, key ) => {
return object[ key ];
}, item );
const str = String( reduce );
return ( str.includes( value ) ? item : false );
} );
} ); If so, May I ask you to explain the |
@ssgstarter Commonly used in two ways. See the nunjucks docs for more. {% set foo = "some string" %}
{% set bar %}
some string and the contents of an `include`
{% include "file.njk" %}
{% endset %} To import the filter, you'd need to do something like this: // .eleventy.js
const includesFilter = require("./path/to/your/copy/of/includes.js")
module.exports = function (eleventyConfig) {
eleventyConfig.addFilter('includes', includesFilter)
// you could name it whatever you want, i.e.
// eleventyConfig.addFilter('has_tag', includesFilter)
} |
Thank you, @jevets for elucidations. Especially the second part of your hint.
{% set postslist = collections.cases | includes("data.modalities", tag ) %} |
@ssgstarter This is an example of how you could use the filter. See nunjucks filter docs too. If you'd named the filter something else when registering it with Eleventy, you'd call it differently. If you did this: eleventyConfig.addFilter('has_tag', includesFilter) Then you'd use it like this: {% set postslist = collections.cases | has_tag("data.tags", "tag1" ) %} In @danfascia's example usage:
{% for post in postslist %}
{% include "post.njk" %}
{% endfor %} I think you just need to spend some time getting to know nunjucks filters. Have a look through nunjuck's built-in filters to get the idea. The A potential example for your use case: {% if title === "Home" %}
<div class="home">
{% elseif tags | includes(tags, "tag1") %}
<div class="tag1">
{% endif %} |
Awesome, @jevets! 🥇 Thank you so much for these deep explanations. Now I can read and understand the different meaning of @zachleat I can imagine that other people (especially beginners like me) would be glad to find their both revealing aspects in the official documentation. By the way, I am a big fan of your work! What remains is somehow Faustian: to use or not to use? Maybe a question of further use cases ... related to @Ryuno-Ki's great hint: somehow pure and legible without any custom filter etc. {% elseif "tag1" in tags %} or related @danfascia's little bit extensive code and much harder to read {% elseif tags | includes(tags, "tag1") %} |
Couple of things here: Most importantly, Eleventy transforms tags to always be an Secondly, based on some of the discussion in this issue I added all of these tests and they all pass fine:
So you shouldn’t need a filter for this but if you want to use a filter that’s okay too. Thanks everyone for your help here! |
|
Hmm, re-reading the original comment I think it might just be a baseline JS syntax misunderstanding. You’re likely trying to run
short circuits when title === "Home" (never running the
does not short circuit. Maybe also related to #556 which @edwardhorsford fixed for the next version. |
My solution for this (third line) is:
I am wondering why this does not work:
In general, is the above solution correct?
I am asking this because I get the following error when I extend the above code like this:
The text was updated successfully, but these errors were encountered: