eleventy
eleventy copied to clipboard
Access the Data Cascade in filters and shortcodes
I was trying to use data from the Data Cascade in a filter. I asked about it in this discussion: https://github.com/11ty/eleventy/discussions/2841 and @pdehaan extremely helpfully solved it.
The relevant docs I could find are here: https://www.11ty.dev/docs/filters/#scoped-data-in-filters
which say:
A few Eleventy-specific data properties are available to filter callbacks.
this.pageAdded in v2.0.0this.eleventyAdded in v2.0.0module.exports = function(eleventyConfig) { // Make sure you’re not using an arrow function here: () => {} eleventyConfig.addFilter("myFilter", function() { // this.page // this.eleventy }); };
However, I think this documentation could be improved:
- There are more data properties available. For example, using Nunjucks,
this.ctxis available. Critically, it contains the entire Data Cascade (I think). Perhaps we could list all the properties that are available? - There are properties available before v2.0.0. Because both the properties listed are tagged as v2.0.0, I thought those were the only ones. Since I was on v1.0.0, I didn't think the arrow function distinction would affect me, but it does.
- The properties that are available depend on the filter. From @pdehaan, they're available at:
- Nunjucks:
this.ctx - Liquid:
this.context.environments - Eleventy: (must pass in manually)
- Nunjucks:
I think it's because I'm bad at JavaScript, but I find it very difficult to figure out what information I can access when I'm working inside filters or templating languages. Having documentation that lists out variables more exhaustively would help me out a lot. (I run into this genre of issue frequently working on my Eleventy + Nunjucks site.)
Many thanks for your consideration!
I think it's because I'm bad at JavaScript, but I find it very difficult to figure out what information I can access when I'm working inside filters or templating languages.
Here's a few tricks I use (apart from the obvious console.log(this)…
In most projects I end up using something like a custom keys filter which dumps an object's available keys:
eleventyConfig.addFilter("keys", obj => Object.keys(obj).sort());
Or, one of my favorites, using Node's util.inspect() method to dump an object. It isn't quite JSON or parseable, but will handle recursively nested objects better than JSON.stringify() if you happen to be debugging an object which might include a reference to a collection which might include references to the current page:
eleventyConfig.addFilter("inspect", obj => require("node:util").inspect(obj, {sorted: true}));
USAGE
---
title: DEBUG
---
<h1>{{ title }}</h1>
<pre data-page-keys>{{ page | keys | inspect }}</pre>
<pre data-page-inspect>{{ page | inspect }}</pre>
<hr/>
{% for p in collections.all %}
<section>
<pre data-collection-page>{{ p | keys | inspect }}</pre>
<pre data-collection-page-data>{{ p.data | keys | inspect }}</pre>
</section>
{% endfor %}
OUTPUT
<h1>DEBUG</h1>
<pre data-page-keys>[
'date',
'filePathStem',
'fileSlug',
'inputPath',
'outputFileExtension',
'outputPath',
'templateSyntax',
'url'
]</pre>
<pre data-page-inspect>{
date: 2023-03-05T03:56:11.339Z,
filePathStem: '/index',
fileSlug: '',
inputPath: './src/index.liquid',
outputFileExtension: 'html',
outputPath: 'www/index.html',
templateSyntax: 'liquid',
url: '/'
}</pre>
<hr/>
<section>
<pre data-collection-page>[
'content',
'data',
'date',
'filePathStem',
'fileSlug',
'inputPath',
'outputPath',
'page',
'template',
'templateContent',
'url'
]</pre>
<pre data-collection-page-data>[ 'collections', 'eleventy', 'page', 'pkg', 'title' ]</pre>
</section>
@pdehaan Thank you!! 🙏🙏🙏 I am bookmarking this
Slightly modifying this one to be the home base for a better DX for this!
Related: #2901
Demilestoning this from 3.0—sorry!