Skip to content

[BUG] [Formatter] Specific mixture of quotes and escaped quotes (e.g. in a json string in an html attribute) breaks the html #1015

@oliverhaas

Description

@oliverhaas

System Info

  • OS: Ubuntu 24.04
  • Python Version: 3.12.3
  • djLint Version: 1.36.1
  • template language: django

Issue

Some combination of html attributes and escaped quotes will break the html during djlint's indenting step.

As a note: I hate using json strings in html attributes like this, but it's valid syntax and some libraries just require this.

Also, it would be nice to have a feature to actually not format inside html attributes at all, like e.g. this issue #723 mentions, or format json properly.

Example

Using max_attribute_length=1 and formatting

<option data-json='{ "icon": "<img class=\"ss\">" }' {% if True %}selected{% endif %}>

will result in

<option data-json='{ "icon": "<img class
    "
    ss
    ">" }'
    {% if True %}selected{% endif %}
     >

(note that this removes some characters!)
instead of

<option data-json='{ "icon": "<img class=\"ss\">" }' 
    {% if True %}selected{% endif %}
    >

The underlying issue is that escaped quotes are not properly ignored, so djlint doesn't match all the html attributes of a tag if it intends to do so.

There is actually another "hidden" issue that once I made djlint respect escaped quotes, I saw that the quotes in template tags are not cleanly handled in the matching of the html attributes. Since this only shows if I fixed the above, I just fixed both in one go (see the PR linked below).

How To Reproduce

Here is a test, see my PR I will link create in the next minutes.

    pytest.param(
        (
            "<option data-json='{ \"icon\": \"<img class=\\\"ss\\\">\" }' {% if True %}selected{% endif %}>"
        ),
        (
            "<option data-json='{ \"icon\": \"<img class=\\\"ss\\\">\" }'\n"
            "    {% if True %}selected{% endif %}\n"
            "    >\n"
        ),
        ({"max_attribute_length": 1}),
        id="with_html_tag_in_attribute_escaped_and_template_tag",
    )

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions