Modifying Object in Nunjucks
Indirectly by Using 11ty’s Computed Data Feature
Limitation of Nunjucks
Templating engine Nunjucks has set
tag to create or modify a variable.
{% set username = "joe" %}
{{ username }} // This would print "joe".// Source: Nunjucks Templating Docs
However, it is not possible to create or modify an existing object with set
.
// The Following Does Not Work{% set obj = {} %}
{% set obj.property = 111 %}// Source: {% set %} doesn't work with objects
Using Static Site Generator 11ty
Nunjucks is used in diverse cases, including in a static site generator.
If static site generator 11ty(Eleventy) is used, the following is possible.
---
title: My First Blog Post
img:
cover:
extension: avif
color: '#70ACC4'
eleventyComputed:
img:
cover:
alt: '{{title}}'s Cover Image'
src: '{{page.url}}cover.{{img.cover.extension}}'
---
Above front matter(YAML syntax) resolves to the following object that can be accessed by a Nunjucks template. (e.g. {{img.cover.src}}
)
{
"title": "My First Blog Post",
"img": {
"cover": {
"extension": "avif",
"color": "#70ACC4",
"alt": "My First Blog Post's Cover Image",
"src": "/posts/My First Blog Post/cover.avif"
}
}
}
img
object assgining is a result of 11ty’s Data Cascade(Computed Data).
By default, Eleventy does a simple top level merge (Object.assign) from the different data sources. It doesn’t dive any deeper to merge Object literals or Arrays in the data. — Eleventy Documentation
Comparison
With this feature, there is less need to handle data inside a template file.
Without 11ty
---
title: My First Blog Post
img:
cover:
extension: avif
color: '#70ACC4'
---{% set img_cover_alt = title + 's Cover Image' %}
{# img.cover.alt is not a valid variable name in `set` #}{% set img_cover_src = page.url + 'cover.' + img.cover.extension %}<img src="{{img_cover_src}}" alt="{{img_cover_alt}}">
With 11ty
---
title: My First Blog Post
img:
cover:
extension: avif
color: '#70ACC4'
eleventyComputed:
img:
cover:
alt: '{{title}}'s Cover Image'
src: '{{page.url}}cover.{{img.cover.extension}}'
---<img src="{{img.cover.src}}" alt="{{img.cover.alt}}">
Common Result
// page.url = /posts/My First Blog Post/<img
src="My First Blog Post's Cover Image"
alt="/posts/My First Blog Post/cover.avif"
>
Absence of template literals in Nunjucks can be supplemented by this.
const a = 5;
const b = 10;console.log(`
Fifteen is ${a + b} and // "Fifteen is 15 and
not ${2 * a + b}. // not 20."
`);// Source: Template literals (Template strings)
Use Case
Javascript functions and Nunjucks macros do not work in front matter of YAML syntax, such as the above. However, 11ty shortcodes do work.
JavaScript functions require either JavaScript front matter or a JavaScript data file (template, directory, or global). YAML and JSON do not support JavaScript functions. — Eleventy Documentation
Find Parent Folder Path
Since a page’s parent folder path is not supplied by 11ty, the following shortcode can be added and can be used in non-javascript front matters.
module.exports = (eleventyConfig) => {
eleventyConfig.addShortcode('parentUrl',
(page) => (page.url).replace(`${page.fileSlug}/`, ''));
};// FileName: .eleventy.js
The following front matter(YAML syntax) is successfully computed.
---
layout: default.njk
eleventyComputed:
img:
mock:
cover: '{% parentUrl page %}cover.{{img.cover.extension}}'
---