11ty / eleventy-plugin-webc

Adds support for WebC *.webc files to Eleventy
https://www.11ty.dev/docs/languages/webc/
120 stars 10 forks source link

Content not accessible in webc file (Error: "Tried to use templateContent too early") #92

Open rothsandro opened 10 months ago

rothsandro commented 10 months ago

The content of other pages is not accessible inside webc pages.

Repro

  1. Create a new Eleventy + WebC project
  2. Add some markdown files with "posts" tag
  3. Add a .webc page that renders a list of posts with the content
---
layout: base
---

<div webc:for="post of collections.posts">
  <div @raw="post.content"></div>
</div>

Repro: https://github.com/rothsandro/repro.eleventy-webc-content

Expected

The posts with their content should be rendered.

Actual

An error is thrown

Tried to use templateContent too early on ./src/blog/post1.md

Further information

This happens only with WebC. If I do the same on a njk page it works fine.

The repro project cannot be started at all, it always fails. My actual project often starts properly (locally, but not on Netlify), the error just occurs every few times.

Versions

@11ty/eleventy: 2.0.1
@11ty/eleventy-plugin-webc: 0.11.1

Node v18.16.0
npm v9.5.1
noelforte commented 8 months ago

Having the same issue, although I can't get my build to start at all. Paging through some of the other issues in 11ty/eleventy it appears that there's some sort of dependency-race-condition occuring where the templates content hasn't been built yet but the call to .content/.templateContent runs before Eleventy can transform the content of the template in question.

It looks like eleventyImport.collections (related GH issue) exists to mitigate template render order issues but I haven't figured out how to get to apply to WebC yet. Hopefully either a fix or workaround will come soon!

chmking commented 8 months ago

I recently hit the same issue and was putting together a minimum repro when I found this.

I have the same inconsistency where the minimum repro won't start at all. My other project will start fine but breaks the moment I edit anything triggering the reload.

VAggrippino commented 2 months ago

I'm experiencing the same issue in a very minimal practice project. Using the following code in a .webc file:

<article class="collections-post" webc:for="post of collections.post.slice(-2)">
    <h3 class="collections-post__title" @text="post.data.title"></h3>
    <div class="collections-post__date" @text="formatted_date(post.data.date)"></div>
    <div class="collections-post__content" @html="post.content"></div>
</article>

I get the message:

[11ty] Problem writing Eleventy templates: (more in DEBUG output) [11ty] 1. Having trouble rendering webc template ./_input/home.webc (via TemplateContentRenderError) [11ty] 2. Check the dynamic attribute: @html="post.content". [11ty] Original error message: Tried to use templateContent too early on ./_input/posts/2023-12-21-vscodevim-broke-quick-open.md (via Error) [11ty] [11ty] Original error stack trace: Error: Check the dynamic attribute: @html="post.content". [11ty] Original error message: Tried to use templateContent too early on ./_input/posts/2023-12-21-vscodevim-broke-quick-open.md [11ty] at ModuleScript.evaluateScript (/home/vince/dev/eleventy-webc/node_modules/@11ty/webc/src/moduleScript.cjs:71:10) [11ty] at ModuleScript.evaluateScriptInline (/home/vince/dev/eleventy-webc/node_modules/@11ty/webc/src/moduleScript.cjs:44:23) [11ty] at AstSerializer.evaluateAttribute (file:///home/vince/dev/eleventy-webc/node_modules/@11ty/webc/src/ast.js:787:40) [11ty] at AstSerializer.getPropContentAst (file:///home/vince/dev/eleventy-webc/node_modules/@11ty/webc/src/ast.js:820:28) [11ty] at AstSerializer.compileNode (file:///home/vince/dev/eleventy-webc/node_modules/@11ty/webc/src/ast.js:1152:36) [11ty] at async AstSerializer.getChildContent (file:///home/vince/dev/eleventy-webc/node_modules/@11ty/webc/src/ast.js:349:56) [11ty] at async AstSerializer.compileNode (file:///home/vince/dev/eleventy-webc/node_modules/@11ty/webc/src/ast.js:1226:36) [11ty] at async Promise.all (index 0) [11ty] at async AstSerializer.getLoopContent (file:///home/vince/dev/eleventy-webc/node_modules/@11ty/webc/src/ast.js:994:11) [11ty] at async AstSerializer.compileNode (file:///home/vince/dev/eleventy-webc/node_modules/@11ty/webc/src/ast.js:1006:15) [11ty] Wrote 0 files in 0.32 seconds (v2.0.1)

... but if I change the template file extension from .webc to .html (which uses Liquid by default) and change it to the following Liquid syntax it works fine:

{% for post in collections.post %}
    <article class="collections-post">
        <h3 class="collections-post__title">{{ post.data.title }}</h3>
        <div class="collections-post__date">{% formatted_date post.data.date %}</div>
        <div class="collections-post__content">{{ post.content }}</div>
    </article>
{% endfor %}
VAggrippino commented 2 months ago

My thanks to @noelforte :

It looks like eleventyImport.collections (related GH issue) exists to mitigate template render order issues but I haven't figured out how to get to apply to WebC yet. Hopefully either a fix or workaround will come soon!

eleventyImport.collections served as a solution for me. I just put the following in my home.webc front matter and everything worked as expected:

eleventyImport:
    collections: ['post']

I don't understand why this works, but I'll keep reading.

cylkee commented 2 weeks ago

Really struggling with this issue :( I'm using WebC with Eleventy.

In eleventy.config.js I have:

eleventyConfig.addCollection("publishedTaggedItems", function (collectionsApi) {
    return collectionsApi
        .getAllSorted()
        .reverse()
        .filter(function (item) {
            return "tags" in item.data && !item.data.draft;
        });
});

I tried adding this to front matter:

eleventyImport:
    collections: ["publishedTaggedItems"]

To the WebC file doing this:

[...]
<for webc:nokeep webc:for="entry of collections.publishedTaggedItems.toSpliced(15, Infinity)">
    [...]
        <summary :xml:lang="language" type="text" @raw="intro(entry.content)"></summary>
    [...]
</for>
[...]

But still getting Tried to use templateContent too early

If I comment out the line with entry.content the site builds fine.

I also have markdownTemplateEngine: "webc" if relevant, but commenting that line does not resolve.

Also tried to work around using page.rawInput but it started to become really complicated.

Was all working fine until I upgraded from v2.0.1 to v3.0.0.

Is there a way to just force the WebC file accessing templateContent to be patient and wait until everything is done?

cylkee commented 2 weeks ago

Is there a way to just force the WebC file accessing templateContent to be patient and wait until everything is done?

It seems there is! I just copied the WebC template into a WebC layout and referenced the layout in the WebC template. I feel like that's a hack though.