3

In Eleventy (11ty) the page source can define custom data in it's front-matter. E.g.:

---
title: this is front-matter data
---
Page content
{% myCustomTag valueOfArg1 %}

where the custom tag (also known as shortcode in Eleventy) is generating extra content based on a configured function handler:

eleventyConfig.addShortcode('myCustomTag', function(arg1) {
    // how can I access here the page front-matter data? E.g. "title"
    return `<div>...${ arg1 }...</div>`;
});

How can I access the page front-matter data in the code of a custom tag (shortcode)?

What I want to achieve is defining a custom tag (shortcode) that has optional arguments. If no arguments are supplied, the arguments are searched in the front-matter:

---
arg1: my value
---
Page content
{% myCustomTag %}

and the myCustomTag handler function:

eleventyConfig.addShortcode('myCustomTag', function(arg1) {
    // if arg1 missing, search page front-matter for arg1
    // arg1 = arg1 || this.page.data.arg1 || 'default';
    return `<div>...${ arg1 }...</div>`;
});
Gabriel Petrovay
  • 20,476
  • 22
  • 97
  • 168
  • Have you tried passing the page/backup variable through to the shortcode as another parameter? – Luke Storry Jan 18 '21 at 16:44
  • The shortcode should have access to the template context using `this`, try if `this.arg1` contains the value you need inside your shortcode callback. – MoritzLost Jan 19 '21 at 10:41

1 Answers1

2

If you're using a shortcode with the function syntax (aka not an arrow function), the function will have access to the page data values through this (docs).

Unfortunately, there isn't access to the front matter, but you can read the file and parse the front matter yourself. Eleventy uses gray-matter internally, so it should already be installed.

const fs = require('fs')
const matter = require('gray-matter')

module.exports = function (eleventyConfig) {
  eleventyConfig.addShortcode('myCustomTag', function(arg1) {
    const str = fs.readFileSync(this.page.inputPath, 'utf8')
    const data = matter(str).data
    console.log(data.arg1)
    // use data however you want
    return
  });
}

If you're generating a lot of pages, it might help to use an async shortcode (also available for Liquid), but in my (very limited) testing it didn't make a huge difference (though you'll have to try for yourself).

person_v1.32
  • 2,641
  • 1
  • 14
  • 27