- D: applies specifically to Django
- H: applies to html
- J: applies specifically to Jinja
- M: applies specifically to Handlebars
- N: applies specifically to Nunjucks
- T: applies generally to templates
djLint includes many rules to check the style and validity of your templates. Take full advantage of the linter by configuring it to use a preset profile for the template language of your choice.
djlint /path/to/templates --lint
# with custom extensions
djlint /path/to/templates -e html.dj --profile=django
# or to file
djlint /path/to/this.html.j2 --profile=jinja
Most rules are enabled by default. Rules can be disabled in the command line with the --ignore
flag. Rules can be enabled with the --include
flag.
For example:
djlint . --lint --include=H017,H035 --ignore=H013,H015
This can also be done through the Configuration file.
Code | Meaning | Default |
---|---|---|
D004 | (Django) Static urls should follow {% static path/to/file %} pattern. |
✔️ |
D018 | (Django) Internal links should use the {% url ... %} pattern. |
✔️ |
H005 | Html tag should have lang attribute. |
✔️ |
H006 | img tag should have height and width attributes. |
✔️ |
H007 | <!DOCTYPE ... > should be present before the html tag. |
✔️ |
H008 | Attributes should be double quoted. | ✔️ |
H009 | Tag names should be lowercase. | ✔️ |
H010 | Attribute names should be lowercase. | ✔️ |
H011 | Attribute values should be quoted. | ✔️ |
H012 | There should be no spaces around attribute = . |
✔️ |
H013 | img tag should have alt attributes. |
✔️ |
H014 | More than 2 blank lines. | ✔️ |
H015 | Follow h tags with a line break. |
✔️ |
H016 | Missing title tag in html. |
✔️ |
H017 | Void tags should be self closing. | - |
H019 | Replace javascript:abc() with on_ event and real url. |
✔️ |
H020 | Empty tag pair found. Consider removing. | ✔️ |
H021 | Inline styles should be avoided. | ✔️ |
H022 | Use HTTPS for external links. | ✔️ |
H023 | Do not use entity references. | ✔️ |
H024 | Omit type on scripts and styles. | ✔️ |
H025 | Tag seems to be an orphan. | ✔️ |
H026 | Empty id and class tags can be removed. | ✔️ |
H029 | Consider using lowercase form method values. | ✔️ |
H030 | Consider adding a meta description. | ✔️ |
H031 | Consider adding meta keywords. | ✔️ |
H033 | Extra whitespace found in form action. | ✔️ |
J004 | (Jinja) Static urls should follow {{ url_for('static'..) }} pattern. |
✔️ |
J018 | (Jinja) Internal links should use the {% url ... %} pattern. |
✔️ |
T001 | Variables should be wrapped in whitespace. Ex: {{ this }} |
✔️ |
T002 | Double quotes should be used in tags. Ex {% extends "this.html" %} |
✔️ |
T003 | Endblock should have name. Ex: {% endblock body %} . |
✔️ |
T027 | Unclosed string found in template syntax. | ✔️ |
T028 | Consider using spaceless tags inside attribute values. {%- if/for -%} |
✔️ |
T032 | Extra whitespace found in template tags. | ✔️ |
T034 | Did you intend to use {% … %} instead of {% … }%? | ✔️ |
H035 | Meta tags should be self closing. | - |
H036 | Avoid use of tags. |
- |
H037 | Duplicate attribute found. | ✔️ |
The first letter of a code follows the pattern:
We welcome pull requests with new rules!
A good rule consists of
Please include a test to validate the rule.
You can add custom rules just for your project by creating a .djlint_rules.yaml
alongside
your pyproject.toml
. Rules can be added to this files and djLint will pick them up.
You can add rules that fails if one of the regex pattern has a match:
- rule:
name: T001
message: Find Trichotillomania
flags: re.DOTALL|re.I
patterns:
- Trichotillomania
You can add rules that import and execute a custom python function:
- rule:
name: T001
message: Found the 'bad' word
python_module: your_package.your_module
The specified python_module
must contain a run()
function that will be executed on
every checked file. It must accept the following arguments:
rule
: The dict that represent your rule in .djlint_rules.yaml
. You will typicallyconfig
: The DJLint configuration object.html
: The full html content of the file.filepath
: Path to the file that we are currently checking.line_ends
: List of line start
and end
character position that you can use withdjlint.lint.get_line()
to get line numbers from a character position. See the example.*args, **kwargs
: We might add other arguments in the future, so you should includeIt must return a list of dict, one for each errors, with the following keys:
code
: Code name of the rule that report the error (typically rule['name']
)line
: Line number and character number on this line, separated by a ‘:’ as a string."2:3"
means that the error has been found on line 2, character 3match
: The part of the content that contains the errormessage
: The message that will be printed to signal the error (typically rule['message']
)from typing import Any, Dict, List
from djlint.settings import Config
from djlint.lint import get_line
import re
def run(
rule: Dict[str, Any],
config: djlint.settings.Config,
html: str,
filepath: str,
line_ends: List[Dict[str, int]],
*args: Any,
**kwargs: Any,
) -> List[Dict[str, str]]:
"""
Rule that fails if if the html file contains 'bad'. This is just an example, in
reality it's much simpler to do that with "pattern rule".
"""
errors: List[Dict[str, str]] = []
for match in re.finditer(r"bad", html):
errors.append(
{
"code": rule["name"],
"line": get_line(match.start(), line_ends),
"match": match.group().strip()[:20],
"message": rule["message"],
}
)
return errors