eleventy icon indicating copy to clipboard operation
eleventy copied to clipboard

Access the Data Cascade in filters and shortcodes

Open mbforbes opened this issue 2 years ago • 7 comments

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.page Added in v2.0.0
  • this.eleventy Added in v2.0.0
module.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:

  1. There are more data properties available. For example, using Nunjucks, this.ctx is available. Critically, it contains the entire Data Cascade (I think). Perhaps we could list all the properties that are available?
  2. 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.
  3. 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)

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!

mbforbes avatar Mar 05 '23 01:03 mbforbes

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 avatar Mar 05 '23 04:03 pdehaan

@pdehaan Thank you!! 🙏🙏🙏 I am bookmarking this

mbforbes avatar Mar 05 '23 04:03 mbforbes

Slightly modifying this one to be the home base for a better DX for this!

zachleat avatar Dec 05 '23 14:12 zachleat

Related: #2901

zachleat avatar Dec 05 '23 14:12 zachleat

Demilestoning this from 3.0—sorry!

zachleat avatar Jul 01 '24 22:07 zachleat