lumeland / lume

🔥 Static site generator for Deno 🦕
https://lume.land
MIT License
1.88k stars 86 forks source link

nunjucks include in for loop breaks build #522

Closed allanberry closed 10 months ago

allanberry commented 10 months ago

Version

v1.19.3

Platform

Macintosh

What steps will reproduce the bug?

Hi there. I can't build my site when I have includes (SVG) within a Nunjucks for loop. The problem seems to be when the include is within certain Nunjucks tags.

For example, this builds OK

<!DOCTYPE html>
<html>
<head></head>
  <body>
    {% include "test.svg" %}

    {% for item in ["a", "b", "c"] %}
      <h1>{{item}}</h1>
    {% endfor %}
  </body>
</html>

But this does not:

<!DOCTYPE html>
<html>
<head></head>
  <body>
    {% for item in ["a", "b", "c"] %}
      {% include "test.svg" %}
      <h1>{{item}}</h1>
    {% endfor %}
  </body>
</html>

if tags also are broken:

{% if true %}
  {% include "test.svg" %}
  <h1>True</h1>
{% endif %}

but block tags seem to work OK:

{% block test %}
  {% include "test.svg" %}
  <h1>Test</h1>
{% endblock %}

How often does it reproduce? Is there a required condition?

This happens each time I try and build my site with deno task build.

It also happens when using deno task serve, but it resolves itself after the first build: if you edit the Nunjucks file, when Lume re-renders the HTML, the include is rendered OK. It will continue to render correctly until you stop the server and run either deno task build or deno task serve again.

What is the expected behavior?

The SVG should render.

What do you see instead?

The SVG silently fails to render, and the rendered HTML gets borked.

Additional information

It seems to me there's some sort of (async?) race condition, where the initial build can't find the include, but on subsequent renderings it already has the data, so it renders. Perhaps this is due to asynchronous template rendering.

Nunjucks has an asyncEach tag for async for rendering, but I tried it and it didn't work.

Thanks very much, great software. Cheers.

oscarotero commented 10 months ago

Nunjucks is primary a sync template engine, but Lume needs to load the files in async. This is why in Lume 2 the default template engine will be Vento, that works much better with async code.

For Nunjucks, the workaround is using asyncEach / endeach and ifasync / endif. If that don't work for you, make sure you don't have anything wrong because it always worked fine to me. This is an example: https://github.com/lumeland/theme-simple-blog/blob/1211528b0f4ea1364d1856e6531a53898a17e074/src/_includes/templates/post-list.njk#L2

allanberry commented 10 months ago

Thanks @oscarotero! I appreciate your attention. I tried asyncEach / endeach and it worked OK this time, I guess I did something wrong before. :/

Looking forward to Vento!