How to dump a collection using eleventy and nunjucks
Leipzig
How to dump a collection using eleventy and nunjucks #
Nunjucks offers some builtin filters out of the box.
Most of them are ported from jinja's filters, in addition nunjucks has a few of its own.
Examples #
{% set items = [1, 2, 3] %}
{{ items | first }}
> 1
{{ items | dump }}
> [1,2,3]
{% set foods = { ketchup: '5 tbsp', mustard: '1 tbsp', pickle: '0 tbsp', salt: '1 tbsp' } %}
{{ foods | length }}
> 3
{{ foods | dump }}
> {"ketchup":"5 tbsp","mustard":"1 tbsp","pickle":"0 tbsp"}
Dumping a collection #
However, dumping a collection leads to the following error:
TypeError: Converting circular structure to JSON (Template render error)
There are several solutions to dump a circular structure anyway:
- in node.js use
util.inspect(object)
to replace circular links with "[Circular]" - use JSON.stringify with a custom replacer function (the second parameter of
stringify
) to exclude already serialized objects** - use a module/plugin like Circular JSON
Example using util #
Add a filter function in .eleventy.js.
Util is a built-in module, you do not have to install it.
.eleventy.js
const util = require('util')
eleventyConfig.addFilter('dump', obj => {
return util.inspect(obj)
});
You can pass an options as second parameter:
util.inspect(obj, { depth: 5, ... })
Usage
<pre>{{ foods | dump }}</pre>
Output
{ ketchup: '5 tbsp',
mustard: '1 tbsp',
pickle: '0 tbsp',
salt: '1 tbsp' }
Example using JSON.stringify #
Solution from MDN.
This solution removes all repeating values, not just the circular ones.
Add a filter function in .eleventy.js.
.eleventy.js
eleventyConfig.addFilter('dump', obj => {
const getCircularReplacer = () => {
const seen = new WeakSet();
return (key, value) => {
if (typeof value === "object" && value !== null) {
if (seen.has(value)) {
return;
}
seen.add(value);
}
return value;
};
};
return JSON.stringify(obj, getCircularReplacer(), 4);
});
Usage
<pre>{{ foods | dump }}</pre>
Output
{
"ketchup": "5 tbsp",
"mustard": "1 tbsp",
"pickle": "0 tbsp",
"salt": "1 tbsp"
}