HTML Template Linter and Formatter. Use with Django, Jinja, Nunjucks and Handlebars templates.

Overview

djLint Logo

Find common formatting issues and reformat HTML templates.

Django · Jinja · Nunjucks · Handlebars · Mustache · GoLang

Ps, --check it out on other templates as well!

codecov test Codacy Badge Maintainability Downloadschat PyPI

Documentation

Read the documentation

Installation and Usage

djLint can be installed with pip install djlint, and is easy to run:

" | djlint - ">
# to lint a directory
djlint /path

# to lint a directory with custom extension
djlint /path -e html.dj

# to check formatting on a file
djlint /path/file.html.j2 --check

# to reformt a directory without printing the file diff
djlint /path --reformat --quiet

# using stdin
echo "
   
"
| djlint -

Show your format

Add a badge to your projects readme.md:

[![Code style: djlint](https://img.shields.io/badge/html%20style-djlint-blue.svg)](https://github.com/Riverside-Healthcare/djlint)

Add a badge to your readme.rst:

.. image:: https://img.shields.io/badge/html%20style-djlint-blue.svg
   :target: https://github.com/Riverside-Healthcare/djlint

Looks like this:

djLint

Contributing

Send a pr with a new feature, or checkout the issue list and help where you can.

Comments
  • [BUG] [Formatter] IndexError: list index out of range

    [BUG] [Formatter] IndexError: list index out of range

    Thanks for useful tool!

    I understand that formatting is beta feature.

    Just a bug reporting.

    System Info

    • OS: e.g. ubuntu 20.04
    • Python Version 3.8
    • djLint Version (1.7.0)
    • template language: e.g. twig

    Issue

    --check and --reformat follows to Phyton exception in some twig files. But --lint passed ok these files.

    djlint view/admin/driver_form.html.twig --check --profile=nunjucks
    
    concurrent.futures.process._RemoteTraceback:                                                                                                                                                          
    """
    Traceback (most recent call last):
      File "/usr/lib/python3.8/concurrent/futures/process.py", line 239, in _process_worker
        r = call_item.fn(*call_item.args, **call_item.kwargs)
      File "/home/vladp/.local/lib/python3.8/site-packages/djlint/__init__.py", line 259, in process
        output["format_message"] = reformat_file(
    [problem_page.html.twig.txt](https://github.com/Riverside-Healthcare/djLint/files/9075293/problem_page.html.twig.txt)
    config, this_file)
      File "/home/vladp/.local/lib/python3.8/site-packages/djlint/reformat.py", line 23, in reformat_file
        indented = indent_html(condensed, config)
      File "/home/vladp/.local/lib/python3.8/site-packages/djlint/formatter/indent.py", line 183, in indent_html
        tmp = re.sub(
      File "/home/vladp/.local/lib/python3.8/site-packages/regex/regex.py", line 278, in sub
        return pat.sub(repl, string, count, pos, endpos, concurrent, timeout)
      File "/home/vladp/.local/lib/python3.8/site-packages/djlint/formatter/attributes.py", line 271, in format_attributes
        attributes = format_template_tags(config, attributes)
      File "/home/vladp/.local/lib/python3.8/site-packages/djlint/formatter/attributes.py", line 218, in format_template_tags
        attributes = add_indentation(config, attributes)
      File "/home/vladp/.local/lib/python3.8/site-packages/djlint/formatter/attributes.py", line 44, in add_indentation
        start_test = (
    IndexError: list index out of range
    """
    
    The above exception was the direct cause of the following exception:
    
    Traceback (most recent call last):
      File "/home/vladp/.local/bin/djlint", line 8, in <module>
        sys.exit(main())
      File "/home/vladp/.local/lib/python3.8/site-packages/click/core.py", line 1130, in __call__
        return self.main(*args, **kwargs)
      File "/home/vladp/.local/lib/python3.8/site-packages/click/core.py", line 1055, in main
        rv = self.invoke(ctx)
      File "/home/vladp/.local/lib/python3.8/site-packages/click/core.py", line 1404, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "/home/vladp/.local/lib/python3.8/site-packages/click/core.py", line 760, in invoke
        return __callback(*args, **kwargs)
      File "/usr/lib/python3.8/contextlib.py", line 75, in inner
        return func(*args, **kwds)
      File "/home/vladp/.local/lib/python3.8/site-packages/djlint/__init__.py", line 216, in main
        file_errors.append(future.result())
      File "/usr/lib/python3.8/concurrent/futures/_base.py", line 437, in result
        return self.__get_result()
      File "/usr/lib/python3.8/concurrent/futures/_base.py", line 389, in __get_result
        raise self._exception
    IndexError: list index out of range
    

    How To Reproduce

    problem file is attached problem_page.html.twig.txt

    :microbe: bug :sponge: formatter released 
    opened by palansher 30
  • [Question] Is there any plan to Linter integration for Editor/IDE?

    [Question] Is there any plan to Linter integration for Editor/IDE?

    Thanks for this tool. Do you have any plans for djlint as a linter to run from the Editor or IDE?

    Also, in that case, it might be good to have stdin support as well.

    Example:

    cat polls/templates/index.html | djlint --check  -
    
    :steam_locomotive: enhancement :question: question released 
    opened by yaegassy 19
  • Django: djLint changes {% blocktranslate %} if not using trimmed strings

    Django: djLint changes {% blocktranslate %} if not using trimmed strings

    This may or may not be a problem. I think I like the fact that {% blocktranslate %} tags are formatted as well, but without trimmed the original string changes each time the template is reindented and that's a bit bad.

    Maybe this is something to add, for example in a new recommendations section.

    need information released 
    opened by matthiask 17
  • Unstable formatter adds extra indentation on every execution

    Unstable formatter adds extra indentation on every execution

    The following sample was tested with v1.9.4 and 1.12.1 - both exhibit the same behaviour (project is running 1.9.4, and 1.12.1 is latest version at the time this issue is being raised)

    Issue #166 appears to be cover the same issue, but that is reported as fixed back in v1.0

    I have been through the documentation, and there appears to be no way to disable the DJLint formatter (the 'djlint:off' comment appears to only disable linting, not formatting?).

    The issue:

    I'm embedding some Jinja2 code inside a script block, and unfortunately the embedded Javascript formatter is butchering the code badly... so I've used the 'beautify preserve:start/end' pragmas to disable the javascript formatting... which works.

    However, when I disable the javascript formatting, the djlint formatter starts adding extra indentation on every execution.

    Sample code (entire contents of 'formatter_test.html.j2' file):

    {% macro generate_clear_script(ids) %}
        <script type="text/javascript">
        /* beautify preserve:start */
            function reset_adv_search_form() {
                {%- for id in ids %}
                $('#{{ id }}').val([]);
                $('#{{ id }} option').prop("selected", false);
                {%- endfor %}
                $('#from_date').val('');
            }
        /* beautify preserve:end */
        </script>
    {% endmacro %}
    

    After the first iteration:

    {% macro generate_clear_script(ids) %}
        <script type="text/javascript">
            /* beautify preserve:start */
                    function reset_adv_search_form() {
                        {%- for id in ids %}
                        $('#{{ id }}').val([]);
                        $('#{{ id }} option').prop("selected", false);
                        {%- endfor %}
                        $('#from_date').val('');
                    }
                /* beautify preserve:end */
        </script>
    {% endmacro %}
    

    After the second iteration:

    {% macro generate_clear_script(ids) %}
        <script type="text/javascript">
            /* beautify preserve:start */
                            function reset_adv_search_form() {
                                {%- for id in ids %}
                                $('#{{ id }}').val([]);
                                $('#{{ id }} option').prop("selected", false);
                                {%- endfor %}
                                $('#from_date').val('');
                            }
                        /* beautify preserve:end */
        </script>
    {% endmacro %}
    

    And third iteration:

    {% macro generate_clear_script(ids) %}
        <script type="text/javascript">
            /* beautify preserve:start */
                                    function reset_adv_search_form() {
                                        {%- for id in ids %}
                                        $('#{{ id }}').val([]);
                                        $('#{{ id }} option').prop("selected", false);
                                        {%- endfor %}
                                        $('#from_date').val('');
                                    }
                                /* beautify preserve:end */
        </script>
    {% endmacro %}
    

    I've tested this behaviour up to 15 iterations, at which point I stopped. Every iteration, the code ends up further and further indented.

    Note: Also tested the same code using 'djlint:off/on' comments - had no impact (same indenting behaviour observed). test code with djlint:off/on comments, for reference:

    {% macro generate_clear_script(ids) %}
        {# djlint:off #}
        <script type="text/javascript">
        /* beautify preserve:start */
            function reset_adv_search_form() {
                {%- for id in ids %}
                $('#{{ id }}').val([]);
                $('#{{ id }} option').prop("selected", false);
                {%- endfor %}
                $('#from_date').val('');
            }
        /* beautify preserve:end */
        </script>
        {# djlint:on #}
    {% endmacro %}
    

    Current workaround: I've explicitly added the impacted file to the exclusion list in the .djlintrc file, but this is sub-optimal, as it means that none of the code in the file is validated as part of the CI/CD pipeline.

    released 
    opened by logicalChimp 15
  • [BUG] [Linter] Can't ignore H006

    [BUG] [Linter] Can't ignore H006

    System Info

    • OS: Archlinux
    • Python Version (3.10.6)
    • djLint Version (1.9.4)
    • template language: django

    Issue

    I'm not able to ignore H006 ('img tag should have height and width attributes.').

    How To Reproduce

    On pre-commit config use args: ["-i H006"] or use one of the methods provided on documentation

    :microbe: bug :mag: linter released 
    opened by aleprovencio 15
  • [BUG] [Linter] Error on empty html elements

    [BUG] [Linter] Error on empty html elements

    System Info

    • OS: Windows 10 Pro, Windows Server 2019 Standard
    • Python Version: 3.10.4, 3.8.8
    • djLint Version: 1.3.0
    • template language: html

    Issue

    Error on many html elements with no content, such as <br>, <p></p>, <h1></h1>, etc..

    Traceback:

    Traceback (most recent call last):
      File "C:\Python310\lib\runpy.py", line 196, in _run_module_as_main
        return _run_code(code, main_globals, None,
      File "C:\Python310\lib\runpy.py", line 86, in _run_code
        exec(code, run_globals)
      File "C:\Users\Kyanite\.virtualenvs\temp-Bh3UMC1v\Scripts\djlint.exe\__main__.py", line 7, in <module>
      File "c:\users\kyanite\.virtualenvs\temp-bh3umc1v\lib\site-packages\click\core.py", line 1130, in __call__
        return self.main(*args, **kwargs)
      File "c:\users\kyanite\.virtualenvs\temp-bh3umc1v\lib\site-packages\click\core.py", line 1055, in main
        rv = self.invoke(ctx)
      File "c:\users\kyanite\.virtualenvs\temp-bh3umc1v\lib\site-packages\click\core.py", line 1404, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "c:\users\kyanite\.virtualenvs\temp-bh3umc1v\lib\site-packages\click\core.py", line 760, in invoke
        return __callback(*args, **kwargs)
      File "C:\Python310\lib\contextlib.py", line 79, in inner
        return func(*args, **kwds)
      File "c:\users\kyanite\.virtualenvs\temp-bh3umc1v\lib\site-packages\djlint\__init__.py", line 251, in main
        if bool(print_output(config, file_errors, len(file_list))) and config.warn is False:
      File "c:\users\kyanite\.virtualenvs\temp-bh3umc1v\lib\site-packages\djlint\output.py", line 34, in print_output
        lint_error_count += build_output(error["lint_message"], config)
      File "c:\users\kyanite\.virtualenvs\temp-bh3umc1v\lib\site-packages\djlint\output.py", line 91, in build_output
        echo(
      File "c:\users\kyanite\.virtualenvs\temp-bh3umc1v\lib\site-packages\click\utils.py", line 299, in echo
        file.write(out)  # type: ignore
      File "c:\users\kyanite\.virtualenvs\temp-bh3umc1v\lib\site-packages\colorama\ansitowin32.py", line 47, in write
        self.__convertor.write(text)
      File "c:\users\kyanite\.virtualenvs\temp-bh3umc1v\lib\site-packages\colorama\ansitowin32.py", line 170, in write
        self.write_and_convert(text)
      File "c:\users\kyanite\.virtualenvs\temp-bh3umc1v\lib\site-packages\colorama\ansitowin32.py", line 198, in write_and_convert
        self.write_plain_text(text, cursor, len(text))
      File "c:\users\kyanite\.virtualenvs\temp-bh3umc1v\lib\site-packages\colorama\ansitowin32.py", line 203, in write_plain_text
        self.wrapped.write(text[start:end])
      File "C:\Python310\lib\encodings\cp1252.py", line 19, in encode
        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
    UnicodeEncodeError: 'charmap' codec can't encode characters in position 39-117: character maps to <undefined>
    

    How To Reproduce

    A couple of examples where the error occurs:

    1. <p></p> error_example_1.txt
    2. <br> error_example_2.txt

    A couple of examples where the error does not occur:

    1. <p>a</p> success_example_1.txt
    2. <br/> success_example_2.txt
    :microbe: bug :mag: linter released 
    opened by lhuhmann 15
  • [BUG] [Formatter] <a> tags cause incorrect formatting

    [BUG] [Formatter] tags cause incorrect formatting

    System Info

    • OS: ubuntu 21.10
    • Python Version 3.9.7
    • djLint Version 0.7.4
    • template language: e.g. Jinja2

    Issue

    When reformatting a ".jinja2" html document, the indentation breaks after an <a> tag. I've observed this multiple times now.

    The code looks like this:

    How To Reproduce

    <a class="btn btn-primary"
     href="{{ url("url") }}"
     title="{{ _("Title") }}">
      <span class="iconify" data-icon="mdi:camera"></span> {{ _("Analyse your image!") }}</a>
    <div class="popup beautiful-popup" id="analysis-options">
      <h4>{{ _("Options") }}</h4> [...]
    </div>
    

    After reformatting it in VSCode using the djLint plugin, I obtain the following:

    <a class="btn btn-primary"
       href="{{ url("url") }}"
       title="{{ _("Title") }}">
      <span class="iconify" data-icon="mdi:camera"></span> {{ _("Analyse your image!") }}</a>
      <div class="popup beautiful-popup" id="analysis-options">
        <h4>{{ _("Options") }}</h4> [...]
      </div>
    

    So the <div>-Tag is incorrectly indented by one extra indentation level. And so is the rest of the document after that point!

    However, if I manually put the code in the following way (i.e. insert line breaks):

    <a class="btn btn-primary"
       href="{{ url("url") }}"
       title="{{ _("Title") }}">
        <span class="iconify" data-icon="mdi:camera"></span>
        {{ _("Analyse your image!") }}
        </a>
    <div class="popup beautiful-popup" id="analysis-options">
      <h4>{{ _("Options") }}</h4> [...]
    </div>
    

    then it will be correctly indented like so:

    <a class="btn btn-primary"
       href="{{ url("url") }}"
       title="{{ _("Title") }}">
      <span class="iconify" data-icon="mdi:camera"></span>
      {{ _("Analyse your image!") }}
    </a>
    <div class="popup beautiful-popup" id="analysis-options">
      <h4>{{ _("Options") }}</h4> [...]
    </div>
    

    I believe it is not related to the <a> tag but to some peculiar property with the {{}} tags or similar.

    The formatting should not be dependent on formatting in the initial document, as long as everything is valid xml, I think at least.

    :microbe: bug :sponge: formatter :toolbox: 2.0 
    opened by MrP01 13
  • Add require_pragma option

    Add require_pragma option

    This PR adds a configuration option for requiring files to have a pragma comment at the beginning of the file before reformatting the file. This behaviour is useful for a slow adoption of the tool instead of requiring the whole code base to be converted at once. It is inspired by the behaviour of prettier.

    Pull Request Check List

    Resolves: #issue-number-here

    • [ x ] Added tests for changed code.
    • [ x ] Updated documentation for changed code.
    released 
    opened by hrjakobsen 13
  • [FEATURE] Prevent text identation

    [FEATURE] Prevent text identation

    Feature Request

    The feature is to provide an option to prevent text being completely aligned when formatted. For example if I have this text:

    interface Ethernet1/2
      description // Connected to leaf-2
      no switchport
      ip address 10.1.2.1/30
      ip router ospf 1 area 0.0.0.0
      no shutdown
    
    interface Ethernet1/3
      description // Connected to leaf-3
      no switchport
      ip address 10.1.3.1/30
      ip router ospf 1 area 0.0.0.0
      no shutdown
    

    And I run the following I get all text aligned.

    ❯ djlint 1234  --profile=jinja --check
    
    Checking 1/1 files ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 00:01
    
    
    home/rick/1234
    ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    @@ -1,13 +1,12 @@
    
     interface Ethernet1/2
    -  description // Connected to leaf-2
    -  no switchport
    -  ip address 10.1.2.1/30
    -  ip router ospf 1 area 0.0.0.0
    -  no shutdown
    -
    +description // Connected to leaf-2
    +no switchport
    +ip address 10.1.2.1/30
    +ip router ospf 1 area 0.0.0.0
    +no shutdown
     interface Ethernet1/3
    -  description // Connected to leaf-3
    -  no switchport
    -  ip address 10.1.3.1/30
    -  ip router ospf 1 area 0.0.0.0
    -  no shutdown
    +description // Connected to leaf-3
    +no switchport
    +ip address 10.1.3.1/30
    +ip router ospf 1 area 0.0.0.0
    +no shutdown
    
    1 file would be updated.
    

    Ideally it would be good to have the option where the text is not aligned.

    Thanks,

    released 
    opened by rickdonato 10
  • Specify acceptable entities

    Specify acceptable entities

    Pull Request Check List

    Resolves: https://github.com/Riverside-Healthcare/djLint/issues/156

    • [x] Added tests for changed code.
    • [ ] Updated documentation for changed code.
    released 
    opened by jayvdb 10
  • [BUG] [Formatter]  endtag and closing tag on same line are adding whitespace

    [BUG] [Formatter] endtag and closing tag on same line are adding whitespace

    System Info

    • OS: Ubuntu 21.10
    • Python Version: 3.9.7
    • djLint Version: 0.7.1
    • template language: Django

    Issue

    Sometimes I'm seeing the formatter incorrect indent when two closing tags are right next to each other as shown in this diff:

    {% extends "base.html" %}
    -
     {% load i18n %}
     {% load account %}
    -
    -{% block head_title %}{% trans "Sign In" %}{% endblock %}
    -
    -{% block content %}
    -
    -<h1>{% trans "Sign In" %}</h1>
    -
    -<p>{% blocktrans %}If you have not created an account yet, then please
    -<a href="{{ signup_url }}">sign up</a> first.{% endblocktrans %}</p>
    -
    -<form class="login" method="POST" action="{% url 'account_login' %}">
    -  {% csrf_token %}
    -  {{ form.as_p }}
    -  {% if redirect_field_value %}
    -  <input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
    -  {% endif %}
    -  <a class="button secondaryAction" href="{% url 'account_reset_password' %}">{% trans "Forgot Password?" %}</a>
    -  <button class="primaryAction" type="submit">{% trans "Sign In" %}</button>
    -</form>
    -
    +{% block head_title %}
    +    {% trans "Sign In" %}
     {% endblock %}
    +{% block content %}
    +    <h1>{% trans "Sign In" %}</h1>
    +    <p>
    +        {% blocktrans %}If you have not created an account yet, then please
    +            <a href="{{ signup_url }}">sign up</a> first.{% endblocktrans %}
    +        </p>
    +        <form class="login" method="POST" action="{% url 'account_login' %}">
    +            {% csrf_token %}
    +            {{ form.as_p }}
    +            {% if redirect_field_value %}
    +                <input type="hidden"
    +                       name="{{ redirect_field_name }}"
    +                       value="{{ redirect_field_value }}"/>
    +            {% endif %}
    +            <a class="button secondaryAction"
    +               href="{% url 'account_reset_password' %}">{% trans "Forgot Password?" %}</a>
    +            <button class="primaryAction" type="submit">{% trans "Sign In" %}</button>
    +        </form>
    +    {% endblock %}
    

    You can see the </p> and everything after, right after the endblocktrans, should be dedented one level

    How To Reproduce

    I see it every time I run the formatter against that specific template

    :microbe: bug :sponge: formatter 
    opened by gone 9
  • [BUG] [Formatter] Reformat on Windows causes files to be changed to CRLF line endings

    [BUG] [Formatter] Reformat on Windows causes files to be changed to CRLF line endings

    System Info

    • OS: Windows 10 (21H2)
    • Python Version (python --version): 3.10.8
    • djLint Version (djlint --version): 1.19.9
    • template language: nunjucks

    Issue

    When running djlint --reformat ., djLint notes that no files were updated, but on Windows all "formatted" files are changed from LF line endings to CRLF. When the same files are checked/linted (djlint --check --lint .), djLint finds no errors and notes no files would be updated.

    When running against the same files on Linux (I tested in a python:alpine container), the line endings are not changed.

    Normally I use VSCode with both the djLint and EditorConfig extensions configured for formatting on save, and in that case it appears the EditorConfig settings are applied last (so in my case the line endings are not changed since all are set to LF).

    For example:

    PS C:\test> djlint --check --lint .
    
    Checking and Linting 5/5 files »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»» 00:00     
    
    
    0 files would be updated.
    Linted 5 files, found 0 errors.
    
    PS C:\test> djlint --reformat .
    
    Reformatting 5/5 files »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»» 00:00     
    
    
    0 files were updated.
    

    But the 5 files were all changed from LF to CRLF.

    How To Reproduce

    Create a nunjucks file with LF line endings and run djlint --reformat ..

    Recommendations

    • I propose that ideally djLint wouldn't change the line endings of a file.
    • If djLint does intentionally change the line endings when reformatting:
      • The console output should reflect that changes were made
      • It would be helpful to have a configuration setting to either control the line endings or disable
      • The behavior should be documented
    :microbe: bug :sponge: formatter 
    opened by aarongoldenthal 3
  • [BUG] [Linter] Linter fails with D018 on data-action=

    [BUG] [Linter] Linter fails with D018 on data-action="xxx"

    System Info

    • OS: Mac OSX Ventura 13.1
    • Python Version (python --version): Python 3.11.1
    • djLint Version (djlint --version): djlint, version 1.19.10
    • template language: e.g. mustache: django

    Issue

    The Linter complains with an error D018 1:0 (Django) Internal links should use the {% url ... %} pattern. if a form has a data-action attribute.

    How To Reproduce

    Lint the following file:

    <form action="{% url 'something' %}" data-action="xxx"></form>
    

    Error: D018 1:0 (Django) Internal links should use the {% url ... %} pattern.

    This is an invalid error, the data-action parameter has nothing to do with URLs but is used in some web frameworks.

    This is happening due to the following error in the Regexp that checks for the D018 rule. The rule is currently the following: <form\s+?[^>]*?(?:action)=[\"|'](?!(?:https?://)|javascript:|on\w+:|mailto:|tel:)[\w|/]+ this does not enforce that there is a space before the action parameter. I'm suggesting that this line gets replaced with the following line: <form+?[^>]*?(?:\saction)=[\"|'](?!(?:https?://)|javascript:|on\w+:|mailto:|tel:)[\w|/]+

    This moves the requirement for the space into the "action" section and fixes this issue.

    :microbe: bug :mag: linter 
    opened by theomega 0
  • [BUG] [Linter] Linter complains about `data-action=

    [BUG] [Linter] Linter complains about `data-action="x"`

    System Info

    • OS: Mac OSX Ventura 13.1
    • Python Version (python --version): Python 3.11.1
    • djLint Version (djlint --version): djlint, version 1.19.10
    • template language: e.g. mustache: django

    Issue

    The Linter complains with an error D018 1:0 (Django) Internal links should use the {% url ... %} pattern. if a form has a data-action attribute.

    How To Reproduce

    Lint the following file:

    <form action="{% url 'something' %}" data-action="xxx"></form>
    

    Error: ``D018 1:0 (Django) Internal links should use the {% url ... %} pattern.```

    This is an invalid error, the data-action parameter has nothing to do with URLs but is used in some web frameworks.

    This is happening due to the following error in the Regexp that checks for the D018 rule. The rule is currently the following: <form\s+?[^>]*?(?:action)=[\"|'](?!(?:https?://)|javascript:|on\w+:|mailto:|tel:)[\w|/]+ this does not enforce that there is a space before the action parameter. I'm suggesting that this line gets replaced with the following line: <form+?[^>]*?(?:\saction)=[\"|'](?!(?:https?://)|javascript:|on\w+:|mailto:|tel:)[\w|/]+

    This moves the requirement for the space into the "action" section and fixes this issue.

    :microbe: bug :mag: linter 
    opened by theomega 0
  • [FEATURE] Multi-line classes

    [FEATURE] Multi-line classes

    Using tailwind in django templates, so there's a lot of classes. It's easier to keep them broken into several lines for easier readability.

    <a
      href="foo"
      class="
        inline-flex items-center p-4
        bg-white hover:bg-gray-200
        text-sm font-medium text-gray-500 hover:text-gray-700
      ">
    

    Currently djlint will want to put all of the classes into a single massive class string. Can we get a config rule to not remove class newlines?

    opened by TonisPiip 1
  • [BUG] [Formatter] django blocktranslate wrong indentation

    [BUG] [Formatter] django blocktranslate wrong indentation

    possible regression of #26

    djlint, version 1.19.7

    Issue

    Something is wrong with blocktranslate formatting, {% endblocktranslate %} is not properly indented.

    Code example - desired state

    <div>
        <span>
            {% translate "View all" %}
            <br />
            ({% blocktranslate count counter=images|length trimmed %}
                {{ counter }} photo
                {% plural %}
                {{ counter }} photos
            {% endblocktranslate %})
            <br/>
            <span>remark</span>
        </span>
    </div>
    

    Formatter output

    <div>
        <span>
            {% translate "View all" %}
            <br />
            ({% blocktranslate count counter=images|length trimmed %}
                {{ counter }} photo
                {% plural %}
                {{ counter }} photos
    {% endblocktranslate %})
            <br/>
            <span>remark</span>
        </span>
    </div>
    

    The example uses complex version of blocktranslate, but result is the same even if I remove count/trimmed args. Also wrapping content brackets (, ) ~~don't seem to play any role in this issue~~. see the comment

    Current workaround is to wrap all code in djlint:off.

    Thank you for djLint :green_heart:!


    :microbe: bug :sponge: formatter 
    opened by vasekch 3
  • [BUG] [Formatter] long textarea in twig - line wrapping does not work

    [BUG] [Formatter] long textarea in twig - line wrapping does not work

    Issue

    Your Djlint becomes better and better. Thank you!

    How To Reproduce

    I cannot reformat such long lines

    <textarea type="textarea" id="messageContent" name="adContent" maxlength="300" class="form-control" rows="10">{{ adContent|default }}</textarea>
    
    

    for like this:

    <textarea 
                   type="textarea" 
                   id="messageContent" 
                   name="adContent" 
                   maxlength="300"  
                   class="form-control" 
                   rows="10">
                   {{ adContent|default }}
    </textarea>
    

    It still one long line. Same time, the long 'inputs' and 'divs' are wrapped well.

    Please give your helping hand!


    BTW,

    By, according to my observations, for textareas

    this style

    <textarea 
                   content</textarea>
    

    is more prefferable then this

    <textarea 
                   content
    </textarea>
    

    Because in the second variant the browser adds extra ugly <CR/LF> trash to the end of content of textarea field. It happens when we have the combination of next three consistently: "content text" + line feed + "". So, the middle line feed makes the problem.


    my conf:

    .djlintrc

    {
        "ignore": "H021,H030,H031,H017,H023,H014,H006",
        "extension": "twig",
        "indent": "4",
        "profile": "nunjucks",
        "format_attribute_template_tags": false,
        "max_line_length": "110",
        "max_attribute_length": "100",
        "preserve_blank_lines": "true"
    }
    

    System Info

    • OS: e.g. ubuntu 20.04
    • Python Version 3.8.10
    • djLint Version 1.19.7
    • template language: twig
    :microbe: bug :sponge: formatter released 
    opened by palansher 14
Releases(v1.19.10)
Owner
Riverside Healthcare Analytics
Riverside Healthcare Analytics
✈️ HTML Template engine for python. Supports XSS preventation and many more!

Htmotor HTML Template Engine for Python! Installation: Open your terminal and type pip install htmotor.

Penguen 3 Nov 6, 2022
Use a docx as a jinja2 template

Use a docx as a jinja2 template

Eric Lapouyade 1.4k Jan 2, 2023
A general purpose template driven code generator

?? Shit Mountain Generator A general purpose template driven code generator Contribute shits to your company's shit mountain more efficiently! Quick S

Kelly 14 Mar 9, 2022
A string template language hosted by Python3 runtime

A string template language hosted by Python3 runtime. Conventionally, the source code of this language is written in plain text with utf-8 encoding and stored in a file with extension ".meme".

null 6 Nov 2, 2022
Simple reuse of partial HTML page templates in the Jinja template language for Python web frameworks.

Jinja Partials Simple reuse of partial HTML page templates in the Jinja template language for Python web frameworks. (There is also a Pyramid/Chameleo

Michael Kennedy 106 Dec 28, 2022
Use heroicons in your Django and Jinja templates.

heroicons Use heroicons in your Django and Jinja templates. Requirements Python 3.6 to 3.9 supported. Django 2.2 to 3.2 supported. Are your tests slow

Adam Johnson 52 Dec 14, 2022
Your missing PO formatter and linter

pofmt Your missing PO formatter and linter Features Wrap msgid and msgstr with a constant max width. Can act as a pre-commit hook. Display lint errors

Frost Ming 5 Mar 22, 2022
Opinionated code formatter, just like Python's black code formatter but for Beancount

beancount-black Opinionated code formatter, just like Python's black code formatter but for Beancount Try it out online here Features MIT licensed - b

Launch Platform 16 Oct 11, 2022
Fully Automated YouTube Channel ▶️with Added Extra Features.

Fully Automated Youtube Channel ▒█▀▀█ █▀▀█ ▀▀█▀▀ ▀▀█▀▀ █░░█ █▀▀▄ █▀▀ █▀▀█ ▒█▀▀▄ █░░█ ░░█░░ ░▒█░░ █░░█ █▀▀▄ █▀▀ █▄▄▀ ▒█▄▄█ ▀▀▀▀ ░░▀░░ ░▒█░░ ░▀▀▀ ▀▀▀░

sam-sepiol 249 Jan 2, 2023
Django/Jinja template indenter

DjHTML A pure-Python Django/Jinja template indenter without dependencies. DjHTML is a fully automatic template indenter that works with mixed HTML/CSS

Return to the Source 378 Jan 1, 2023
JTEX is a command line tool (CLI) for rendering LaTeX documents from jinja-style templates.

JTEX JTEX is a command line tool (CLI) for rendering LaTeX documents from jinja-style templates. This package uses Jinja2 as the template engine with

Curvenote 15 Dec 21, 2022
A Django app that allows you to send email asynchronously in Django. Supports HTML email, database backed templates and logging.

Django Post Office Django Post Office is a simple app to send and manage your emails in Django. Some awesome features are: Allows you to send email as

User Inspired 856 Dec 25, 2022
Use minify-html, the extremely fast HTML + JS + CSS minifier, with Django.

django-minify-html Use minify-html, the extremely fast HTML + JS + CSS minifier, with Django. Requirements Python 3.8 to 3.10 supported. Django 2.2 to

Adam Johnson 60 Dec 28, 2022
Django-Text-to-HTML-converter - The simple Text to HTML Converter using Django framework

Django-Text-to-HTML-converter This is the simple Text to HTML Converter using Dj

Nikit Singh Kanyal 6 Oct 9, 2022
Django module to easily send emails/sms/tts/push using django templates stored on database and managed through the Django Admin

Django-Db-Mailer Documentation available at Read the Docs. What's that Django module to easily send emails/push/sms/tts using django templates stored

LPgenerator 250 Dec 21, 2022
A flask template with Bootstrap 4, asset bundling+minification with webpack, starter templates, and registration/authentication. For use with cookiecutter.

cookiecutter-flask A Flask template for cookiecutter. (Supports Python ≥ 3.6) See this repo for an example project generated from the most recent vers

null 4.3k Dec 29, 2022
This is a template tag project for django to calculate in templates , enjoy it

Calculator-Template-Django this is a template tag project for django to calculate in templates , enjoy it Get Started : 1 - Download Source Code 2 - M

null 1 Feb 1, 2022
Blender Game Engine Game Type Templates Logic Bricks (and Python script) based Game Templates for Blender

Blender-Game-Engine-Templates Blender Game Engine Game Type Templates Logic Bric

null 3 Oct 25, 2022
A Python command-line utility for validating that the outputs of a given Declarative Form Azure Portal UI JSON template map to the input parameters of a given ARM Deployment Template JSON template

A Python command-line utility for validating that the outputs of a given Declarative Form Azure Portal UI JSON template map to the input parameters of a given ARM Deployment Template JSON template

Glenn Musa 1 Feb 3, 2022
Tweak the form field rendering in templates, not in python-level form definitions. CSS classes and HTML attributes can be altered.

django-widget-tweaks Tweak the form field rendering in templates, not in python-level form definitions. Altering CSS classes and HTML attributes is su

Jazzband 1.8k Jan 2, 2023