zackad / prettier-plugin-twig

Code formatting plugin for Prettier to handle Twig templates
Apache License 2.0
49 stars 6 forks source link

Parser doesn't allow <{{ tag }}> #60

Open jraller opened 2 months ago

jraller commented 2 months ago

In a twig component I have:

<{{ tag }} {{ attributes.defaults({
    class: 'px-4 py-2 border border-transparent text-sm font-medium rounded-md '~this.variantClasses,
}) }}>
    {% block content %}{% endblock %}
</{{ tag }}>

Which prettier-plugin-twig responds to with:

>templates/components/Button.html.twig
[error] templates/components/Button.html.twig: Error: ERROR: Expected element start
[error] > 1 | <{{ tag }} {{ attributes.defaults({
[error]     |  ^
[error]   2 |     class: 'px-4 py-2 border border-transparent text-sm font-medium rounded-md '~this.variantClasses,
[error]   3 | }) }}>
[error]   4 |     {% block content %}{% endblock %}
[error]
[error] Expected an element to start
[error]     at TokenStream.error (file:///C:/Users/Jason/AppData/Roaming/npm/node_modules/@zackad/prettier-plugin-twig/src/melody/melody-parser/TokenStream.js:129:24)
[error]     at Parser.error (file:///C:/Users/Jason/AppData/Roaming/npm/node_modules/@zackad/prettier-plugin-twig/src/melody/melody-parser/Parser.js:452:21)
[error]     at Parser.matchElement (file:///C:/Users/Jason/AppData/Roaming/npm/node_modules/@zackad/prettier-plugin-twig/src/melody/melody-parser/Parser.js:319:18)
[error]     at Parser.parse (file:///C:/Users/Jason/AppData/Roaming/npm/node_modules/@zackad/prettier-plugin-twig/src/melody/melody-parser/Parser.js:207:32)
[error]     at Object.parse (file:///C:/Users/Jason/AppData/Roaming/npm/node_modules/@zackad/prettier-plugin-twig/src/parser.js:82:24)     
[error]     at parse4 (file:///C:/Users/Jason/AppData/Roaming/npm/node_modules/prettier/index.mjs:20685:24)
[error]     at async coreFormat (file:///C:/Users/Jason/AppData/Roaming/npm/node_modules/prettier/index.mjs:21146:7)
[error]     at async formatWithCursor (file:///C:/Users/Jason/AppData/Roaming/npm/node_modules/prettier/index.mjs:21348:14)
[error]     at async formatFiles (file:///C:/Users/Jason/AppData/Roaming/npm/node_modules/prettier/internal/cli.mjs:3468:18)
[error]     at async main (file:///C:/Users/Jason/AppData/Roaming/npm/node_modules/prettier/internal/cli.mjs:3876:5)

I've used symfony console lint:twig templates which doesn't report any lint issues with the twig syntax the way I'm using it. Can the parser be set to allow a tag to start with {{ variable }}, in my case <{{ tag }}?

The functional reason for this is that this twig component defaults to <button but it is possible to pass it a tag value in which case you could cause it to render as <a instead.

jraller commented 2 months ago

It looks like this dates back to https://github.com/trivago/prettier-plugin-twig-melody/issues/53

renestalder commented 2 months ago

You should be able to work around that by constructing the whole start and end tags with one big string you then render with |raw. That's what I did in the past. It isn't beautiful. It isn't "handy" (because you don't get nesting), but it works for those edge cases.

example:

{% set start_tag = "<#{tag} #{attributes.defaults....}>" %}

{{ start_tag|raw }}