rtts / djhtml

Django/Jinja template indenter
GNU General Public License v3.0
582 stars 32 forks source link

HTML attribute (alpinejs) with inline javascript not formatted properly #103

Closed krims0n32 closed 1 year ago

krims0n32 commented 1 year ago

First of, thanks for your work. This formatter saves me a lot of time.

I have one issue with it, I use django with alpinejs extensively, using x-data and x-init and the likes. Consider this example:

image

Looks fine on one line, however when I want something like this:

image

djhtml formats it as:

image

Is this fixable at all?

oselz commented 1 year ago

A workaround I found is using static formatting:

<div x-data={# fmt:off #}"
        { ... }
"{# fmt:on #}>
</div>

It would be handy if there were a fmt:<mode> option to force the correct mode in special cases.

spookylukey commented 1 year ago

djhtml I think should not touch whitespace within a HTML attribute by default. It happens that in many cases, changing whitespace has no effect on behaviour, but for things like data- attributes especially, changing whitespace could easily change behaviour, because they can be used for anything, and browser HTML parsers preserve whitespace within attributes exactly (tested Firefox).

My particular motivation is hyperscript, BTW.

JaapJoris commented 1 year ago

DjHTML was specifically created to indent HTML that contains Django template tags. The first example in the README is:

<blockquote cite="Guido Van Rossum"
            style="font-style: italic;
                   {% if dark_mode %}
                       background: black;
                   {% endif %}
                  ">
    Don't you hate code that's not properly indented?
</blockquote>

Of course, you can use an infinite number of syntaxeis inside HTML attribute values, which are all currently unsupported. DjHTML shouldn't dictate which languages you use, although I personally think that the trend of embedding all kinds of logic and layout rules inside HTML files is a bad idea.

The {# fmt:<mode> #} option seems like a good idea though, so I experimented a bit with it. The problem is that it's hard to "exit" this mode again without running into inconsistencies. What if you use the tag multiple times? What should {# fmt:on #} do exactly?

I'm not spending any more time on this, but feel free to submit a PR if you think this can be improved :hug

oselz commented 1 year ago

The {# fmt:<mode> #} option seems like a good idea though, so I experimented a bit with it. The problem is that it's hard to "exit" this mode again without running into inconsistencies. What if you use the tag multiple times? What should {# fmt:on #} do exactly?

@JaapJoris Would it work to set some basic ground rules along with a basic syntax change, ie:

For backwards compatibility fmt:on would need an alias back to fmt:auto, and ftm:off to fmt:none (although I'm unsure if fmt:none is actually required, fmt:off may be adequate already).

If you think this is doable I can probably find some time to work on implementing it.