Closed carbontwelve closed 3 months ago
Just checked and this still happens in 2.0.0-canary.3
although with a nicer error output (nice work!)
[11ty] Problem writing Eleventy templates: (more in DEBUG output)
[11ty] 1. Having trouble rendering liquid template ./posts/2018-05-03-build-an-incremental-web-game-with-vue-js.md (via TemplateContentRenderError)
[11ty] 2. unexpected token at "? '/' + units...", file:./posts/2018-05-03-build-an-incremental-web-game-with-vue-js.md, line:285, col:96 (via ParseError)
[11ty] 3. unexpected token at "? '/' + units..." (via AssertionError)
[11ty]
[11ty] Original error stack trace: AssertionError: unexpected token at "? '/' + units..."
[11ty] at new AssertionError (/Users/simon/Code/photogabble/website/node_modules/liquidjs/dist/liquid.node.cjs.js:679:28)
[11ty] at assert (/Users/simon/Code/photogabble/website/node_modules/liquidjs/dist/liquid.node.cjs.js:836:15)
[11ty] at Tokenizer.readFilter (/Users/simon/Code/photogabble/website/node_modules/liquidjs/dist/liquid.node.cjs.js:1958:9)
[11ty] at Tokenizer.readFilters (/Users/simon/Code/photogabble/website/node_modules/liquidjs/dist/liquid.node.cjs.js:1947:31)
[11ty] at new Value (/Users/simon/Code/photogabble/website/node_modules/liquidjs/dist/liquid.node.cjs.js:2432:34)
[11ty] at new Output (/Users/simon/Code/photogabble/website/node_modules/liquidjs/dist/liquid.node.cjs.js:4164:23)
[11ty] at Parser.parseToken (/Users/simon/Code/photogabble/website/node_modules/liquidjs/dist/liquid.node.cjs.js:4225:24)
[11ty] at Parser.parseTokens (/Users/simon/Code/photogabble/website/node_modules/liquidjs/dist/liquid.node.cjs.js:4215:33)
[11ty] at Parser.parse (/Users/simon/Code/photogabble/website/node_modules/liquidjs/dist/liquid.node.cjs.js:4209:21)
[11ty] at Liquid.parse (/Users/simon/Code/photogabble/website/node_modules/liquidjs/dist/liquid.node.cjs.js:4339:28)
[11ty] Copied 6 files / Wrote 0 files in 0.61 seconds (v2.0.0-canary.3)
Interesting. I think .md files are processed in liquidjs by default, per https://www.11ty.dev/docs/config/#default-template-engine-for-markdown-files.
You could try setting markdownTemplateEngine: false
in your config file; although I'm uncertain why that would have changed between 0.12.x and 1.0. I didn't see anything obvious in the 1.0 release notes.
I'll try fetching your repo and poking at it later today and see if I can give you a better response than "wrap the Vue code in a {% raw %}..{% endraw %}
block".
"Good" news: I can reproduce the above errors in v1, but no errors if I downgrade to 0.12. "Bad" news: I don't think it worked in 0.12 either, but the older (v6?) version of liquidjs failed a bit more silently.
<template>
<div id="app">
<h1>Ore Reserves: {{ ore }}</h1>
<br>
<button>Mine Ore</button>
</div>
</template>
But I build locally in v0.12 and view the http://localhost:8080/blog/tutorials/build-an-incremental-clicker-web-game-with-vuejs-part-one/#implementing-a-basic-game-mechanic page, I see the following:
<template>
<div id="app">
<h1>Ore Reserves: </h1>
<br>
<button>Mine Ore</button>
</div>
</template>
Note how liquid is trying to process the {{ ore }}
VueJS code, but then silently failing.
I think I managed to potentially fix 0.12 by setting templateEngineOverride: md
in the front matter for posts/2018-05-03-build-an-incremental-web-game-with-vue-js.md. I tried my suggestion of setting markdownTemplateEngine: false
globally in the .eleventy.js config file, but that seemed to break the permalinks because now liquidjs wasn't processing the posts/posts.json file's permalink
key which included some LiquidJS tags of "permalink": "blog/{{ categories | first }}/{{ title | slugify }}/index.html",
, which threw some confusing results like:
> Output conflict: multiple input files are writing to `_site/blog/{{ categories | first }}/{{ title | slugify }}/index.html`. Use distinct `permalink` values to resolve this conflict.
1. ./posts/2021-01-03-a-focus-on-birdsite-drama.md
2. ./posts/2009-06-10-mission-mainframe.md
...
49. ./posts/2021-01-01-if-dos-game-dev-is-a-rabbit-hole-then-call-me-alice.md
Unfortunately, it doesn't look like you can globally set the "templateEngineOverride": "md"
in your posts/posts.json file, and it might need to be added to each template individually.
Of course, take it all w/ a grain of salt. I just spot checked that one file, I didn't check each blog post and see if you were using liquidjs tags/filters elsewhere to see if I broke something unexpected.
But after seeing it [theoretically] fixed in 0.12, I upgraded to 1.0.0 and I didn't see build errors anymore, so that might have been the only template using liquidjs-looking-but-actually-vuejs variables. So you probably don't need to add it in all your posts/*.md files.
Finally, if you want my promised disappointing response of "Just use {% raw %}...{% endraw %}
, that seemed to work for me without needing to disable liquidjs processing of the markdown file in question. I had to change 3 code blocks, but it wasn't a huge deal, and looked something like this:
```html
{%- raw -%}
<template>
<div id="app">
<h1>Ore Reserves: {{ ore }}</h1>
<h1>Mines: {{ mines }}</h1>
<h1>Colonists: {{ colonists }}</h1>
<h1>Food: {{ food }}</h1>
<br>
<button v-on:click="mineOre">Mine Ore</button>
</div>
</template>
{% endraw -%}
And still rendered out some HTML like this:
```html
<template>
<div id="app">
<h1>Ore Reserves: {{ ore }}</h1>
<h1>Mines: {{ mines }}</h1>
<h1>Colonists: {{ colonists }}</h1>
<h1>Food: {{ food }}</h1>
<br>
<button v-on:click="mineOre">Mine Ore</button>
</div>
</template>
Versus the current, live version at https://photogabble.co.uk/blog/tutorials/build-an-incremental-clicker-web-game-with-vuejs-part-one/#adding-the-colonists
<template>
<div id="app">
<h1>Ore Reserves: </h1>
<h1>Mines: </h1>
<h1>Colonists: </h1>
<h1>Food: </h1>
<br>
<button v-on:click="mineOre">Mine Ore</button>
</div>
</template>
If you want to disable liquidjs processing of the markdown files, it looks like you CAN set markdownTemplateEngine: false
in your .eleventy.js config file, but then you'll need to rename your posts/posts.json file to posts/posts.11tydata.js and set the permalink
using JavaScript instead of liquidjs templating:
// posts/posts.11tydata.js
module.exports = {
// "permalink": "blog/{{ categories | first }}/{{ title | slugify }}/index.html",
featured: false,
layout: "layouts/post.njk",
eleventyComputed: {
permalink(data) {
return `blog/${ data.categories[0] }/${ this.slugify(data.title) }/`
}
}
};
@pdehaan Thank you for looking into this in so much detail, I hadn't noticed that the code examples weren't displaying correctly - this was likely broken in the previous static site generators I used.
I have a figure shortcode that I will eventually get round to refactoring posts to use in place of images therefore it seems your {%- raw -%}
solution is the way to go until this is possibly fixed in Eleventy.
until this is possibly fixed in Eleventy.
Honestly, I'm not sure this is a bug. Markdown files are preprocessed by LiquidJS (or Nunjucks or your engine of choice). But the fact that JSX or Vue or whatever uses a familiar and overlapping {{ ... }}
syntax is an unfortunate inconvenience which can lead to circumstances like this. Eleventy would have no idea if your template meant to use a LiquidJS variable or a Vue code snippet or something else. I'd argue that the more recent strict behavior of LiquidJS throwing errors instead of silently failing is a very good step in the right direction since it can highlight these issues.
I'd argue that the solution is to use {% raw %}
(why the filter exists), or else disable Markdown preprocessing if it isn't a feature you want/need.
Honestly, I'm not sure this is a bug.
I heartily agree. I think you're right that this is an unfortunate edge case due to the overlapping syntax.
While I can't say this is a "common pitfall" I certainly consider it warrants a small section in https://www.11ty.dev/docs/pitfalls/
While I can't say this is a "common pitfall" I certainly consider it warrants a small section in 11ty.dev/docs/pitfalls
OOooohhh, excellent suggestion! PRs welcome over in the 11ty/11ty-website repo.
As mentioned in https://github.com/11ty/eleventy/issues/2273#issuecomment-1065837671 I confirm templateEngineOverride
settings is only working if added from the content file directly... not as a directory data file...
This is a really big gotcha that prevented me from updating for a while, agree with adding it to the common pitfalls section
As these are contained in markdown code blocks is there a way to get the LiquidJS templating engine to ignore {{}}
when within a "code block" (maybe even as a setting)?
(I wouldn't know where to start with this but am willing to put some time into it if someone can point me in the right direction)
have same issue
Please use {% raw %}
if you want Liquid or Nunjucks to ignore a block of code! Otherwise, you do have full control over the preprocessing language here: https://www.11ty.dev/docs/languages/#overriding-the-template-language
Just in case somebody comes back to this, my solution was to pass markdown-it
as the md
engine in the config.
I did it originally because I need some custom stuff around link parsing, but it ended up preventing this issue. Not sure what's going on behind the scenes, I am guessing liquid.js let's its markdown engine to parse thing for it and delegate to liquid rendering when encounter things like that, but overriding the markdown engine undoes this 🤷
@jeremenichelli I think that is because the default parser config for md
files is markdown|liquid
. This means 11ty will parse the file first as a markdown document and then as a liquid template nessesitating the use of {% raw %}
.
Describe the bug I have a Vue.js template example within a markdown code block, as seen here in my blogs source and in the below screenshot:
In upgrading to eleventy 1.0 I now get a parse error which didn't occur in previous versions:
Having thrown a debugger on the process it looks as though the markdown isn't being parsed and therefore the code examples aren't going via
@11ty/eleventy-plugin-syntaxhighlight
before the file's content is parsed by the liquid template parser.As you can see here, its attempting to tokenise the unparsed markdown; the vue template syntax is similar to liquid and so it's attempting to tokenise it when it shouldn't
To Reproduce Steps to reproduce the behavior:
npm run build
Is there something I am missing in my configuration that needs to tell 11ty that md files need to be parsed by the markdown lib and prism before being passed to the liquid template parser?
This wasn't an issue in
0.12.1
, deleting the problematic markdown file results in the website building correctly therefore I assume the error is limited to the scope highlighted in my screenshots above.