11ty / eleventy

A simpler site generator. Transforms a directory of templates (of varying types) into HTML.
https://www.11ty.dev/
MIT License
17.06k stars 494 forks source link

(Liquid) Unable to access 11ty globals like page.X inside a partial rendered via the {% render %} tag #2453

Open AleksandrHovhannisyan opened 2 years ago

AleksandrHovhannisyan commented 2 years ago

Describe the bug

Per the Liquidjs docs, the {% include %} tag is deprecated and it's recommended that we use the {% render %} tag instead. See also: https://github.com/11ty/eleventy/issues/2411. Unfortunately, while it's currently possible to use the {% render %} tag in 11ty, it's not possible to access globals or global data from within the rendered template. Per the Liquid docs on render:

When a partial template is rendered, the code inside it can’t access its parent’s variables

However, the section on passing in arguments to the rendered template clarifies that globals should be accessible:

globals don’t need to be passed down. They are accessible from all files.

The LiquidOptions interface does have a globals config here: https://github.com/harttle/liquidjs/blob/01029aba87e9a40ce104cdd9b8228170f345792c/src/liquid-options.ts#L65-L66. And 11ty supports configuring Liquid options via eleventyConfig.setLiquidOptions.

Unfortunately, there is no way to pass along 11ty global data and the page variable because these are not accessible from the .eleventy.js config as far as I can tell. How do I proceed?

To Reproduce Steps to reproduce the behavior:

  1. Clone this minimal sandbox branch: https://github.com/AleksandrHovhannisyan/11ty-sandbox/tree/render-tag
  2. Run yarn to install 11ty, the only dependency.
  3. Run yarn serve to start the server.
  4. Observe that the argument passed into the rendered partial is accessible within the partial, as expected.
  5. Observe that the page variable is not accessible within the partial (unexpected).

.eleventy.js

const TEMPLATE_ENGINE = 'liquid';

module.exports = (eleventyConfig) => {
  return {
    dir: {
        input: 'src',
        output: '_site',
        includes: '_includes',
        layout: '_layouts'
    },
    dataTemplateEngine: TEMPLATE_ENGINE,
    markdownTemplateEngine: TEMPLATE_ENGINE,
    htmlTemplateEngine: TEMPLATE_ENGINE,
    templateFormats: ['html', 'md', TEMPLATE_ENGINE],
  };
};

src/_includes/partial.html

{{ arg | log }}
{{ page | log }}

src/index.html

{% render "partial.html" arg: "value" %}

Expected behavior It should be possible to access 11ty data and page data from within a rendered partial since render is the recommended tag for rendering partials in Liquid.

Observed behavior page is undefined inside a rendered partial.

Environment:

Additional context

https://github.com/11ty/eleventy/issues/2411

NOTE: It is possible to work around this issue by passing in the necessary information as arguments. But I'm wondering if there's a way to avoid having to do that.

woodcox commented 2 years ago

I’m also experiencing this same issue with accessing global and page data using:

{% render “partial.html” %}
vrugtehagel commented 6 months ago

Related (i.e. can be extended to include this): https://github.com/11ty/eleventy/pull/3212