uncenter / eleventy-plugin-icons

✨ A plugin for Eleventy to add and transform icons from any icon set.
https://www.npmjs.com/package/eleventy-plugin-icons
MIT License
11 stars 0 forks source link

Asynchronous shortcode breaks macros #118

Open Lamecarlate opened 2 hours ago

Lamecarlate commented 2 hours ago

Hello,

I wanted to add an icon in a macro, and it seems to fail silently. No error in the console, and the html is truncated just before the icon, the macro is returned and displayed as is. In my case, breaking the html, since there is no closing tag…

My macro:

{%- macro warning(content) -%}
<div class="warning-block">    
    {% icon "triangle-alert" %}

    {{ content }}
</div>
{%- endmacro -%}

This outputs:

<div class="warning-block">

and stops. The rest of the template, after the macro, is displayed.

Note: I installed the Lucide Icons Plugin, to test if the problem was only the plugin, or shortcodes in macros, or any other thing. It works with the {% lucide "triangle-alert" %} provided by this plugin.

Do you need more information, what can I do to help?

Thanks in advance.

uncenter commented 2 hours ago

Hi, unfortunately this is due to a limitation of the templating language itself: https://mozilla.github.io/nunjucks/templating.html#macro.

Important note: If you are using the asynchronous API, please be aware that you cannot do anything asynchronous inside macros. This is because macros are called like normal functions. In the future we may have a way to call a function asynchronously. If you do this now, the behavior is undefined.

Since the icon shortcode is asynchronous, you cannot use it in macros.

uncenter commented 2 hours ago

Though, I could look into providing a synchronous version of the shortcode...

Lamecarlate commented 1 hour ago

Oh. I did not realise it was asynchronous… So, I guess the Lucide shortcut is synchronous (the Lucide plugin is here).

Is it possible to override your Icons plugin to make it synchronous? Oh, I see your second comment now… Can I help? I'm new to Eleventy but not bad in JS, I could try to understand.

uncenter commented 1 hour ago

The difference is that the Lucide plugin statically imports the icon data, whereas this plugin uses the filesystem as the source - meaning we read files for the SVG data, asynchronously. I think I should look into providing a more customizable approach to "sources" - maybe I provide a FileSystemSource class and a StaticSource for reading from the filesystem vs retrieving from an object? Some things I'll have to think about here... if you have any other/better ideas feel free to chime in 😅