11ty / eleventy

A simpler site generator. Transforms a directory of templates (of varying types) into HTML.

Home Page:https://www.11ty.dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Access complete page data within layout?

kuwts opened this issue · comments

commented

Describe the bug
I am trying to access the complete page data with the page variable within a layout. At the moment, I can easily access specific front-matter fields but not the global page data. The page variable returns some information (see below) but nothing about front matter fields.

To Reproduce
When I try to {{ page | dump }} I get
{"date":"2021-10-25T22:00:23.450Z","inputPath":"./src/bonuses/bonus.njk","fileSlug":"21","filePathStem":"/bonuses/bonus","url":"/bonuses/bonus/","outputPath":"dist/bonuses/bonus/index.html"}

I thought making it {{ page.data | dump }} would work, but this comes back empty.

I can access specific front-matter fields with interpolation, but I'm trying to figure out how to get the full page data.

Expected behavior
I would like to access the page variable and add it into a Nunjucks macro. For example:
{{ simpleCard(cardData = page.data) }}

Screenshots
n/a

Environment:
macOS High Sierra, Eleventy version 0.12.1

Not sure if it helps, but one thing I've done in the past is use the eleventyComputed to return all the original data that it receives (which will include the package.json data, all frontmatter, page data, and collections).

// ./src/index.11tydata.js
module.exports = {
  eleventyComputed: {
    frontmatter: (data) => data
  }
};
---
# ./src/index.njk
title: foo
pageId: home
age: 99
bool: true
---

<pre data-page>
{{ page | dump | safe }}
</pre>

<pre data-frontmatter>
{{ frontmatter | dump | safe }}
</pre>

OUTPUT

<pre data-page>
{
  date: 2021-12-05T18:56:28.523Z,
  inputPath: './src/index.njk',
  fileSlug: '',
  filePathStem: '/index',
  url: '/',
  outputPath: 'www/index.html'
}
</pre>

<pre data-frontmatter>
<ref *1> {
  pkg: {
    name: '11ty-2052',
    version: '1.0.0',
    main: 'index.js',
    scripts: {
      build: 'eleventy',
      test: 'echo "Error: no test specified" && exit 1'
    },
    keywords: [],
    author: '',
    license: 'ISC',
    description: '',
    devDependencies: { '@11ty/eleventy': '^0.12.1' }
  },
  eleventyComputed: { frontmatter: [Function: frontmatter] },
  title: 'foo',
  pageId: 'home',
  age: 99,
  bool: true,
  page: {
    date: 2021-12-05T18:56:28.523Z,
    inputPath: './src/index.njk',
    fileSlug: '',
    filePathStem: '/index',
    url: '/',
    outputPath: 'www/index.html'
  },
  collections: { all: [ [Object] ] },
  frontmatter: [Circular *1]
}
</pre>

So I think your code would just be able to use something like this instead (and your macro would receive all the local frontmatter, as well as global data, collections info, package.json, etc). Although you could probably filter the object using a custom filter or some clever hacking of the frontmatter eleventyComputed function.

{{ simpleCard(cardData = frontmatter) }}

... in fact, the clever hacking is probably just as simple as using the JavaScript ... spread syntax and some object destructuring:

module.exports = {
  eleventyComputed: {
    frontmatter: ({collections, page, pkg, ...rest}) => rest
  }
};

… which now changes the output to this:

<pre data-frontmatter>
{
  eleventyComputed: { frontmatter: [Function: frontmatter] },
  title: 'foo',
  pageId: 'home',
  age: 99,
  bool: true,
  frontmatter: ''
}
</pre>