Check if string is empty in Nunjucks? - nunjucks

Using Eleventy with Nunjucks, and need to check if a front matter field is empty and if a string is empty. It would be the same thing as isEmpty() in JS. Does Nunjucks support this functionality? It seems like a pretty simple and common feature, but I've looked all over the docs and StackOverflow but can't find any mention or example.
Thanks :)

I tested like so:
---
name: ray
age:
---
{% if age %}
age has a value
{% else %}
age has NO value
{% endif %}
And it worked as expected, I got: "age has NO value".

Related

Errors with nesting macros and passing a collection through them? Using Eleventy with Nunjucks

Somewhat of a more advanced question here... is it possible to pass a collection down through a few macros? For example, I have a blog posts section:
{% from "components/switchers/topCoupons.njk" import topBonuses %}
{{ topCoupons(
title = "Top Coupons",
blurb = "some body text content",
posts = collections.coupon
) }}
Then within the posts macro, I have a slider macro:
{% from "components/sliders/generalSlider.njk" import generalSlider %}
{{ generalSlider(
slides = posts
) }}
Then within the slider macro, I have a card macro:
{%- for slide in slides -%}
{% from "components/cards/card.njk" import card %}
{{ card(
title = posts
) }}
{%- endfor -%}
At the moment it is not working but I'm wondering how could I approach this situation and whether Eleventy and Nunjucks even offer this type of functionality, what the solution would be, or if I'm better off using another SSG that would have this kind of infrastructure?
At the moment, it is throwing this error when trying to compile:
[eleventy:dev] `TemplateContentRenderError` was thrown
[eleventy:dev] > (./src/index.njk)
[eleventy:dev] TypeError: Converting circular structure to JSON
Any and all insight is very much appreciated. Thanks :)
There's nothing inherently wrong with passing Eleventy collections through nested macros since a collection is just a regular JavaScript array. The issue arises depending on how you're using the collection inside Nunjucks since the collections object is a circular structure.
You can try this yourself by passing a collection into a macro and only accessing individual properties in the collection.
{# include.njk #}
{% macro navigation(data) %}
<ol>
{%- for page in data -%}
<li>
{{ page.data.title }}
</li>
{%- endfor -%}
</ol>
{% endmacro %}
{{ navigation(collections.all) }}
This setup works perfectly fine even with more macro nesting. The error you're running into comes from doing something like using the dump filter.
{# include.njk #}
{{ collections.all | dump }}
Since I don't know what your macros are doing, I'm not sure what is exactly causing the error to be thrown, but you might want to look for things that might be JSON.stringifying the collections object. Depending on your use case, you might have to manually parse the object yourself, find an external library, or only use the fields you need. Creating custom Eleventy filters may help.

How can I catch properties of an object's relations in a twig dump?

I am exploring the possibilities of OctoberCMS in a test project about movies. Each movie has several properties, among others one or more genres (both movies and genres are models btw). I am now trying to code something for the front-end filters on a movie list page, but I am having problems trying to get to the field genre_title -see screenshot at https://i.stack.imgur.com/yrIHm.png. When I do {{ dump(movies.items[0].relations) }} I see the collection genres but from then on I am stuck. I have tried many different things:
{{dump(movies.items[0].relations[0].items)}}
{{dump(movies.items[0].relations['genres'].items)}}
{{dump(movies.items[0].relations.items)}}
etc.
Most of my attempts gave me NULL as a result. How can I get to the genre_title? I'd really appreciate it if someone could point me in the right direction! Many thanks!
Its collection so you can simply need to loop
{% for movie in movies %}
{% for genre in movie.genres %}
{{ genre.genre_title }} - {{ genre.slug }} - {{dump(genre)}}...
{% endfor %}
{% endfor %}
Now you can have all the data available.
if any doubt please comment.

Nunjucks if with more than one 'or' conditions

I'm kind of stuck making a multiple comparison using nunjucks!
It works when I use:
{% if (tab.type != 'default') %}
but not when I use:
{% if (tab.type != 'placement') or (tab.type != "version1") or (tab.type != 'default') %}
In the latter, it keeps getting there as if everything was equal instead of different!
HELP!
Thanks
Strange! I've had the exact same problem just now. To be precise, I was checking to see if page title is not certain value and then output some code. There were two pages which are impacted by this so my first logical condition was as same as yours.
{% if title != 'Messenger' or title != 'Video' %}
OUTPUT
{% endif %}
It didn't work.
What worked for my case in the end (after countless combinations) is this:
{% if title != 'Messenger' and title !='Video' %}
OUTPUT
{% endif %}
In my case it doesn't matter too much because I can have only one page title anyway, but in your or someone else's case it may be different. Someone maybe wants to trigger the output if either one of the conditions has been met.
As far as my logics goes: and means that both conditions must be fulfilled, which clearly isn't the case here.
If you still read this, please let me know if this has worked for you.

Listing records by 'sortorder' in Bolt CMS template not following numerical value

I have a contenttype called "courses" which I would like to list in a specific order. I'm able to do so in the backend (by setting has_sortorder: true for the corresponding taxonomy), but I am not able to get the records to list in the same order in my "courses.twig" listing template. Here's a snippet from "courses.twig" where I'm outputting the list of records:
<ul>
{% for record in records|order('sortorder') %}
<li>Name: {{ record.title }}</li>
{% endfor %}
</ul>
The output is not following the numerical 'sortorder' value as defined in the backend. Seems like a trivial thing, but I'm completely stumped.
Could anyone offer clues or tell me if I missed anything?
Thanks!
(1) Use {{ dump(record) }} to check if your record has a sortorder field.
(2) A contenttype definition can have a listing_sort field. Have you tried that?

Liquid templates - accessing members by name

I'm using Jekyll to create a new blog. It uses Liquid underneath.
Jekyll defines certain "variables": site, content, page, post and paginator. These "variables" have several "members". For instance, post.date will return the date of a post, while post.url will return its url.
My question is: can I access a variable's member using another variable as the member name?
See the following example:
{% if my_condition %}
{% assign name = 'date' %}
{% else %}
{% assign name = 'url' %}
{% endif %}
I have a variable called name which is either 'date' or 'url'.
How can I make the liquid equivalent of post[name] in ruby?
The only way I've found is using a for loop to iterate over all the pairs (key-value) of post. Beware! It is quite horrible:
{% for property in post %}
{% if property[0] == name %}
{{ property[1] }}
{% endif %}
{% endfor %}
Argh! I hope there is a better way.
Thanks.
I don't know what I was thinking.
post[name] is a perfectly valid liquid construction. So the for-if code above can be replaced by this:
{{ post[name] }}
I thought that I tried this, but apparently I didn't. D'oh!
Liquid admits even fancier constructs; the following one is syntactically correct, and will return the expected value if post, element, categories, etc are correctly defined:
{{ post[element.id].categories[1].name }}
I am greatly surprised with Liquid. Will definitively continue investigating.
Actually, this did not work for me. I tried a bunch of different combinations and what finally worked was
<!-- object myObj.test has the string value "this is a test" -->
{% assign x = 'test' %}
{{ myObj.[x] }}
Output:
this is a test

Resources