updated docs

This commit is contained in:
Christopher Pickering 2022-01-03 16:45:58 -06:00
parent 64a806a3eb
commit efec955de5
No known key found for this signature in database
GPG key ID: E14DB3B0A0FACF84
85 changed files with 18634 additions and 6727 deletions

View file

@ -13,14 +13,9 @@ jobs:
- name: Checkout
uses: actions/checkout@v2
- name: build docs
run: |
pip install tox
tox -e docs
- name: publish
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/_build
publish_dir: ./docs
publish_branch: netlify

4
.gitignore vendored
View file

@ -2,6 +2,8 @@ badtest.html
node_modules
source_django
report.xml
_site
# Created by https://www.toptal.com/developers/gitignore/api/macos,python
# Edit at https://www.toptal.com/developers/gitignore?templates=macos,python
@ -175,3 +177,5 @@ dmypy.json
cython_debug/
# End of https://www.toptal.com/developers/gitignore/api/macos,python
!docs/lib
!docs_new/lib

191
docs/.eleventy.js Normal file
View file

@ -0,0 +1,191 @@
const Image = require("@11ty/eleventy-img");
const syntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight");
const criticalCss = require("eleventy-critical-css");
const slugify = require("slugify");
const metagen = require("eleventy-plugin-metagen");
const fs = require('fs');
const outdent = require('outdent');
const schema = require("@quasibit/eleventy-plugin-schema");
const slugifyCustom = (s) =>
slugify(s, { lower: true, remove: /[*+~.()'"!:@]/g });
async function imageShortcode(src, alt, sizes, type='asdf', loading="lazy", decoding="async") {
let metadata = await Image(src, {
widths: [24, 300, 400, 500, 600, 800, 1200],
formats: ["webp"],
sharpWebpOptions: {
options: {
quality:70
}
},
outputDir: "./_site/static/img/",
urlPath: "/static/img/"
});
let imageAttributes = {
alt,
sizes,
loading: loading,
decoding: decoding,
};
if(type=="boxed"){
return `<div class="block"><div class="box is-inlineblock">` + Image.generateHTML(metadata, imageAttributes) + `</div></div>`;
}
return Image.generateHTML(metadata, imageAttributes);
}
// from https://github.com/pusher/docs/blob/main/.eleventy.js
// widont is a function that takes a string and replaces the space between the last two words with a non breaking space. This stops typographic widows forming
const widont = (string) => {
return string.split(" ").length > 2
? string.replace(/\s([^\s<]+)\s*$/, "\u00A0$1")
: string;
};
module.exports = function(eleventyConfig) {
eleventyConfig.setUseGitIgnore(false);
eleventyConfig.addFilter("widont", widont);
eleventyConfig.addWatchTarget("./src/static/");
eleventyConfig.addNunjucksAsyncShortcode("image", imageShortcode);
eleventyConfig.addTransform("htmlmin", require("./src/_utils/minify-html.js"));
eleventyConfig.addPlugin(syntaxHighlight);
eleventyConfig.addPlugin(metagen);
eleventyConfig.addPlugin(criticalCss);
eleventyConfig.addPlugin(schema);
/* Markdown Plugins */
const markdownItAnchor = require("markdown-it-anchor");
const markdownIt = require("markdown-it")({
html: true,
breaks: true,
linkify: true,
typographer: true,
});
const opts = {
level: [2, 3, 4, 5],
permalink: markdownItAnchor.permalink.linkInsideHeader({
class: "link bn",
symbol:"∞",
placement: "before"
}),
slugify: slugifyCustom,
};
const mapping = {
h1: 'title is-1',
h2: 'title is-2',
h3: 'title is-3',
h4: 'title is-4',
h5: 'title is-5',
h6: 'title is-5',
p: 'block',
table: 'table'
};
markdownIt
.use(markdownItAnchor, opts)
.use(require("markdown-it-imsize"), { autofill: true })
.use(require('@toycode/markdown-it-class'), mapping)
.use(require('markdown-it-div'), 'div', {});
eleventyConfig.setLibrary("md", markdownIt);
// copy font
eleventyConfig.addPassthroughCopy({
"./node_modules/@fontsource/inter/files": "static/font/inter/files"
});
eleventyConfig.addPassthroughCopy({
"./node_modules/@fontsource/rasa/files": "static/font/rasa/files"
});
// copy images
eleventyConfig.addPassthroughCopy({
"src/static/img": "static/img"
});
// copy robots
eleventyConfig.addPassthroughCopy({
"src/robots.txt": "robots.txt"
});
// copy favicon
eleventyConfig.addPassthroughCopy({
"src/static/img/favicon.ico": "favicon.ico"
});
eleventyConfig.addFilter("jsonify", (text) => {
return JSON.stringify(text).replace(/(?:\\n\s*){2,}/g, "\\n");
});
eleventyConfig.addFilter("niceDate", (value) => {
try{
const options = {year: 'numeric', month: 'short', day: 'numeric' };
return value.toLocaleDateString('en-us', options);
} catch (e) {
return value
}
});
eleventyConfig.addFilter("algExcerpt", (text) => {
return text
.replace(/<code class="language-.*?">.*?<\/code>/gs, "")
.replace(/<.*?>/g, "")
.substring(0, 8000);
});
eleventyConfig.addCollection("algolia", function(collection) {
return collection.getFilteredByGlob("**/*.md");
});
const icons = {
note: '<span class="icon has-text-info"><i class="fas fa-pencil-alt"></i></span>',
hint: "./src/_includes/icons/green_question.njk",
alert: "./src/_includes/icons/red_triangle.njk"
};
eleventyConfig.addShortcode("admonition", function(icon, title, text) {
return outdent`
<article class="message ` + icon + ` box">
<div class="message-header">
<p>` + icons[icon] +title+`</p>
</div>
<div class="message-body">` + `${markdownIt.render(text)}`+ `</div>
</article>`;
});
eleventyConfig.addFilter('markdown', value => {
return `${markdownIt.render(value)}`;
});
const { fontawesomeSubset } = require('fontawesome-subset');
fontawesomeSubset({
brands:['discord', 'github'],
regular:['envelope', 'life-ring'],
solid: ['arrow-circle-right', 'pencil-alt', 'envelope', 'share', 'infinity', 'search', 'book', 'project-diagram', 'heart', 'address-card', 'server', 'database', 'ship', 'code', 'chart-bar', 'sitemap', 'tasks', 'lock', 'sliders-h', 'user', 'users', 'compass', 'download', 'sync-alt']
}, '_site/static/font/fontawesome/webfonts');
return {
dir: {
input: "src",
formats: "njk",
includes: "_includes",
data: "_data",
output: "_site"
},
templateFormats: ["md", "html", "njk", "11ty.js"],
htmlTemplateEngine: "njk",
markdownTemplateEngine: "njk",
passthroughFileCopy: true
};
};

2
docs/.eleventyignore Normal file
View file

@ -0,0 +1,2 @@
src/static/**/*.md
src/static/**/*.html

View file

@ -1,20 +0,0 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

View file

@ -1,7 +0,0 @@
@import "../node_modules/bulma/bulma";
a {
color:pink;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

BIN
docs/_static/icon.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -1,132 +0,0 @@
{#
basic/layout.html
~~~~~~~~~~~~~~~~~
Master layout template for Sphinx themes.
:copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
#}
{%- block doctype -%}{%- if html5_doctype %}
<!DOCTYPE html>
{%- else %}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
{%- endif %}{%- endblock %}
{%- set reldelim1 = reldelim1 is not defined and ' &#187;' or reldelim1 %}
{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %}
{%- set render_sidebar = (not embedded) and (not theme_nosidebar|tobool) and
(sidebars != []) %}
{# URL root should never be #, then all links are fragments #}
{%- if not embedded and docstitle %}
{%- set titlesuffix = " &#8212; "|safe + docstitle|e %}
{%- else %}
{%- set titlesuffix = "" %}
{%- endif %}
{%- if html_tag %}
{{ html_tag }}
{%- else %}
<html{% if not html5_doctype %} xmlns="http://www.w3.org/1999/xhtml"{% endif %}{% if language is not none %} lang="{{ language }}"{% endif %}>
{%- endif %}
<head>
{%- if not html5_doctype and not skip_ua_compatible %}
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
{%- endif %}
{%- if use_meta_charset or html5_doctype %}
<meta charset="{{ encoding }}" />
{%- else %}
<meta http-equiv="Content-Type" content="text/html; charset={{ encoding }}" />
{%- endif %}
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
{{- metatags }}
{%- block htmltitle %}
<title>{{ title|striptags|e }}{{ titlesuffix }}</title>
{%- endblock %}
{%- if not embedded %}
{%- if pageurl %}
<link rel="canonical" href="{{ pageurl|e }}" />
{%- endif %}
{%- if use_opensearch %}
<link rel="search" type="application/opensearchdescription+xml"
title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}"
href="{{ pathto('_static/opensearch.xml', 1) }}"/>
{%- endif %}
{%- if favicon_url %}
<link rel="shortcut icon" href="{{ favicon_url|e }}"/>
{%- endif %}
{%- endif %}
{%- block linktags %}
{%- if hasdoc('about') %}
<link rel="author" title="{{ _('About these documents') }}" href="{{ pathto('about') }}" />
{%- endif %}
{%- if hasdoc('genindex') %}
<link rel="index" title="{{ _('Index') }}" href="{{ pathto('genindex') }}" />
{%- endif %}
{%- if hasdoc('search') %}
<link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}" />
{%- endif %}
{%- if hasdoc('copyright') %}
<link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}" />
{%- endif %}
{%- if next %}
<link rel="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}" />
{%- endif %}
{%- if prev %}
<link rel="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}" />
{%- endif %}
{%- endblock %}
{%- block extrahead %} {% endblock %}
</head>
{%- block body_tag %}<body>{% endblock %}
{%- block header %}{% endblock %}
{%- block content %}
{%- block sidebar1 %} {# possible location for sidebar #} {% endblock %}
<div class="document">
{%- block document %}
<div class="documentwrapper">
{%- if render_sidebar %}
<div class="bodywrapper">
{%- endif %}
<div class="body" role="main">
{% block body %} {% endblock %}
<div class="clearer"></div>
</div>
{%- if render_sidebar %}
</div>
{%- endif %}
</div>
{%- endblock %}
<div class="clearer"></div>
</div>
{%- endblock %}
{%- block footer %}
<div class="footer" role="contentinfo">
{%- if show_copyright %}
{%- if hasdoc('copyright') %}
{% trans path=pathto('copyright'), copyright=copyright|e %}&#169; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
{%- else %}
{% trans copyright=copyright|e %}&#169; Copyright {{ copyright }}.{% endtrans %}
{%- endif %}
{%- endif %}
{%- if last_updated %}
{% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
{%- endif %}
{%- if show_sphinx %}
{% trans sphinx_version=sphinx_version|e %}Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> {{ sphinx_version }}.{% endtrans %}
{%- endif %}
</div>
{%- endblock %}
</body>
</html>

View file

@ -1,58 +0,0 @@
{% extends "!layout.html" %}
{%- block htmltitle %}
<meta {{pageurl}} >
<title>{{ docstitle|e }}{{ title|striptags|e }}</title>
{%- endblock %}
{%- if pageurl %}
{% set pageurl = pageurl| replace("index.html","")| replace(".html","/") %}
{%- endif %}
{%- block extrahead %}
<meta {{pageurl}} >
{{ super() }}
{%- if meta is mapping and meta.get("description") %}
{% set description = meta.get("description") %}
{% else %}
{% set description = "djLint HTML template linter and formatter. Find common syntax errors, reformat to make your HTML templates shine! Supports django, jinja, nunjucks, twig, handlebars, mustache, golang, and more!" %}
{%- endif %}
<script type="application/ld+json">{
"@context": "https://schema.org",
"@graph": [
{
"@type": "WebSite",
"@id": "https://djlint.com#website",
"url": "https://djlint.com",
"name": "djLint HTML template linter and formatter",
"description": "djLint HTML template linter and formatter. Find common syntax errors, reformat to make your HTML templates shine! Supports django, jinja, nunjucks, twig, handlebars, mustache, golang, and more!",
"inLanguage": "en-US"
},
{
"@type": "WebPage",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://djlint.com/"
},
"url": "{{ pageurl }}",
"isPartOf": {
"@id": "https://djlint.com#website"
},
"headline": "{{ docstitle|e }}{{ title|striptags|e }}",
"description": "{{ description }}",
"inLanguage": "en-US",
"publisher": {
"@type": "Organization",
"name": "Riverside Healthcare",
"url": "https://github.com/Riverside-Healthcare",
"logo": {
"@type": "ImageObject",
"url": "https://djlint.com/_static/icon.png"
}
}
}
]
}</script>
{% endblock %}

View file

@ -1,78 +0,0 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# -- Project information -----------------------------------------------------
project = "djlint"
copyright = "2021, Riverside Healthcare"
author = "Christopher Pickering"
release = "0.6.9"
version = release
# -- General configuration ---------------------------------------------------
extensions = ["myst_parser", "sphinx_copybutton", "sphinx_sitemap"]
templates_path = ["_templates"]
exclude_patterns = [
"_build",
"Thumbs.db",
".DS_Store",
"_assets",
"node_modules",
"gulpfile.js",
"package.json",
"package-lock.json",
"requirements.txt",
]
# -- Options for HTML output -------------------------------------------------
html_theme = "alabaster"
html_title = "djLint » "
html_favicon = "_static/favicon.ico"
language = "en"
html_sidebars = {
"**": [
"about.html",
"navigation.html",
"relations.html",
"searchbox.html",
]
}
html_theme_options = {
"show_related": False,
"description": "Html Template Linter and Formatter",
"github_button": True,
"github_user": "Riverside-Healthcare",
"github_repo": "djlint",
"github_type": "star",
"show_powered_by": False,
"fixed_sidebar": True,
"logo": "icon.png",
}
html_static_path = ["_static"]
source_suffix = [".rst", ".md"]
pygments_style = "sphinx"
html_css_files = [
"css/style.css",
]
# -- Sitemap -------------------------------------------------------------------
html_baseurl = "https://djlint.com/"
html_extra_path = ["robots.txt"]
sitemap_url_scheme = "{link}"

View file

@ -1,59 +0,0 @@
:description: Best practices for using djLint to format HTML templates.
.. meta::
:title lang=en: Best Practices | djLint
:description lang=en:
Best practices for using djLint to format HTML templates.
:keywords lang=en: template linter, template formatter, djLint, HTML, templates, formatter, linter, best practices
Best Practices
==============
Spaces Around Conditional Attributes
------------------------------------
Sometimes conditions are used to add classes to a tag. djLint removes whitespace inside conditional statements.
This pattern is recommended:
.. code:: html
<div class="class1 {% if condition -%}class2{%- endif %}">content</div>
^ space here
This pattern is not recommended:
.. code:: html
<div class="class1{% if condition -%} class2{%- endif %}">content</div>
^ space here
``format_attribute_template_tags`` and Spaceless Conditional Attributes
-----------------------------------------------------------------------
If ``format_attribute_template_tags`` option is enabled, conditional attributes should use spaceless tags, for example ``{% if a -%}`` in nunjuck and jinja, to remove spaces inside the.
djLint will format long attributes onto multiple lines, and the whitespace saved inside of attributes could break your code.
This pattern is recommended:
.. code:: html
<input value="{% if database -%}{{ database.name }}{%- else -%}blah{%- endif %}"/>
^ ^ ^ ^-- spaceless tags
This pattern is not recommended:
.. code:: html
<input value="{% if database %}{{ database.name }}{% else %}blah{% endif %}"/>
After formatting this could look like:
.. code:: html
<input value="{% if database %}
{{ database.name }}
{% else %}
blah
{% endif %}"/>

View file

@ -1,223 +0,0 @@
:description: djLint configuration for HTML Template Linting and Formatting. Take advantage of the many formatter options.
.. meta::
:title lang=en: Configuration | djLint
:description lang=en: djLint configuration for HTML Template Linting and Formatting. Take advantage of the many formatter options.
:keywords lang=en: template linter, template formatter, djLint, HTML, templates, formatter, linter, configuration
Configuration
=============
Configuration is done through your projects `pyproject.toml` file. Command line args will always override any settings in `pyproject.toml`.
.. code:: ini
[tool.djlint]
<config options>
ignore
------
Ignore linter codes.
Usage:
.. code:: ini
ignore = "H014"
extension
---------
Use to only find files with a specific extension.
Usage:
.. code:: ini
extension = "html.dj"
custom_blocks
-------------
Use to indent custom code blocks. For example ``{% toc %}...{% endtoc %}``
Usage:
.. code:: ini
custom_blocks = "toc,example"
custom_html
-----------
Use to indent custom HTML tags. For example ``<mjml>`` or ``<simple-greeting>`` or ``<mj-\w+>``
Usage:
.. code:: ini
custom_html = "mjml,simple-greeting,mj-\\w+"
indent
------
Use to change the code indentation. Default is 4 (four spaces).
Usage:
.. code:: ini
indent = 3 # change indentation level
exclude
-------
Override the default exclude paths.
Usage:
.. code:: ini
exclude = ".venv,venv,.tox,.eggs,..."
extend_exclude
--------------
Add additional paths to the default exclude.
Usage:
.. code:: ini
extend_exclude = ".custom"
blank_line_after_tag
--------------------
Add an additional blank line after ``{% <tag> ... %}`` tag groups.
Usage:
.. code:: ini
blank_line_after_tag = "load,extends,include"
profile
-------
Set a default profile for the template language. The profile will disable linter rules that do not apply to your template language, and may also change reformatting. For example, in ``handlebars`` there are no spaces inside ``{{#if}}`` tags.
Options:
- html
- django
- jinja
- nunjucks
- handlebars (for handlebars and mustache)
- golang
- angular
Usage:
.. code:: ini
profile="django"
require_pragma
--------------
Only format or lint files that starts with a comment with only the text 'djlint:on'. The comment can be a HTML comment or a comment in the template language defined by the profile setting. If no profile is specified, a comment in any of the template languages is accepted.
Usage:
.. code:: ini
require_pragma = true
.. code:: html
<!-- djlint:on -->
or
{# djlint:on #}
or
{% comment %} djlint:on {% endcomment %}
or
{{ /* djlint:on */ }}
or
{{!-- djlint:on --}}
max_line_length
---------------
Formatter will attempt to put some html and template tags on a single line instead of wrapping them if the line length will not exceed this value.
Usage:
.. code:: ini
max_line_length=120
max_attribute_length
--------------------
Formatter will attempt to wrap tag attributes if the attribute length exceeds this value.
Usage:
.. code:: ini
max_attribute_length=10
use_gitignore
-------------
Add .gitignore excludes to the default exclude.
Usage:
.. code:: ini
use_gitignore = True
format_attribute_template_tags
------------------------------
Formatter will attempt to format template syntax inside of tag attributes. Disabled by default.
Usage:
.. code:: ini
format_attribute_template_tags=true
For example, with this option enabled, the following html will be acceptable:
.. code:: html
<input class="{% if this %}
then something neat
{% else %}
that is long stuff asdf and more even
{% endif %}"/>
linter_output_format
--------------------
Customize order of output message. Default="{code} {line} {message} {match}". If ``{filename}`` is not include in message, then the output will be grouped by file and a header will automatically be added to each group.
Usage:
.. code:: ini
# optional variables:
# {filename}
# {line}
# {code}
# {message}
# {match}
linter_output_format="{filename}:{line}: {code} {message} {match}"

View file

@ -1,47 +0,0 @@
:description: Format your HTML Templates with djLint. Fast, accurate, output will make your templates shine.
.. meta::
:title lang=en: Formatter Usage | djLint
:description lang=en:
Format your HTML Templates with djLint. Fast, accurate, output
will make your templates shine.
:keywords lang=en: template linter, template formatter, djLint, HTML, templates, formatter, linter, formatter usage
Formatter Usage
===============
djLint's formatter will take sloppy html templates and make it look pretty nice!
Before
------
.. code ::
{% load admin_list %}{% load i18n %}<p class="paginator">{% if pagination_required %}{% for i in page_range %}{% paginator_number cl i %}{% endfor %}{% endif %}{{ cl.result_count }}{% if cl.result_count == 1 %}{{ cl.opts.verbose_name }} {% else %}{{ cl.opts.verbose_name_plural }} {% endif %}{% if show_all_url %} <a href="{{ show_all_url }}" class="showall">{% translate 'Show all' %} </a> {% endif %}{% if cl.formset and cl.result_count %}<input type="submit" name="_save" class="default" value="{% translate 'Save' %}">{% endif %} </p>
After
-----
.. code :: html
{% load admin_list %}
{% load i18n %}
<p class="paginator">
{% if pagination_required %}
{% for i in page_range %}
{% paginator_number cl i %}
{% endfor %}
{% endif %}
{{ cl.result_count }}
{% if cl.result_count == 1 %}
{{ cl.opts.verbose_name }}
{% else %}
{{ cl.opts.verbose_name_plural }}
{% endif %}
{% if show_all_url %}
<a href="{{ show_all_url }}" class="showall">
{% translate 'Show all' %}
</a>
{% endif %}
{% if cl.formset and cl.result_count %}
<input type="submit" name="_save" class="default" value="{% translate 'Save' %}">
{% endif %}
</p>

View file

@ -1,136 +0,0 @@
:description: Getting started with djLint for HTML Template Linting and Formatting. Take advantage of the easy cli interface and many formatter options.
.. meta::
:title lang=en: Getting Started | djLint
:description lang=en:
Getting started with djLint for HTML Template Linting and Formatting.
Take advantage of the easy cli interface and many formatter options.
:keywords lang=en: template linter, template formatter, djLint, HTML, templates, formatter, linter, usage
Getting Started
================
Installation from `Pypi <https://pypi.org/project/djlint/>`__
--------------------------------------------------------------
.. code:: bash
pip install djlint
CLI Usage
---------
djLint is a command line application. See `configuration </docs/configuration>`_ for advanced configuration.
.. code:: sh
Usage: python -m djlint [OPTIONS] SRC ...
djLint · lint and reformat HTML templates.
Options:
--version Show the version and exit.
-e, --extension TEXT File extension to check [default: html]
-i, --ignore TEXT Codes to ignore. ex: "H014,H017"
--reformat Reformat the file(s).
--check Check formatting on the file(s).
--indent INTEGER Indent spacing. [default: 4]
--quiet Do not print diff when reformatting.
--profile TEXT Enable defaults by template language. ops: django,
jinja, nunjucks, handlebars, golang
--require-pragma Only format or lint files that starts with a comment
with the text 'djlint:on'
--lint Lint for common issues. [default option]
--use-gitignore Use .gitignore file to extend excludes.
-h, --help Show this message and exit.
Linter Usage
------------
.. code:: sh
djlint src # file or path
# with custom extensions
djlint src -e html.dj
Formatter Usage
---------------
Formatting is a beta tool. ``--check`` the output before applying changes.
To review what may change in formatting run:
.. code:: sh
djlint . --check --ignore="H014,H017"
To format the code and update files run:
.. code:: sh
djlint . --reformat --indent=3
.. note::
Reformatting does not work with long json/html embedded into attribute data.
Ignoring Code
-------------
Code can be skipped by the linter and formatter by wrapping in djlint tags:
.. code:: html
<!-- djlint:off -->
<bad html to ignore>
<!-- djlint:on -->
or
{# djlint:off #}
<bad html to ignore>
{# djlint:on #}
or
{% comment %} djlint:off {% endcomment %}
<bad html to ignore>
{% comment %} djlint:on {% endcomment %}
or
{{ /* djlint:off */ }}
<bad html to ignore>
{{ /* djlint:on */ }}
or
{{!-- djlint:off --}}
<bad html to ignore>
{{!-- djlint:on --}}
Stdin vs Path
-------------
djLint also works with stdin.
.. code:: sh
echo "<div></div>" | djlint -
Stdin can also be used to reformat code. The output will be only the formatted code without messages.
.. code:: sh
echo "<div></div>" | djlint - --reformat
Output -
.. code:: html
<div></div>

View file

@ -1,124 +0,0 @@
:description: djLint HTML Template linter includes over 30 rules! Find the definitions here. Easily expand with include custom rules!
.. meta::
:title lang=en: Linter Rules | djLint
:description lang=en:
djLint HTML Template linter includes over 30 rules! Find the definitions here.
Easily expand with include custom rules!
:keywords lang=en: template linter, template formatter, djLint, HTML, templates, formatter, linter, rules
Linter Rules
============
Codes
~~~~~
+--------+---------------------------------------------------------------------------+
| Code | Meaning |
+========+===========================================================================+
| T001 | Variables should be wrapped in a single whitespace. Ex: ``{{ this }}`` |
+--------+---------------------------------------------------------------------------+
| T002 | Double quotes should be used in tags. Ex ``{% extends "this.html" %}`` |
+--------+---------------------------------------------------------------------------+
| T003 | Endblock should have name. Ex: ``{% endblock body %}``. |
+--------+---------------------------------------------------------------------------+
| D004 | (Django) Static urls should follow ``{% static path/to/file %}`` pattern. |
+--------+---------------------------------------------------------------------------+
| J004 | (Jinja) Static urls should follow ``{{ url_for('static'..) }}`` 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 | Tag should be self closing. |
+--------+---------------------------------------------------------------------------+
| D018 | (Django) Internal links should use the ``{% url ... %}`` pattern. |
+--------+---------------------------------------------------------------------------+
| J018 | (Jinja) Internal links should use the ``{% url ... %}`` pattern. |
+--------+---------------------------------------------------------------------------+
| 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 | Emtpy id and class tags can be removed. |
+--------+---------------------------------------------------------------------------+
| T027 | Unclosed string found in template syntax. |
+--------+---------------------------------------------------------------------------+
| T028 | Consider using spaceless tags inside attribute values. ``{%- if/for -%}`` |
+--------+---------------------------------------------------------------------------+
| H029 | Consider using lowercase form method values. |
+--------+---------------------------------------------------------------------------+
| H030 | Consider adding a meta description. |
+--------+---------------------------------------------------------------------------+
| H031 | Consider adding meta keywords. |
+--------+---------------------------------------------------------------------------+
Adding Rules
------------
A good rule consists of
- Name
- Code
- Message - Message to display when error is found.
- Flags - Regex flags. Defaults to re.DOTALL. ex: re.I|re.M
- Patterns - regex expressions that will find the error.
- Exclude - Optional list of profiles to exclude rule from.
Code Patterns
~~~~~~~~~~~~~
The first letter of a code follows the pattern:
- T: applies generally to templates
- H: applies to html
- D: applies specifically to Django
- J: applies specifically to Jinja
- N: applies specifically to Nunjucks
- M: applies specifically to Handlebars
Custom Rules
~~~~~~~~~~~~
Create a file ``.djlint_rules.yaml`` alongside your ``pyproject.toml``. Rules can be added to this files and djLint will pick them up.
A good rule follows this pattern:
.. code:: yaml
- rule:
name: T001
message: Find Trichotillomania
flags: re.DOTALL|re.I
patterns:
- Trichotillomania

View file

@ -1,32 +0,0 @@
var postcss = require('gulp-postcss');
var { gulp, series, src, dest, watch, paths } = require('gulp');
var autoprefixer = require('autoprefixer');
var cssnano = require('cssnano');
var sass = require('gulp-sass')(require('sass'));
var sortMediaQueries = require('postcss-sort-media-queries');
var purgecss = require('gulp-purgecss');
function style() {
return src('./_assets/style.scss')
.pipe(sass().on('error', sass.logError))
.pipe(postcss([
sortMediaQueries(),
autoprefixer(),
cssnano(),
]))
.pipe(purgecss({
content: ['./**/*.html.dj'],
safelist: {
deep: [/breadcrumb/],
}
}))
.pipe(dest('./_static/css/'));
};
exports.default = series(style)
exports.watch = function() {
watch('./_assets/style.scss',{ ignoreInitial: false }, style)
}

View file

@ -1,90 +0,0 @@
.. meta::
:title lang=en: djLint | HTML Template Linter and Formatter
:description lang=en:
Find common syntax errors, reformat to make your HTML templates shine!
Supports django, jinja, nunjucks, twig, handlebars, mustache, golang, and more!
:keywords lang=en: template linter, template formatter, djLint, HTML, templates, formatter, linter
HTML Template Linter and Formatter
==================================
.. toctree::
:hidden:
:glob:
:maxdepth: 1
:titlesonly:
Welcome<self>
docs/getting_started
docs/linter_rules
docs/formatter
docs/configuration
docs/best_practices
docs/changelog
docs/integrations
.. toctree::
:hidden:
GitHub ↪ <https://github.com/Riverside-Healthcare/djlint>
PyPI ↪ <https://pypi.org/project/djlint/>
Chat ↪ <https://discord.gg/taghAqebzU>
Lint for common HTML/template issues and *format* HTML templates.
*Django·Jinja·Nunjucks·Twig·Handlebars·Mustache·GoLang*
Ps, ``--check`` it out on other templates as well!
.. image:: /_static/demo.gif
|codecov| |test| |Codacy Badge| |Maintainability| |Downloads| |chat| |version|
.. note:: djLint is not an html parser or syntax validator.
Show your format
----------------
Add a badge to your projects `readme.md`:
.. code-block:: 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`:
.. code-block:: rst
.. image:: https://img.shields.io/badge/html%20style-djLint-blue.svg
:target: https://github.com/Riverside-Healthcare/djlint
Looks like this:
.. image:: https://img.shields.io/badge/html%20style-djLint-blue.svg
:target: https://github.com/Riverside-Healthcare/djlint
Contributing - Please Help!
---------------------------
Send a pr with a new feature, or checkout the `issue <https://github.com/Riverside-Healthcare/djlint/issues>`_ list and help where you can.
.. |codecov| image:: https://codecov.io/gh/Riverside-Healthcare/djlint/branch/master/graph/badge.svg?token=eNTG721BAA
:target: https://codecov.io/gh/Riverside-Healthcare/djlint
.. |test| image:: https://github.com/Riverside-Healthcare/djlint/actions/workflows/test.yml/badge.svg
:target: https://github.com/Riverside-Healthcare/djlint/actions/workflows/test.yml
.. |Codacy Badge| image:: https://app.codacy.com/project/badge/Grade/dba6338b0e7a4de896b45b382574f369
:target: https://www.codacy.com/gh/Riverside-Healthcare/djlint/dashboard?utm_source=github.com&utm_medium=referral&utm_content=Riverside-Healthcare/djlint&utm_campaign=Badge_Grade
.. |Maintainability| image:: https://api.codeclimate.com/v1/badges/5febe4111a36c7e0d2ed/maintainability
:target: https://codeclimate.com/github/Riverside-Healthcare/djlint/maintainability
.. |Downloads| image:: https://img.shields.io/pypi/dm/djlint.svg
:target: https://pypi.org/project/djlint/
.. |chat| image:: https://img.shields.io/badge/chat-discord-green
:target: https://discord.gg/taghAqebzU
.. |version| image:: https://img.shields.io/pypi/v/djlint
:target: https://pypi.org/project/djlint/
:alt: PyPI

View file

@ -1,35 +0,0 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

19829
docs/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,39 +1,57 @@
{
"name": "djlint",
"version": "0.6.8",
"description": "djlint HTML Template Linter and Formatter",
"main": " ",
"directories": {
"doc": "docs"
},
"name": "djlint_docs",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"start": "eleventy --serve --watch",
"install": "ELEVENTY_PRODUCTION=true eleventy",
"prepare": "husky install",
"test": "npm run test:eslint && npm run test:prettier",
"test:eslint": "eslint \"./**/*.js\" --color",
"test:prettier": "prettier --check ./**/*.js",
"format": "prettier --config .prettierrc \"src/**/*.{ts,css,less,scss,js}\" --write",
"updateSearch": "node ./src/search/update-algolia-index.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Riverside-Healthcare/djLint.git"
},
"keywords": [
"djlint",
"html",
"formatter",
"linter"
],
"keywords": [],
"author": "Christopher Pickering",
"license": "GPL-3.0-or-later",
"bugs": {
"url": "https://github.com/Riverside-Healthcare/djLint/issues"
},
"homepage": "https://github.com/Riverside-Healthcare/djLint#readme",
"license": "AGPL-3.0-or-later",
"browserslist": "> 2%, not dead",
"dependencies": {
"autoprefixer": "^10.4.0",
"@creativebulma/bulma-divider": "^1.1.0",
"@fontsource/rasa": "^4.5.3",
"@quasibit/eleventy-plugin-schema": "^1.0.0",
"@sindresorhus/slugify": "^2.1.0",
"animate-sass": "^0.8.2",
"eleventy-critical-css": "^1.0.0",
"md5": "^2.3.0"
},
"devDependencies": {
"@11ty/eleventy": "^0.12.1",
"@11ty/eleventy-img": "^1.0.0",
"@11ty/eleventy-plugin-syntaxhighlight": "^3.1.2",
"@fontsource/inter": "^4.5.0",
"@fortawesome/fontawesome-free": "^5.15.4",
"@fullhuman/postcss-purgecss": "^4.0.3",
"@toycode/markdown-it-class": "^1.2.4",
"algoliasearch": "^4.10.5",
"autoprefixer": "^10.3.1",
"bulma": "^0.9.3",
"cssnano": "^5.0.12",
"gulp": "^4.0.2",
"gulp-postcss": "^9.0.1",
"gulp-purgecss": "^4.1.3",
"gulp-sass": "^5.0.0",
"postcss-sort-media-queries": "^4.2.1",
"sass": "^1.44.0"
"bulma-pricingtable": "^0.2.0",
"cssnano": "^5.0.14",
"eleventy-plugin-metagen": "^1.4.0",
"esbuild": "^0.14.6",
"fontawesome-subset": "^3.0.0",
"html-minifier": "^4.0.0",
"markdown-it": "^12.3.0",
"markdown-it-anchor": "^8.3.0",
"markdown-it-div": "^1.1.0",
"markdown-it-imsize": "^2.0.1",
"outdent": "^0.8.0",
"postcss-cli": "^9.1.0",
"postcss-nested": "^5.0.6",
"prismjs": "^1.24.1",
"sass": "^1.45.1",
"slugify": "^1.6.4"
}
}

View file

@ -1,3 +0,0 @@
Sphinx
sphinx_copybutton
myst_parser

View file

@ -1,8 +0,0 @@
User-agent: *
Sitemap: https://djlint.com/sitemap.xml
Disallow: /_sources/
Disallow: /objects.inv
Disallow: /.buildinfo
Disallow: /.doctrees/

8
docs/src/_data/css.js Normal file
View file

@ -0,0 +1,8 @@
const path = require('path');
const generateContentHash = require('../lib/generateContentHash');
const hash = generateContentHash('src/static/**/*.{scss,css}');
module.exports = {
stylesCss: `/static/css/${hash}.css`,
};

View file

@ -0,0 +1,24 @@
module.exports = {
type: data => "page",
meta: {
site: {
name: data => data.site.title,
description: data => data.site.description,
url: data => data.site.url,
logo: {
src: data => data.site.image,
}
},
language: data => "en-US",
url: data => data.site.url + data.page.url,
title: data => data.title || data.site.title,
description: data => data.description || data.site.description,
image: {
src: data => data.page.image
},
modified: data => data.page.date.toISOString(),
keywords: data => data.keywords
}
};

8
docs/src/_data/js.js Normal file
View file

@ -0,0 +1,8 @@
const path = require('path');
const generateContentHash = require('../lib/generateContentHash');
const hash = generateContentHash('src/static/js/**/*.js');
module.exports = {
scriptsJs: `/static/js/${hash}.js`,
};

8
docs/src/_data/site.json Normal file
View file

@ -0,0 +1,8 @@
{
"description": "Find common syntax errors, reformat to make your HTML templates shine! Supports django, jinja, nunjucks, twig, handlebars, mustache, golang, and more!",
"image": "/static/img/icon.png",
"keywords": "djLint, template linting, template formatting, html template linting, django template, nunjucks template, jinja template",
"title": "HTML Template Linter and Formatter",
"name": "djLint",
"url": "https://www.djlint.com"
}

View file

@ -0,0 +1,46 @@
---
layout: layout.njk
---
<div class="container">
<div class="columns">
<div class="column is-narrow mr-5">
<aside class="menu is-sticky">
<!--<div id="search-wrap">
<form id="search-form"
class="mb-3"
style="position: relative;">
<div class="control has-icons-left is-flex-grow-1">
<span class="icon is-small is-left"><span class="icon">
<i class="fas fa-search"></i>
</span></span>
<input id="search"
class="input"
type="text"
label="search"
placeholder="search the docs ..."/>
</div>
<div id="search-results" class="panel has-background-white"></div>
</form>
</div>-->
<p class="menu-label">
Documentation
</p>
<ul class="menu-list">
<li><a class="{% if page.url == "/docs/getting-started/" %}is-active{% endif %}" href="/docs/getting-started/">Getting Started</a></li>
<li><a class="{% if page.url == "/docs/formatter/" %}is-active{% endif %}" href="/docs/formatter/">Formatter</a></li>
<li><a class="{% if page.url == "/docs/linter/" %}is-active{% endif %}" href="/docs/linter">Linter</a></li>
<li><a class="{% if page.url == "/docs/configuration/" %}is-active{% endif %}" href="/docs/configuration/">Configuration</a></li>
<li><a class="{% if page.url == "/docs/integrations/" %}is-active{% endif %}" href="/docs/integrations">Integrations</a></li>
<li><a class="{% if page.url == "/docs/best-practices/" %}is-active{% endif %}" href="/docs/best-practices/">Best Practices</a></li>
<li><a class="{% if page.url == "/docs/changelog/" %}is-active{% endif %}" href="/docs/changelog">Changelog</a></li>
</ul>
</aside>
</div>
<div class="column mb-5">
{{ content | safe }}
</div>
</div>

View file

@ -0,0 +1,20 @@
<footer class="footer">
<div class="container">
<div class="columns">
<div class="column is-one-third">
<figure class="image" style="max-width: 100px;">
{% image "./src/static/img/icon.png", "djlint icon", "(min-width:100px) 50vw, 100vw" %}
</figure>
<p class="my-4">
{{ site.description }}
</p>
</div>
<div class="column"></div>
<div class="column">
<p class="copyright has-text-grey">
djLint © 2021 Riverside Healthcare <br><br> Updated {{ page.date | niceDate }}
</p>
</div>
</div>
</div>
</footer>

View file

@ -0,0 +1,7 @@
---
layout: layout.njk
---
<div class="container">
{{ content | safe }}
</div>

View file

@ -0,0 +1,97 @@
<!DOCTYPE html>
<html lang="en" class="has-navbar-fixed-top">
<head>
{% block meta %}
{% metagen
title=(title or site.description) + " | " + site.name,
desc=desc or description or site.description,
url=site.url + page.url,
img=image or site.url + site.image,
img_alt=alt or "djlint logo",
twitter_card_type=type,
twitter_handle=twitter,
name="Riverside Healthcare / Christopher Pickering"
%}
{% endblock meta %}
<meta name="keywords"
content="{{ page.keywords or keywords or site.keywords }}"/>
<meta name="revised" content="{{ page.date.toISOString() }}" />
<meta property="og:locale" content="en_US" />
<meta property="article:author" content="Riverside Healthcare / Christopher Pickering" />
<meta name="robots" content="index,follow" />
<meta name="googlebot" content="index,follow" />
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<link rel="apple-touch-icon" href="/static/img/apple-touch-icon.png" />
<link rel="apple-touch-icon"
sizes="192x192"
href="/static/img/logo-192x192.png"/>
<link rel="apple-touch-icon"
sizes="512x512"
href="/static/img/logo-512x512.png"/>
<meta content="yes" name="apple-mobile-web-app-capable">
<meta name="apple-mobile-web-app-status-bar-style"
content="black-translucent">
<!-- critical css is inlined, so we can async the rest -->
<link rel="preload"
href="{{ css.stylesCss }}"
as="style"
onload="this.rel='stylesheet'"/>
<link rel="preload"
href="/static/font/inter/files/inter-latin-400-normal.woff2"
as="font"
type="font/woff2"
crossorigin/>
<link rel="preload"
href="/static/font/inter/files/inter-latin-600-normal.woff2"
as="font"
type="font/woff2"
crossorigin/>
<link rel="preload"
href="/static/font/inter/files/inter-latin-700-normal.woff2"
as="font"
type="font/woff2"
crossorigin/>
<link rel="preload"
href="/static/font/rasa/files/rasa-latin-500-normal.woff2"
as="font"
type="font/woff2"
crossorigin/>
<link rel="preload"
href="/static/font/rasa/files/rasa-latin-600-normal.woff2"
as="font"
type="font/woff2"
crossorigin/>
<link rel="preload"
href="/static/font/rasa/files/rasa-latin-700-normal.woff2"
as="font"
type="font/woff2"
crossorigin/>
<link rel="preload"
href="/static/font/fontawesome/webfonts/fa-brands-400.woff2"
as="font"
type="font/woff2"
crossorigin/>
<link rel="preload"
href="/static/font/fontawesome/webfonts/fa-regular-400.woff2"
as="font"
type="font/woff2"
crossorigin/>
<link rel="preload"
href="/static/font/fontawesome/webfonts/fa-solid-900.woff2"
as="font"
type="font/woff2"
crossorigin/>
{% jsonLdScript meta, type, tags %}
</head>
<body>
{% include "src/_includes/nav.njk" %}
<section class="is-flex-grow-1 main">
{% block body %}
{{ content | safe }}
{% endblock body %}
</section>
{% include "src/_includes/foot.njk" %}
<!--<script src="https://cdn.jsdelivr.net/npm/algoliasearch@4.5.1/dist/algoliasearch-lite.umd.js"></script>-->
<script src="{{ js.scriptsJs }}" async></script>
</body>
</html>

View file

@ -0,0 +1,72 @@
<nav class="navbar djlint-nav is-white is-fixed-top"
aria-label="main navigation">
<div class="container">
<div class="navbar-brand">
<a href="/">{% image "./src/static/img/icon.png", "djlint icon", "(min-width:600px) 50vw, 100vw" %}</a>
<a role="button"
class="navbar-burger"
aria-label="menu"
aria-expanded="false"
data-target="djlint-nav-menu">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div id="djlint-nav-menu" class="navbar-menu">
<div class="my-5 is-justify-content-center">
<a class="navbar-item has-text-grey" href="/docs/getting-started/">
Getting Started
</a>
<a class="navbar-item has-text-grey" href="/docs/formatter/">
Formatter
</a>
<a class="navbar-item has-text-grey" href="/docs/linter/">
Linter
</a>
<a class="navbar-item has-text-grey" href="/docs/configuration">
Configuration
</a>
<a class="navbar-item has-text-grey" href="/docs/integrations">
Integrations
</a>
<a class="navbar-item has-text-grey" href="/docs/best-practices">
Best Practices
</a>
</div>
<div class="navbar-end">
<a class="navbar-item button is-white animated fadeIn"
href="https://github.com/Riverside-Healthcare/djlint"
target="_blank"
rel="noopener">
<span class="icon is-large has-text-grey">
<i class="fab fa-2x fa-github"></i>
</span>
</a>
<a class="navbar-item button is-white animated fadeIn"
href="https://discord.gg/taghAqebzU"
target="_blank"
rel="noopener">
<span class="icon is-large has-text-grey">
<i class="fab fa-2x fa-discord"></i>
</span>
</a>
<a class="navbar-item button is-white animated fadeIn"
href="https://pypi.org/project/djlint/"
target="_blank"
rel="noopener">
<span class="icon is-large has-text-grey">
<i class="fab fa-2x fa-download"></i>
</span>
</a>
</div>
</div>
</div>
</div>
</nav>

View file

@ -0,0 +1,13 @@
const htmlmin = require("html-minifier");
module.exports = function(content, outputPath) {
if( outputPath.endsWith(".html") ) {
let minified = htmlmin.minify(content, {
useShortDoctype: true,
removeComments: true,
collapseWhitespace: true
});
return minified;
}
return content;
}

View file

@ -0,0 +1,24 @@
const esbuild = require('esbuild')
const generateContentHash = require('../lib/generateContentHash');
module.exports = class {
data() {
return {
permalink: `/static/js/${generateContentHash('src/static/js/**/*.js')}.js`,
eleventyExcludeFromCollections: true
}
}
async render() {
await esbuild.build({
entryPoints: ['src/static/js/search.js'],
inject: ['./src/static/js/hamburger.js','./src/static/js/animate.js','./src/static/js/modal.js'],
bundle: true,
minify: true,
outfile: `_site/static/js/${generateContentHash('src/static/js/**/*.js')}.js`,
sourcemap: false,
target: 'es5'
})
}
}

View file

@ -0,0 +1,38 @@
const util = require('util');
const sass = require('sass'); // `npm i -D sass`
const renderSass = util.promisify(sass.render);
const purgecss = require('@fullhuman/postcss-purgecss')
const postcss = require('postcss');
const generateContentHash = require('../lib/generateContentHash');
module.exports = class {
async data() {
return {
permalink: `/static/css/${generateContentHash('src/static/**/*.{scss,css}')}.css`,
eleventyExcludeFromCollections: true,
};
}
async render() {
const result = await renderSass({
file: 'src/static/css/site.scss',
});
return await postcss([
require('postcss-nested'),
purgecss({
content: ['./src/**/*.njk', './src/**/*.md'],
safelist: {
deep: [/zoomIn/, /fadeInUp/, /pre/,/code/,/block/, /box/, /title/, /is-\d/, /table/, /message/, /message-header/, /message-body/, /panel-block/, /p-3/, /is-block/, /is-justify-content-space-between/, /is-light/, /is-active/, /is-info/],
}
}),
require('autoprefixer'),
require('cssnano'),
])
.process(result.css, { from: undefined })
.then(result => result.css);
}
};

View file

@ -0,0 +1,64 @@
---
description: Best practices for using djLint to format HTML templates.
title: Best Practices
keywords: template linter, template formatter, djLint, HTML, templates, formatter, linter, best practices
---
# Best Practices
## Spaces Around Conditional Attributes
Sometimes conditions are used to add classes to a tag. djLint removes whitespace inside conditional statements.
This pattern is recommended:
{% raw %}
```html
<div class="class1 {% if condition -%}class2{%- endif %}">content</div>
^ space here
```
{% endraw %}
This pattern is not recommended:
{% raw %}
```html
<div class="class1{% if condition -%} class2{%- endif %}">content</div>
^ space here
```
{% endraw %}
## ``format_attribute_template_tags`` and Spaceless Conditional Attributes
If ``format_attribute_template_tags`` option is enabled, conditional attributes should use spaceless tags, for example {% raw %}`{% if a -%}`{% endraw %} in nunjuck and jinja, to remove spaces inside the.
djLint will format long attributes onto multiple lines, and the whitespace saved inside of attributes could break your code.
This pattern is recommended:
{% raw %}
```html
<input value="{% if database -%}{{ database.name }}{%- else -%}blah{%- endif %}"/>
^ ^ ^ ^-- spaceless tags
```
{% endraw %}
This pattern is not recommended:
{% raw %}
```html
<input value="{% if database %}{{ database.name }}{% else %}blah{% endif %}"/>
```
{% endraw %}
After formatting this could look like:
{% raw %}
```html
<input value="{% if database %}
{{ database.name }}
{% else %}
blah
{% endif %}"/>
```
{% endraw %}

View file

@ -1,103 +1,142 @@
:description: djLint Changelog. Find updates from recent releases and what feature you can expect on your next upgrade.
---
description: djLint Changelog. Find updates from recent releases and what feature you can expect on your next upgrade.
title: Changelog
keywords: template linter, template formatter, djLint, HTML, templates, formatter, linter, changelog
---
.. meta::
:title lang=en: Changelog | djLint
:description lang=en:
djLint Changelog. Find updates from recent releases and what feature you can expect on your next upgrade.
:keywords lang=en: template linter, template formatter, djLint, HTML, templates, formatter, linter, changelog
{% raw %}
Changelog
=========
# Changelog
0.6.9
-----
## Next Release
::: content
- Added config for custom HTML tags
- Bug fixes
:::
## 0.6.9
::: content
- Added HTML and Angular profiles
- Allowed some entities in rule #H023
- Bug fixes
:::
0.6.8
-----
## 0.6.8
::: content
- Bug fixes
- Updated docs
:::
0.6.7
-----
## 0.6.7
::: content
- Added config option ``format_attribute_template_tags`` as opt-in for template tag formatting inside of attributes
- Added config option ``linter_output_format`` to customize linter message variable order
- Added rules H030 and H031 to check meta tags
:::
0.6.6
-----
## 0.6.6
::: content
- Big fixes
:::
0.6.5
-----
## 0.6.5
::: content
- Updated output paths to be relative to the project root
- Bug fixes
:::
0.6.4
-----
## 0.6.4
::: content
- Bug fixes
:::
0.6.3
-----
## 0.6.3
::: content
- Added support for django `blocktrans` tag
- Bug fixes
:::
0.6.2
-----
## 0.6.2
::: content
- Bug fixes
:::
0.6.1
-----
## 0.6.1
::: content
- Bug fixes
- Made rule T028 stricter with clearer message
:::
0.6.0
-----
## 0.6.0
::: content
- Added rule T027 to check for unclosed in template syntax
- Added rule T028 to check for missing spaceless tags in attributes
- Added rule H029 to check for lowercase form method
- Ignored djagno blocktranslate tags that do not have "trimmed" from formatter
- Bug fixes
:::
0.5.9a
------
## 0.5.9a
::: content
- Added test support for python 3.10
- Added pre-commit hook
:::
0.5.9
-----
## 0.5.9
::: content
- Added option ``--use-gitignore`` to extend the excludes
- Changed default exclude matching
- Fixed windows exclude paths
- Fixed formatting of ``{%...%}`` tags in attributes
- Fixed formatting of `{%...%}` tags in attributes
- Fixed formatting for for loops and nested conditions in attributes
:::
0.5.8
-----
## 0.5.8
::: content
- Added require_pragma option
- Updated DJ018 to catch ``data-src`` and ``action`` on inputs
- Fixed inline ignore syntax
- Added ``--lint`` option as placeholder for default usage
- Bug fixes
:::
0.5.7
-----
## 0.5.7
::: content
- Bug fixes
:::
0.5.6
-----
## 0.5.6
::: content
- Added rule H026 to find empty id and class tags
- Bug fixes
:::
0.5.5
-----
## 0.5.5
::: content
- Consolidated settings and slimmed code
- Bug fixes
:::
0.5.4
-----
## 0.5.4
::: content
- Added rule H020 to find empty tag pairs
- Added rule H021 to find inline styles
- Added rule H022 to find http links
@ -112,13 +151,17 @@ Changelog
- Added srcset as possible url location in linter rules
- Speed up formatting
- Special thanks to `jayvdb <https://github.com/jayvdb>`_
:::
0.5.3
-----
## 0.5.3
::: content
- Change stdout for ``--reformat/check`` options to only print new html when using stdin as the input
:::
0.5.2
-----
## 0.5.2
::: content
- Split ``alt`` requirement from H006 to H013
- Added optional custom rules file
- Added ``golang`` as profile option
@ -128,113 +171,164 @@ Changelog
- Fixed file encoding on Windows OS
- Fix single line template tag regex
- Fix ``blank_line_after_tag`` for tags with leading space
:::
0.5.1
-----
## 0.5.1
::: content
- Added rule H019
- Fixed bugs in DJ018 and H012
:::
0.5.0
-----
## 0.5.0
::: content
- Fixed several regex matching bugs in linter rules
- Stopped linter from returning errors in ignored blocks
- Added option to ignore code block from linter/formatter with ``{% djlint:off %}...{% djlint:on %}`` tags
- Added option to ignore code block from linter/formatter with `{% djlint:off %}...{% djlint:on %}` tags
:::
0.4.9
-----
## 0.4.9
::: content
- Fixed bug `#35 <https://github.com/Riverside-Healthcare/djLint/issues/35>`_
:::
0.4.8
-----
## 0.4.8
::: content
- Fixed bug `#34 <https://github.com/Riverside-Healthcare/djLint/issues/34>`_
:::
0.4.7
-----
## 0.4.7
::: content
- Moved ``source`` tag to single line tags
:::
0.4.6
-----
## 0.4.6
::: content
- Fixed bug `#31 <https://github.com/Riverside-Healthcare/djLint/issues/31>`_
:::
0.4.5
-----
## 0.4.5
::: content
- Added best practices to docs
- Add ``--profile`` option to set default linter/formatter rules
- Added linter rules for jinja url patterns
:::
0.4.4
-----
## 0.4.4
::: content
- Change indent config from string to int. ``--indent 3``
:::
0.4.3
-----
## 0.4.3
::: content
- Added cli option for indent spacing. ``--indent=" "``
:::
0.4.2
-----
## 0.4.2
::: content
- Added support for additional whitespace after tags with ``blank_line_after_tag`` option
:::
0.4.1
-----
## 0.4.1
::: content
- Added support for processing several files or folders at once
:::
0.4.0
-----
- Fixed formatting of django ``{# ... #}`` tags
## 0.4.0
::: content
- Fixed formatting of django `{# ... #}` tags
- Added indent support for figcaption, details and summary tags
- Added support for overriding or extending the list of excluded paths in ``pyproject.toml``
:::
0.3.9
-----
## 0.3.9
::: content
- Updated attribute handling
:::
0.3.8
-----
## 0.3.8
::: content
- Added support for stdin
:::
0.3.7
-----
## 0.3.7
::: content
- Fixed formatting on ``small``, ``dt``, and ``dd`` tags
:::
0.3.6
-----
- Added formatter support for Nunjucks ``{%-`` opening blocks
## 0.3.6
0.3.5
-----
::: content
- Added formatter support for Nunjucks `{%-` opening blocks
:::
## 0.3.5
::: content
- Added support for more Django blocks
- Added support for custom blocks
- Added support for config in ``pyproject.toml``
:::
0.3.4
-----
## 0.3.4
::: content
- Fixed Nunjucks spaceless tag ``-%}`` format
:::
0.3.3
-----
## 0.3.3
::: content
- Allowed short ``div`` tags to be single line
:::
0.3.2
-----
## 0.3.2
::: content
- Fixed Django comment formatting
- Ignored textarea from formatting
:::
0.3.1
-----
## 0.3.1
::: content
- Updated attribute formatting regex
- Updated lint rule W010
:::
0.3.0
-----
## 0.3.0
::: content
- Changed exit code to 1 if there were any formatting changes
- Added support for Jinja ``asset`` tags
:::
0.2.9
-----
## 0.2.9
::: content
- Updated W018 regex
- Removed duplicate lint messages
- Updated E001 for Handlebars
:::
0.2.8
-----
## 0.2.8
::: content
- Fixed progress bar error for old Click version
:::
{% endraw %}

View file

@ -0,0 +1,207 @@
---
description: djLint configuration for HTML Template Linting and Formatting. Take advantage of the many formatter options.
title: Configuration
keywords: template linter, template formatter, djLint, HTML, templates, formatter, linter, configuration
---
# Configuration
Configuration is done through your projects `pyproject.toml` file. Command line args will always override any settings in `pyproject.toml`.
```ini
[tool.djlint]
<config options>
```
## ignore
Ignore linter codes.
Usage:
```ini
ignore="H014,H015"
```
## extension
Use to only find files with a specific extension.
Usage:
```ini
extension="html.dj"
```
## custom_blocks
Use to indent custom code blocks. For example {% raw %}`{% toc %}...{% endtoc %}`{% endraw %}
Usage:
```ini
custom_blocks="toc,example"
```
## custom_html
Use to indent custom HTML tags. For example ``<mjml>`` or ``<simple-greeting>`` or ``<mj-\w+>``
Usage:
```ini
custom_html="mjml,simple-greeting,mj-\\w+"
```
## indent
Use to change the code indentation. Default is 4 (four spaces).
Usage:
```ini
indent=3
```
## exclude
Override the default exclude paths.
Usage:
```ini
exclude=".venv,venv,.tox,.eggs,..."
```
## extend_exclude
Add additional paths to the default exclude.
Usage:
```ini
extend_exclude=".custom"
```
## blank_line_after_tag
Add an additional blank line after {% raw %}`{% <tag> ... %}`{% endraw %} tag groups.
Usage:
```ini
blank_line_after_tag="load,extends,include"
```
## profile
Set a default profile for the template language. The profile will disable linter rules that do not apply to your template language, and may also change reformatting. For example, in ``handlebars`` there are no spaces inside {% raw %}``{{#if}}``{% endraw %} tags.
Options:
:::content
- html
- django
- jinja
- nunjucks (for nunjucks and twig)
- handlebars (for handlebars and mustache)
- golang
- angular
:::
Usage:
```ini
profile="django"
```
## require_pragma
Only format or lint files that starts with a comment with only the text 'djlint:on'. The comment can be a HTML comment or a comment in the template language defined by the profile setting. If no profile is specified, a comment in any of the template languages is accepted.
Usage:
```ini
require_pragma=true
```
{% raw %}
```html
<!-- djlint:on -->
or
{# djlint:on #}
or
{% comment %} djlint:on {% endcomment %}
or
{{ /* djlint:on */ }}
or
{{!-- djlint:on --}}
```
{% endraw %}
## max_line_length
Formatter will attempt to put some html and template tags on a single line instead of wrapping them if the line length will not exceed this value.
Usage:
```ini
max_line_length=120
```
## max_attribute_length
Formatter will attempt to wrap tag attributes if the attribute length exceeds this value.
Usage:
```ini
max_attribute_length=10
```
## use_gitignore
Add .gitignore excludes to the default exclude.
Usage:
```ini
use_gitignore=True
```
## format_attribute_template_tags
Formatter will attempt to format template syntax inside of tag attributes. Disabled by default.
Usage:
```ini
format_attribute_template_tags=true
```
For example, with this option enabled, the following html will be acceptable:
```html
<input class="{% if this %}
then something neat
{% else %}
that is long stuff asdf and more even
{% endif %}"/>
```
## linter_output_format
Customize order of output message. Default="{code} {line} {message} {match}". If ``{filename}`` is not include in message, then the output will be grouped by file and a header will automatically be added to each group.
Usage:
```ini
# optional variables:
# {filename}
# {line}
# {code}
# {message}
# {match}
linter_output_format="{filename}:{line}: {code} {message} {match}"
```

3
docs/src/docs/docs.json Normal file
View file

@ -0,0 +1,3 @@
{
"layout": "docs_layout.njk"
}

131
docs/src/docs/formatter.md Normal file
View file

@ -0,0 +1,131 @@
---
description: Format your HTML Templates with djLint. Fast, accurate, output will make your templates shine.
title: Formatter Usage
keywords: template linter, template formatter, djLint, HTML, templates, formatter, linter, formatter usage
---
# Formatter Usage
djLint's formatter will take sloppy html templates and make the formatting consistent and easy to follow!
Formatting is a beta tool. ``--check`` the output before applying changes.
To review what may change in formatting run:
```bash
djlint . --check
```
To format the code and update files run:
```bash
djlint . --reformat
```
<div class="box notification is-info is-light">
<span class="icon is-large"><i class="fas fa-2x fa-arrow-circle-right"></i></span><div class="my-auto ml-3 is-inline-block"><a href="/docs/configuration/">Check out the configuration guide for all the options!</a></div>
</div>
{% admonition
"note",
"Note",
"Reformatting does not work with long json/html embedded into attribute data."
%}
{% admonition
"note",
"Note",
"djLint is not an html parser or syntax validator."
%}
## Ignoring Code
Code can be ignored by wrapping it in `djlint` tags:
{% raw %}
For plain old html -
```html
<!-- djlint:off -->
<bad html to ignore>
<!-- djlint:on -->
```
or as a comment -
```html
{# djlint:off #}
<bad html to ignore>
{# djlint:on #}
```
or as a long comment
```html
{% comment %} djlint:off {% endcomment %}
<bad html to ignore>
{% comment %} djlint:on {% endcomment %}
```
or as a javascript style comment -
```html
{{ /* djlint:off */ }}
<bad html to ignore>
{{ /* djlint:on */ }}
```
or as a golan style comment -
```html
{{!-- djlint:off --}}
<bad html to ignore>
{{!-- djlint:on --}}
```
{% endraw %}
## Here's an example!
### Before
Here's a blob of HTML that's in desperate need of attention -
{% raw %}
```
{% load admin_list %}{% load i18n %}<p class="paginator">{% if pagination_required %}{% for i in page_range %}{% paginator_number cl i %}{% endfor %}{% endif %}{{ cl.result_count }}{% if cl.result_count == 1 %}{{ cl.opts.verbose_name }} {% else %}{{ cl.opts.verbose_name_plural }} {% endif %}{% if show_all_url %} <a href="{{ show_all_url }}" class="showall">{% translate 'Show all' %} </a> {% endif %}{% if cl.formset and cl.result_count %}<input type="submit" name="_save" class="default" value="{% translate 'Save' %}">{% endif %} </p>
```
{% endraw %}
### After
It looks a bit better now... we can read it :)
{% raw %}
```html
{% load admin_list %}
{% load i18n %}
<p class="paginator">
{% if pagination_required %}
{% for i in page_range %}
{% paginator_number cl i %}
{% endfor %}
{% endif %}
{{ cl.result_count }}
{% if cl.result_count == 1 %}
{{ cl.opts.verbose_name }}
{% else %}
{{ cl.opts.verbose_name_plural }}
{% endif %}
{% if show_all_url %}
<a href="{{ show_all_url }}" class="showall">
{% translate 'Show all' %}
</a>
{% endif %}
{% if cl.formset and cl.result_count %}
<input type="submit" name="_save" class="default" value="{% translate 'Save' %}">
{% endif %}
</p>
```
{% endraw %}

View file

@ -0,0 +1,81 @@
---
description: Getting started with djLint for HTML Template Linting and Formatting. Take advantage of the easy cli interface and many formatter options.
title: Getting Started
keywords: template linter, template formatter, djLint, HTML, templates, formatter, linter, usage
---
# Getting Started
## Installation from [Pypi](https://pypi.org/project/djlint/)
djLint is build with [Python 3](https://python.org), it can be installed by simply running:
```bash
pip install djlint
```
## CLI Usage
djLint is a command line application. See `configuration` for advanced configuration.
```bash
Usage: python -m djlint [OPTIONS] SRC ...
djLint · lint and reformat HTML templates.
Options:
--version Show the version and exit.
-e, --extension TEXT File extension to check [default: html]
-i, --ignore TEXT Codes to ignore. ex: "H014,H017"
--reformat Reformat the file(s).
--check Check formatting on the file(s).
--indent INTEGER Indent spacing. [default: 4]
--quiet Do not print diff when reformatting.
--profile TEXT Enable defaults by template language. ops: django,
jinja, nunjucks, handlebars, golang
--require-pragma Only format or lint files that starts with a comment
with the text 'djlint:on'
--lint Lint for common issues. [default option]
--use-gitignore Use .gitignore file to extend excludes.
-h, --help Show this message and exit.
```
{% admonition
"note",
"Note",
"If the command `djlint` is not found, ensure sure that Python is [in your path](https://www.geeksforgeeks.org/how-to-add-python-to-windows-path/)."
%}
## Using Path vs Stdin
djLint works with a path or stdin.
Running with a path -
```bash
djlint /path/to/templates --lint
```
Or a specific file -
```bash
djlint /path/to/this.mustache --lint
```
Or with stdin -
```bash
echo "<div></div>" | djlint -
```
Stdin can also be used to reformat code. The output will be only the formatted code without messages.
```bash
echo "<div></div>" | djlint - --reformat
```
Output -
```html
<div></div>
```

View file

@ -1,84 +1,69 @@
:description: Integrate djLint with your favorite editor. Auto format your templates with Pre-Commit. Lint with SublimeText.
---
description: Integrate djLint with your favorite editor. Auto format your templates with Pre-Commit. Lint with SublimeText.
title: Integrations
keywords: template linter, template formatter, djLint, HTML, templates, formatter, linter, integrations
---
.. meta::
:title lang=en: Integrations | djLint
:description lang=en:
Integrate djLint with your favorite editor. Auto format
your templates with Pre-Commit. Lint with SublimeText.
:keywords lang=en: template linter, template formatter, djLint, HTML, templates, formatter, linter, integrations
Integrations
============
# Integrations
There are several editor integrations build for djLint.
Pre-Commit
----------
## Pre-Commit
djLint can be used as a `pre-commit <https://pre-commit.com>`_ hook.
djLint can be used as a [pre-commit](https://pre-commit.com) hook.
The repo provides multiple pre-configured hooks for specific djLint profiles (it just pre-sets the ``--profile`` argument and tells pre-commit which file extensions to look for):
::: content
* ``djlint-django`` for Django templates:
This will look for files matching ``templates/**.html`` and set ``--profile=django``.
* ``djlint-jinja``
This will look for files matching ``*.j2`` and set ``--profile=jinja``.
* ``djlint-nunjucks``
This will look for files matching ``*.njk`` and set ``--profile=nunjucks``.
* ``djlint-handlebars``
This will look for files matching ``*.hbs`` and set ``--profile=handlebars``.
* ``djlint-golang``
This will look for files matching ``*.tmpl`` and set ``--profile=golang``.
:::
Note that these predefined hooks are sometimes too conservative in the inputs they accept (your templates may be using a different extension) so pre-commit explicitly allows you to override any of these pre-defined options. See the `pre-commit docs <https://pre-commit.com/#pre-commit-configyaml---hooks>`_ for additional configuration
Default Django example
^^^^^^^^^^^^^^^^^^^^^^
### Default Django example
.. code:: yaml
```yaml
repos:
- repo: https://github.com/Riverside-Healthcare/djLint
rev: 0.5.10 # grab latest tag from GitHub
hooks:
- id: djlint-django
```
repos:
- repo: https://github.com/Riverside-Healthcare/djLint
rev: 0.5.10 # grab latest tag from GitHub
hooks:
- id: djlint-django
### Handlebars with .html extension instead of .hbs
Handlebars with .html extension instead of .hbs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code:: yaml
repos:
- repo: https://github.com/Riverside-Healthcare/djLint
rev: 0.5.10 # grab latest tag from GitHub
hooks:
- id: djlint-handlebars
files: "\\.html"
```yaml
repos:
- repo: https://github.com/Riverside-Healthcare/djLint
rev: 0.5.10 # grab latest tag from GitHub
hooks:
- id: djlint-handlebars
files: "\\.html"
```
You can use the ``files`` or ``exclude`` parameters to constrain each hook to its own directory, allowing you to support multiple template languages within the same repo.
SublimeText Linter
------------------
## SublimeText Linter
djLint can be used as a SublimeText Linter plugin. It can be installed via `package-control <https://packagecontrol.io/packages/SublimeLinter-contrib-djlint>`_.
djLint can be used as a SublimeText Linter plugin. It can be installed via [package-control](https://packagecontrol.io/packages/SublimeLinter-contrib-djlint).
::: content
1. ``cmd + shft + p``
2. Install SublimeLinter
3. Install SublimeLinter-contrib-djlint
:::
Ensure djLint is installed in your global python, or on yout ``PATH``.
coc.nvim
--------
## coc.nvim
https://www.npmjs.com/package/coc-htmldjango

View file

@ -0,0 +1,30 @@
---
title: Angular Template Linter
keywords: angular, djlint, angular template linter, lint angular templates
description: djLint is a angular template linter! Take advantage of the pre-build profile when linting and formatting your templates with djLint.
tool: angular
---
# {{ title }}
{{ description }}
#### Using the Command Line
```bash
djlint /path/to/templates --profile={{ tool }}
```
#### Or, Use a Config File
Configure djLint in your projects ``pyproject.toml``.
```toml
[tool.djlint]
profile="{{ tool }}"
```
<div class="box notification is-info is-light">
<span class="icon is-large"><i class="fas fa-2x fa-arrow-circle-right"></i></span><div class="my-auto ml-3 is-inline-block"><a href="/docs/configuration/">Check out the configuration guide for all the options!</a></div>
</div>

View file

@ -0,0 +1,30 @@
---
title: Django Template Linter and Formatter
keywords: django, djlint, django template linter, django template formatter, format django templates
description: djLint is a django template linter and a django template formatter! Take advantage of the pre-build profile when linting and formatting your templates with djLint.
tool: django
---
# {{ title }}
{{ description }}
#### Using the Command Line
```bash
djlint /path/to/templates --profile={{ tool }}
```
#### Or, Use a Config File
Configure djLint in your projects ``pyproject.toml``.
```toml
[tool.djlint]
profile="{{ tool }}"
```
<div class="box notification is-info is-light">
<span class="icon is-large"><i class="fas fa-2x fa-arrow-circle-right"></i></span><div class="my-auto ml-3 is-inline-block"><a href="/docs/configuration/">Check out the configuration guide for all the options!</a></div>
</div>

View file

@ -0,0 +1,30 @@
---
title: GoLang Template Linter and Formatter
keywords: GoLang, djlint, GoLang template linter, GoLang template formatter, format GoLang templates
description: djLint is a GoLang template linter and a GoLang template formatter! Take advantage of the pre-build profile when linting and formatting your templates with djLint.
tool: golang
---
# {{ title }}
{{ description }}
#### Using the Command Line
```bash
djlint /path/to/templates --profile={{ tool }}
```
#### Or, Use a Config File
Configure djLint in your projects ``pyproject.toml``.
```toml
[tool.djlint]
profile="{{ tool }}"
```
<div class="box notification is-info is-light">
<span class="icon is-large"><i class="fas fa-2x fa-arrow-circle-right"></i></span><div class="my-auto ml-3 is-inline-block"><a href="/docs/configuration/">Check out the configuration guide for all the options!</a></div>
</div>

View file

@ -0,0 +1,30 @@
---
title: Handlebars Template Linter and Formatter
keywords: handlebars, djlint, handlebars template linter, handlebars template formatter, format handlebars templates
description: djLint is a handlebars template linter and a handlebars template formatter! Take advantage of the pre-build profile when linting and formatting your templates with djLint.
tool: handlebars
---
# {{ title }}
{{ description }}
#### Using the Command Line
```bash
djlint /path/to/templates --profile={{ tool }}
```
#### Or, Use a Config File
Configure djLint in your projects ``pyproject.toml``.
```toml
[tool.djlint]
profile="{{ tool }}"
```
<div class="box notification is-info is-light">
<span class="icon is-large"><i class="fas fa-2x fa-arrow-circle-right"></i></span><div class="my-auto ml-3 is-inline-block"><a href="/docs/configuration/">Check out the configuration guide for all the options!</a></div>
</div>

View file

@ -0,0 +1,30 @@
---
title: Jinja Template Linter and Formatter
keywords: jinja, djlint, jinja template linter, jinja template formatter, format jinja templates
description: djLint is a jinja template linter and a jinja template formatter! Take advantage of the pre-build profile when linting and formatting your templates with djLint.
tool: jinja
---
# {{ title }}
{{ description }}
#### Using the Command Line
```bash
djlint /path/to/templates --profile={{ tool }}
```
#### Or, Use a Config File
Configure djLint in your projects ``pyproject.toml``.
```toml
[tool.djlint]
profile="{{ tool }}"
```
<div class="box notification is-info is-light">
<span class="icon is-large"><i class="fas fa-2x fa-arrow-circle-right"></i></span><div class="my-auto ml-3 is-inline-block"><a href="/docs/configuration/">Check out the configuration guide for all the options!</a></div>
</div>

View file

@ -0,0 +1,3 @@
{
"layout": "languages_layout.njk"
}

View file

@ -0,0 +1,30 @@
---
title: Mustache Template Linter and Formatter
keywords: mustache, djlint, mustache template linter, mustache template formatter, format mustache templates
description: djLint is a mustache template linter and a mustache template formatter! Take advantage of the pre-build profile when linting and formatting your templates with djLint.
tool: handlebars
---
# {{ title }}
{{ description }}
#### Using the Command Line
```bash
djlint /path/to/templates --profile={{ tool }}
```
#### Or, Use a Config File
Configure djLint in your projects ``pyproject.toml``.
```toml
[tool.djlint]
profile="{{ tool }}"
```
<div class="box notification is-info is-light">
<span class="icon is-large"><i class="fas fa-2x fa-arrow-circle-right"></i></span><div class="my-auto ml-3 is-inline-block"><a href="/docs/configuration/">Check out the configuration guide for all the options!</a></div>
</div>

View file

@ -0,0 +1,30 @@
---
title: Nunjucks Template Linter and Formatter
keywords: nunjucks, djlint, nunjucks template linter, nunjucks template formatter, format nunjucks templates
description: djLint is a nunjucks template linter and a nunjucks template formatter! Take advantage of the pre-build profile when linting and formatting your templates with djLint.
tool: nunjucks
---
# {{ title }}
{{ description }}
#### Using the Command Line
```bash
djlint /path/to/templates --profile={{ tool }}
```
#### Or, Use a Config File
Configure djLint in your projects ``pyproject.toml``.
```toml
[tool.djlint]
profile="{{ tool }}"
```
<div class="box notification is-info is-light">
<span class="icon is-large"><i class="fas fa-2x fa-arrow-circle-right"></i></span><div class="my-auto ml-3 is-inline-block"><a href="/docs/configuration/">Check out the configuration guide for all the options!</a></div>
</div>

View file

@ -0,0 +1,30 @@
---
title: Twig Template Linter and Formatter
keywords: twig, djlint, twig template linter, twig template formatter, format twig templates
description: djLint is a twig template linter and a twig template formatter! Take advantage of the pre-build profile when linting and formatting your templates with djLint.
tool: nunjucks
---
# {{ title }}
{{ description }}
#### Using the Command Line
```bash
djlint /path/to/templates --profile={{ tool }}
```
#### Or, Use a Config File
Configure djLint in your projects ``pyproject.toml``.
```toml
[tool.djlint]
profile="{{ tool }}"
```
<div class="box notification is-info is-light">
<span class="icon is-large"><i class="fas fa-2x fa-arrow-circle-right"></i></span><div class="my-auto ml-3 is-inline-block"><a href="/docs/configuration/">Check out the configuration guide for all the options!</a></div>
</div>

109
docs/src/docs/linter.md Normal file
View file

@ -0,0 +1,109 @@
---
description: djLint HTML Template linter includes over 30 rules! Find the definitions here. Easily expand with include custom rules!
title: Linter Rules
keywords: template linter, template formatter, djLint, HTML, templates, formatter, linter, rules
---
# Linter Usage
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.
```bash
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
```
<div class="box notification is-info is-light">
<span class="icon is-large"><i class="fas fa-2x fa-arrow-circle-right"></i></span><div class="my-auto ml-3 is-inline-block"><a href="/docs/configuration/">Check out the configuration guide for all the options!</a></div>
</div>
## Custom Rules
Create a file ``.djlint_rules.yaml`` alongside your ``pyproject.toml``. Rules can be added to this files and djLint will pick them up.
A good rule follows this pattern:
```yaml
- rule:
name: T001
message: Find Trichotillomania
flags: re.DOTALL|re.I
patterns:
- Trichotillomania
```
## Rules
| Code | Meaning |
|--------|---------------------------------------------------------------------------|
| T001 | Variables should be wrapped in a single whitespace. Ex: {% raw %}``{{ this }}``{% endraw %} |
| T002 | Double quotes should be used in tags. Ex {% raw %}``{% extends "this.html" %}``{% endraw %} |
| T003 | Endblock should have name. Ex: {% raw %}``{% endblock body %}``{% endraw %}. |
| D004 | (Django) Static urls should follow {% raw %}``{% static path/to/file %}``{% endraw %} pattern. |
| J004 | (Jinja) Static urls should follow {% raw %}``{{ url_for('static'..) }}``{% endraw %} 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 | Tag should be self closing. |
| D018 | (Django) Internal links should use the {% raw %}``{% url ... %}``{% endraw %} pattern. |
| J018 | (Jinja) Internal links should use the {% raw %}``{% url ... %}``{% endraw %} pattern. |
| 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 | Emtpy id and class tags can be removed. |
| T027 | Unclosed string found in template syntax. |
| T028 | Consider using spaceless tags inside attribute values. {% raw %}``{%- if/for -%}``{% endraw %} |
| H029 | Consider using lowercase form method values. |
| H030 | Consider adding a meta description. |
| H031 | Consider adding meta keywords. |
### Adding Rules
We welcome pull requests with new rules!
A good rule consists of
::: content
- Name
- Code
- Message - Message to display when error is found.
- Flags - Regex flags. Defaults to re.DOTALL. ex: re.I|re.M
- Patterns - regex expressions that will find the error.
- Exclude - Optional list of profiles to exclude rule from.
:::
Please include a test to validate the rule.
### Code Patterns
The first letter of a code follows the pattern:
::: content
- T: applies generally to templates
- H: applies to html
- D: applies specifically to Django
- J: applies specifically to Jinja
- N: applies specifically to Nunjucks
- M: applies specifically to Handlebars
:::

165
docs/src/index.njk Normal file
View file

@ -0,0 +1,165 @@
---
layout: layout.njk
date: Last Modified
---
{% block body %}
<div class="section">
<div class="container has-text-centered">
<h1 class="title huge mt-5">dj<span class="has-text-weight-light">&#8201;Lint</span></h1>
<h2 class="title is-2">
Lint & Format HTML Templates</h2>
<h2 class="title is-2 has-text-centered"></h2>
<p class="subtitle has-text-centered mb-5">find your favorite template language!
<div class="columns is-multiline">
<div class="column is-one-quarter">
<a class="is-block card animated" data-animate="fadeInUp" href="/docs/languages/django/">
<div class="card-content" >
<div class="content">
<figure class="image brand">
{% image "./src/static/img/logos/django.png", "django logo", "(min-width:300px) 50vw, 100vw" %}
</figure>
<h3 class="title is-4 my-0 is-uppercase has-text-weight-light is-family-sans-serif has-text-grey">Django</h3>
</div>
</div>
</a>
</div>
<div class="column is-one-quarter">
<a class="is-block card animated" data-animate="fadeInUp" href="/docs/languages/jinja/">
<div class="card-content">
<div class="content">
<figure class="image brand">
{% image "./src/static/img/logos/jinja.png", "jinja logo", "(min-width:300px) 50vw, 100vw" %}
</figure>
<h3 class="title is-4 my-0 is-uppercase has-text-weight-light is-family-sans-serif has-text-grey">jinja</h3>
</div>
</div>
</a>
</div>
<div class="column is-one-quarter">
<a class="is-block card animated" data-animate="fadeInUp" href="/docs/languages/nunjucks/">
<div class="card-content">
<div class="content">
<figure class="image brand">
{% image "./src/static/img/logos/nunjucks.png", "nunjucks logo", "(min-width:300px) 50vw, 100vw" %}
</figure>
<h3 class="title is-4 my-0 is-uppercase has-text-weight-light is-family-sans-serif has-text-grey">nunjucks</h3>
</div>
</div>
</a>
</div>
<div class="column is-one-quarter">
<a class="is-block card animated" data-animate="fadeInUp" href="/docs/languages/twig/">
<div class="card-content">
<div class="content">
<figure class="image brand">
{% image "./src/static/img/logos/twig.png", "twig logo", "(min-width:300px) 50vw, 100vw" %}
</figure>
<h3 class="title is-4 my-0 is-uppercase has-text-weight-light is-family-sans-serif has-text-grey">twig</h3>
</div>
</div>
</a>
</div>
<div class="column is-one-quarter">
<a class="is-block card animated" data-animate="fadeInUp" href="/docs/languages/handlebars/">
<div class="card-content">
<div class="content">
<figure class="image brand">
{% image "./src/static/img/logos/handlebars.png", "handlebars logo", "(min-width:300px) 50vw, 100vw" %}
</figure>
<h3 class="title is-4 my-0 is-uppercase has-text-weight-light is-family-sans-serif has-text-grey">handlebars</h3>
</div>
</div>
</a>
</div>
<div class="column is-one-quarter">
<a class="is-block card animated" data-animate="fadeInUp" href="/docs/languages/mustache/">
<div class="card-content">
<div class="content">
<figure class="image brand">
{% image "./src/static/img/logos/mustache.png", "mustache logo", "(min-width:300px) 50vw, 100vw" %}
</figure>
<h3 class="title is-4 my-0 is-uppercase has-text-weight-light is-family-sans-serif has-text-grey">mustache</h3>
</div>
</div>
</a>
</div>
<div class="column is-one-quarter">
<a class="is-block card animated" data-animate="fadeInUp" href="/docs/languages/golang/">
<div class="card-content">
<div class="content">
<figure class="image brand">
{% image "./src/static/img/logos/golang.png", "golang logo", "(min-width:300px) 50vw, 100vw" %}
</figure>
<h3 class="title is-4 my-0 is-uppercase has-text-weight-light is-family-sans-serif has-text-grey">golang</h3>
</div>
</div>
</a>
</div>
<div class="column is-one-quarter">
<a class="is-block card animated" data-animate="fadeInUp" href="/docs/languages/angular/">
<div class="card-content">
<div class="content">
<figure class="image brand">
{% image "./src/static/img/logos/angular.png", "angular logo", "(min-width:300px) 50vw, 100vw" %}
</figure>
<h3 class="title is-4 my-0 is-uppercase has-text-weight-light is-family-sans-serif has-text-grey">angular</h3>
</div>
</div>
</a>
</div>
</div>
</div>
</div>
<div class="container has-text-centered">
<h2 class="title is-2">Watch it run!</h2>
<figure class="image animated is-radius fadeInUp mx-auto" style="max-width:800px">
<img src="/static/img/demo.gif" alt="djlint html template formater demo">
</figure>
<h2 class="title is-2 mt-5">Show your format!</h2>
</div>
<div class="container">
Add a badge to your projects <code>readme.md</code>:
{% highlight "md" %}
[![Code style: djLint](https://img.shields.io/badge/html%20style-djLint-blue.svg)](https://github.com/Riverside-Healthcare/djlint)
{% endhighlight %}
Add a badge to your <code>readme.rst</code>:
{% highlight "md" %}
.. image:: https://img.shields.io/badge/html%20style-djLint-blue.svg
:target: https://github.com/Riverside-Healthcare/djlint
{% endhighlight %}
Looks like this:
<figure class="image" style="max-width:100px;"><img src="https://img.shields.io/badge/html%20style-djLint-blue.svg" alt="https://github.com/Riverside-Healthcare/djlint" /></figure>
</div>
<div class="container has-text-centered mb-5">
<h2 class="title is-2 mt-5">Contributing</h2>
<p class="has-text-left">
Contributions are welcome. Send a pr with a new feature, or checkout the <a href="https://github.com/Riverside-Healthcare/djlint/issues">issue</a> list and help where you can.</p>
</div>
</div>
{% endblock body %}

4
docs/src/robots.txt Normal file
View file

@ -0,0 +1,4 @@
Sitemap: https://www.atlas.bi/sitemap.xml
User-agent: *
Disallow: /cdn-cgi/

19
docs/src/search/all.njk Normal file
View file

@ -0,0 +1,19 @@
---
permalink: search/all.json
eleventyExcludeFromCollections: true
---
{%- set posts = collections.algolia -%}
[
{%- for post in posts -%}
{
"title": "{{ post.data.title | default(" ") }}",
"date": "{{ page.date }}",
"url": "{{ post.url }}",
"content": {{ post.templateContent | algExcerpt | jsonify | safe }},
"_tags": [{%- for tag in post.data.tags -%}"{{ tag }}"{%- if not loop.last -%},{% endif %}
{% endfor %}
]
}
{% if not loop.last %},{% endif %}
{% endfor %}
]

View file

@ -0,0 +1,11 @@
const algoliasearch = require("algoliasearch");
const objects = require("../../_site/search/all.json");
const client = algoliasearch('QFXNLHI6NP', process.env.ALGOLIA_SEARCH);
const index = client.initIndex('dev_atlas');
index.replaceAllObjects(objects, { autoGenerateObjectIDIfNotExist: true }).then(() => {
console.log("updated");
}).catch((error) => console.error("Failed to Algolia update index", error));

16
docs/src/sitemap.njk Normal file
View file

@ -0,0 +1,16 @@
---
permalink: /sitemap.xml
eleventyExcludeFromCollections: true
---
<?xml version="1.0" encoding="utf-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{%- for page in collections.all -%}
{%- if not page.data.draft %}
<url>
<loc>{{ site.url }}{{ page.url | url }}</loc>
<lastmod>{{ page.date.toISOString() }}</lastmod>
<changefreq>{{ page.data.changeFreq if page.data.changeFreq else "weekly" }}</changefreq>
</url>
{%- endif -%}
{%- endfor -%}
</urlset>

View file

@ -0,0 +1,527 @@
$link-hover:hsl(207, 61%, 53%);
$link: hsl(207, 61%, 53%);
@import "../../../node_modules/bulma/bulma";
@import "../../../node_modules/bulma-pricingtable/src/sass/index";
@import "../../../node_modules/@creativebulma/bulma-divider/src/sass/index";
$fontDir: "/static/font/inter/";
@import "../../../node_modules/@fontsource/inter/scss/mixins";
$use-all:true;
$use-slideInDown:true;
@import "../../../node_modules/animate-sass/animate";
@import "../font/fontawesome/stylesheet";
/* purgecss start ignore */
pre .tag {
align-items: unset;
background-color: unset;
border-radius: unset;
color: unset;
display: unset;
font-size: unset;
height: unset;
justify-content: unset;
line-height: unset;
padding-left: unset;
padding-right: unset;
white-space: unset;
}
@import "../../../node_modules/prismjs/themes/prism";
@include fontFace(
$fontName: Inter,
$weight: 400,
$display: swap,
$unicodeMap: latin,
$fontDir: "/static/font/inter/files/"
);
@include fontFace(
$fontName: Inter,
$weight: 600,
$display: swap,
$unicodeMap: latin,
$fontDir: "/static/font/inter/files/"
);
@include fontFace(
$fontName: Inter,
$weight: 700,
$display: swap,
$unicodeMap: latin,
$fontDir: "/static/font/inter/files/"
);
$fontDir: "/static/font/rasa/";
@import "../../../node_modules/@fontsource/rasa/scss/mixins";
@include fontFace(
$fontName: Rasa,
$weight: 300,
$display: swap,
$unicodeMap: latin,
$fontDir: "/static/font/rasa/files/"
);
@include fontFace(
$fontName: Rasa,
$weight: 500,
$display: swap,
$unicodeMap: latin,
$fontDir: "/static/font/rasa/files/"
);
@include fontFace(
$fontName: Rasa,
$weight: 600,
$display: swap,
$unicodeMap: latin,
$fontDir: "/static/font/rasa/files/"
);
@include fontFace(
$fontName: Rasa,
$weight: 700,
$display: swap,
$unicodeMap: latin,
$fontDir: "/static/font/rasa/files/"
);
html {
height: 100%;
}
body {
font-family: "Inter", Arial, Verdana, Tahoma, sans-serif;
display: flex;
flex-direction: column;
min-height: 100%;
}
.title {
font-family: "Rasa", Georgia, "Times New Roman", Times, serif;
}
.huge {
font-size:100px;
}
.djlint-nav {
padding-left: 15px;
}
.djlint-nav .navbar-brand a {
margin-top:auto;
margin-bottom:auto;
}
body.has-navbar-fixed-top, html.has-navbar-fixed-top {
padding-top:118px;
}
.djlint-nav .navbar-brand img {
width:auto;
height: 40px !important;
margin-top: 6px;
margin-bottom: -2px;
}
.is-flex-widescreen {
display:none !important;
}
@media screen and (min-width: $widescreen) {
.djlint-nav {
padding: 15px 0;
}
.djlint-nav .navbar-brand img {
height: 56px !important;
}
.is-flex-widescreen {
display: flex !important;
}
}
.image.brand {
height:200px;
}
.image.brand img {
max-width: 200px;
max-height:200px;
margin-top: 50%;
translate: 0 -50%;
}
a.navbar-item:hover,
a.navbar-link:hover,
.navbar-item.has-dropdown:hover .navbar-link {
background: transparent;
}
.hero-body {
background-color: rgba(167, 200, 204, 0.7);
}
.hero-two {
background-color: rgba(0, 68, 106, 0.08);
}
h1 {
font-size: 50px;
}
h2 {
font-size: 25px;
}
/* fix for prism in bulma */
pre .number {
background-color: inherit;
font: inherit;
padding: 0;
margin: 0;
height: inherit;
min-width: inherit;
text-align: inherit;
vertical-align: inherit;
}
.navbar-item.button {
margin: 13px;
margin-top: auto;
margin-bottom: auto;
}
.mail-icon > img {
margin-top:3px;
}
/* comparison */
.plan-item .icon {
height:auto;
}
.plan-item .icon svg {
height:15px;
width:15px
}
.pricing-table .pricing-plan .plan-group {
align-content: center;
background-color: #fff;
color: #4a4a4a;
font-size: $size-6;
font-weight: 600;
padding: .75em;
text-align: center;
}
.pricing-table .pricing-plan .plan-header {
font-size: $size-6;
}
.icon.is-huge {
height: 2.5em;
width: 2.5em;
}
/* search */
#search-form .icon svg {
height:1.2rem;
}
#search-results {
position:absolute;
top:70px;
left:0;
right:0;
display:none;
border-radius: $radius
}
#search-results:empty {
display: none !important;
}
#search:focus {
border-color: $info;
box-shadow: $input-focus-box-shadow-size bulmaRgba($info, 0.25);
}
#search:active {
border-color: $info;
box-shadow: $input-focus-box-shadow-size bulmaRgba($info, 0.25);
}
#search-wrap:focus-within #search-results
{
display:block;
box-shadow: $input-focus-box-shadow-size bulmaRgba($info, 0.25);
border: 1px solid $info;
}
#search-results:active {
display:block;
box-shadow: $input-focus-box-shadow-size bulmaRgba($info, 0.25);
border: 1px solid $info;
}
#search-results .panel-block:first-of-type {
border-top-left-radius: inherit;
border-top-right-radius: inherit;
}
#search-results em {
background-color: $info-light;
color: $info;
}
// tabs
.tab-container {
@extend %block
}
.tab-container .tab {
display:none
}
.tab-container .tab.is-active {
display:initial;
}
// admonitions
.message-header .icon svg {
height:$size-6;
padding-right:10px;
}
.message.note {
border-width:$message-body-border-width;
border-style:solid;
border-color: $info;
background-color:$white;
padding:0;
}
.message.hint {
border-width:$message-body-border-width;
border-style:solid;
border-color: $success;
background-color:$white;
padding:0;
}
.message.alert {
border-width:$message-body-border-width;
border-style:solid;
border-color: $danger;
background-color:$white;
padding:0;
}
.message.note .message-header {
color:$text;
background-color:$info-light;
}
.message.hint .message-header {
color:$text;
background-color:$success-light;
}
.message.alert .message-header {
color:$text;
background-color:$danger-light;
}
.message.note .message-body,
.message.hint .message-body,
.message.alert .message-body {
color:$text;
}
.image.is-35x35 {
height: 35px;
width: 35px;
}
/* menu collapse */
.is-collapsible, .is-collapsible.is-active {
transition: max-height 0.2s ease-out;
}
.is-collapsible {
max-height:0;
overflow:hidden;
margin-top:0;
margin-bottom:0;
}
.is-collapsible-menu {
height:0;
overflow: hidden;
margin-top:0;
margin-bottom:0;
}
.is-collapsible-menu.is-active {
height:auto;
}
.is-collapsible-menu:not(.is-active) {
margin-top:0 !important;
margin-bottom:0 !important;
}
.is-collapsible-menu .is-collapsible-menu {
margin-bottom:0 !important;
}
.menu .menu-label {
font-weight:600;
font-size: unset;
color: $grey-dark
}
.menu li a{
position: relative;
padding-left:20px;
}
.menu li a.is-active{
background:unset;
color: unset;
font-weight: 700;
}
.menu li.head > a {
font-weight: 600
}
.menu-list li.head ul {
margin-left:3px;
padding-left:20px;
}
.menu-list a:hover,
.menu li a:hover {
background-color: unset;
}
.menu li a:before {
position: absolute;
display: block;
margin-right:18px;
margin-left:-18px;
content: "";
}
.menu li a:not([data-action="collapse-menu"]):before {
height:4px;
width:4px;
border-radius:4px;
background: $grey;
top: calc(50% - 2px);
}
.menu li a[data-action="collapse-menu"]:before {
border: 2px solid $grey-light;
border-radius: 2px;
border-right: 0;
border-top: 0;
height: 7px;
margin-top: -.4375em;
transform-origin: 3px 4px;
width: 7px;
transition: transform .2s;
transform: rotate(-135deg);
top: calc(50% + 3px);
margin-left: -19px;
}
.menu li a.is-active[data-action="collapse-menu"]:before {
transform: rotate(-45deg);
transition: transform .2s;
}
pre {
margin-bottom: 1.5rem !important;
}
.column:not(.is-narrow) {
min-width:0px;
}
.is-inlineblock {
display: inline-block !important;
}
.is-radius > img {
border-radius: $radius
}
.hero.is-white .hero-body {
background-color: $white;
}
.hero {
position:relative
}
a.card:hover {
box-shadow: 0 .5em 2em -.125em #0a0a0a1a,0 0 0 1px #0a0a0a05;
}
.title {
color: $grey-darker;
}
@media screen and (min-width: $tablet) {
.is-sticky {
position: sticky;
top:118px;
bottom:0;
max-height: calc(100vh - 118px);
overflow-y: scroll;
}
}
@media screen and (min-width: $desktop){
.navbar.is-transparent a.is-info.navbar-item:hover {
background-color: $info-dark !important;
}
}
.navbar-item.button.is-white:hover {
background: transparent !important;
}
.is-256x256 {
max-height:256px;
max-width:256px;
}
@media screen and (max-width: $tablet) {
.main {
padding: 0 15px;
}
}
.animated[data-animate] {
visibility:hidden
}
.navbar-item .media img {
max-height:unset !important;
}
.icon.is-5x {
height:6rem;
width:6rem;
}
/* purgecss end ignore */
.navbar-item.is-mega {
position: static;
.is-mega-menu-title {
margin-bottom: 0;
padding: .375rem 1rem;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,160 @@
@use "sass:math";
@import "_variables";
$fa-font-path: "/static/font/fontawesome/webfonts";
/* from font awesome */
@font-face {
font-family: 'Font Awesome 5 Free';
font-style: normal;
font-weight: 400;
font-display: $fa-font-display;
src: url('#{$fa-font-path}/fa-regular-400.eot');
src: url('#{$fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'),
url('#{$fa-font-path}/fa-regular-400.woff2') format('woff2'),
url('#{$fa-font-path}/fa-regular-400.woff') format('woff'),
url('#{$fa-font-path}/fa-regular-400.ttf') format('truetype'),
url('#{$fa-font-path}/fa-regular-400.svg#fontawesome') format('svg');
}
.far, .fab {
font-family: 'Font Awesome 5 Free';
font-weight: 400;
}
@font-face {
font-family: 'Font Awesome 5 Free';
font-style: normal;
font-weight: 900;
font-display: $fa-font-display;
src: url('#{$fa-font-path}/fa-solid-900.eot');
src: url('#{$fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'),
url('#{$fa-font-path}/fa-solid-900.woff2') format('woff2'),
url('#{$fa-font-path}/fa-solid-900.woff') format('woff'),
url('#{$fa-font-path}/fa-solid-900.ttf') format('truetype'),
url('#{$fa-font-path}/fa-solid-900.svg#fontawesome') format('svg');
}
@font-face {
font-family: 'Font Awesome 5 Free';
font-style: normal;
font-weight: 400;
font-display: $fa-font-display;
src: url('#{$fa-font-path}/fa-brands-400.eot');
src: url('#{$fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'),
url('#{$fa-font-path}/fa-brands-400.woff2') format('woff2'),
url('#{$fa-font-path}/fa-brands-400.woff') format('woff'),
url('#{$fa-font-path}/fa-brands-400.ttf') format('truetype'),
url('#{$fa-font-path}/fa-brands-400.svg#fontawesome') format('svg');
}
.fa,
.fas {
font-family: 'Font Awesome 5 Free';
font-weight: 900;
}
// List Icons
// -------------------------
.#{$fa-css-prefix}-ul {
list-style-type: none;
margin-left: $fa-li-width * math.div(5,4);
padding-left: 0;
> li { position: relative; }
}
.#{$fa-css-prefix}-li {
left: -$fa-li-width;
position: absolute;
text-align: center;
width: $fa-li-width;
line-height: inherit;
}
// Icon Sizes
// -------------------------
// makes the font 33% larger relative to the icon container
.#{$fa-css-prefix}-lg {
font-size: math.div(4em, 3);
line-height: math.div(3em, 4);
vertical-align: -.0667em;
}
.#{$fa-css-prefix}-xs {
font-size: .75em;
}
.#{$fa-css-prefix}-sm {
font-size: .875em;
}
.#{$fa-css-prefix}-2_3x {
font-size: 2.3em;
}
@for $i from 1 through 10 {
.#{$fa-css-prefix}-#{$i}x {
font-size: $i * 1em;
}
}
// Base Class Definition
// -------------------------
.#{$fa-css-prefix},
.fas,
.far,
.fal,
.fad,
.fab {
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
display: inline-block;
font-style: normal;
font-variant: normal;
text-rendering: auto;
line-height: 1;
}
/* build icon list */
$icons: (
infinity: $fa-var-infinity,
search: $fa-var-search,
book: $fa-var-book,
project-diagram: $fa-var-project-diagram,
heart: $fa-var-heart,
address-card: $fa-var-address-card,
server: $fa-var-server,
database: $fa-var-database,
ship: $fa-var-ship,
code: $fa-var-code,
sitemap: $fa-var-sitemap,
chart-bar: $fa-var-chart-bar,
tasks: $fa-var-tasks,
sliders-h: $fa-var-sliders-h,
lock: $fa-var-lock,
compass: $fa-var-compass,
user: $fa-var-user,
users: $fa-var-users,
share: $fa-var-share,
discord: $fa-var-discord,
github: $fa-var-github,
envelope: $fa-var-envelope,
download: $fa-var-download,
sync-alt: $fa-var-sync-alt,
life-ring: $fa-var-life-ring,
pencil-alt: $fa-var-pencil-alt,
arrow-circle-right: $fa-var-arrow-circle-right,
);
@each $key, $value in $icons {
.#{$fa-css-prefix}-#{$key}:before {
content: fa-content($value);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

View file

Before

Width:  |  Height:  |  Size: 215 KiB

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 852 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View file

Before

Width:  |  Height:  |  Size: 705 KiB

After

Width:  |  Height:  |  Size: 705 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

View file

@ -0,0 +1,66 @@
(function () {
var debounce = function debounce(func, wait, immediate) {
var timeout;
return function () {
var context = this,
args = arguments;
var later = function later() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
var d = document,
load = function () {
[].forEach.call(d.querySelectorAll(".animated[data-animate]"), function (el) {
if (isInViewport(el)) {
// set image to nothing to clear, then load new
el.classList.add(el.getAttribute("data-animate"));
el.removeAttribute("data-animate");
}
});
};
var isInViewport = function isInViewport(elem) {
var bounding = elem.getBoundingClientRect(),
padding = 0;
return (
bounding.top >= 0 &&
bounding.left >= 0 &&
bounding.bottom - elem.clientHeight - padding <=
(document.documentElement.clientHeight ||
d.documentElement.clientHeight) &&
bounding.right - padding - elem.clientWidth <=
(document.documentElement.clientWidth || d.documentElement.clientWidth)
);
};
load();
d.addEventListener("lazy", function () {
setTimeout(function () {
load();
}, 0);
});
var resetHash = function(){
if(window.location.hash != ""){
history.pushState("", document.title, window.location.pathname + window.location.search);
}
}
d.addEventListener(
"scroll",
function () {
debounce(load(), 200);
debounce(resetHash(), 500);
}
);
})();

View file

@ -0,0 +1,16 @@
// Get all "navbar-burger" elements
var $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0); // Check if there are any navbar burgers
if ($navbarBurgers.length > 0) {
// Add a click event on each of them
$navbarBurgers.forEach(function (el) {
el.addEventListener('click', function () {
// Get the target from the "data-target" attribute
var target = el.dataset.target;
var $target = document.getElementById(target); // Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
el.classList.toggle('is-active');
$target.classList.toggle('is-active');
});
});
}

View file

@ -0,0 +1,46 @@
// Modals
var rootEl = document.documentElement;
var $modals = getAll('.modal');
var $modalButtons = getAll('.modal-button');
var $modalCloses = getAll('.modal-background, .modal-close, .modal-card-head .delete, .modal-card-foot .button');
if ($modalButtons.length > 0) {
$modalButtons.forEach(function ($el) {
$el.addEventListener('click', function () {
var target = $el.dataset.target;
var $target = document.getElementById(target);
rootEl.classList.add('is-clipped');
$target.classList.add('is-active');
});
});
}
if ($modalCloses.length > 0) {
$modalCloses.forEach(function ($el) {
$el.addEventListener('click', function () {
closeModals();
});
});
}
document.addEventListener('keydown', function (event) {
var e = event || window.event;
if (e.keyCode === 27) {
closeModals();
}
});
function closeModals() {
rootEl.classList.remove('is-clipped');
$modals.forEach(function ($el) {
$el.classList.remove('is-active');
});
}
// Functions
function getAll(selector) {
return Array.prototype.slice.call(document.querySelectorAll(selector), 0);
}

View file

@ -0,0 +1,101 @@
// var client = algoliasearch('QFXNLHI6NP', '6b5ccc86ead48e79e587963eeb2d83e8');
// var searchIndex = client.initIndex("dev_atlas");
// var searchBox = document.getElementById("search");
// var searchForm = document.getElementById("search-form");
// var runSearch = function(event) {
// var searchResultsContainer = document.getElementById("search-results");
// searchResultsContainer.textContent = "";
// var searchTerm = event.target.value;
// if (searchTerm.length < 2) return;
// var toolToFilterBy = event.target.dataset.filter || false;
// var alogliaArgs = {
// hitsPerPage: 10,
// attributesToRetrieve: ["title", "url", "_tags"],
// attributesToSnippet: ["content"],
// snippetEllipsisText: "…",
// };
// if (toolToFilterBy) alogliaArgs.filters = toolToFilterBy;
// searchIndex.search(searchTerm, alogliaArgs).then(function(e){
// results = e["hits"]
// console.log(results);
// var formattedResults = results.map(function(result){
// var toolName = extractToolName(result._tags);
// console.log(toolName)
// // Create elements
// var link = document.createElement("a");
// var title = document.createElement("strong");
// var excerpt = document.createElement("p");
// var tool = document.createElement("span");
// link.href = result.url;
// link.classList.add(
// "panel-block",
// "p-3",
// "is-block"
// );
// excerpt.classList.add("search-snippet");
// excerpt.innerHTML = result._snippetResult.content.value;
// title.classList.add("is-flex", "is-justify-content-space-between");
// title.innerText = result.title;
// tool.innerText = toolName;
// tool.classList.add(
// "tag",
// "is-info",
// "is-light"
// );
// // Put all the elements together
// title.appendChild(tool);
// link.appendChild(title);
// link.appendChild(excerpt);
// return link;
// });
// formattedResults.map(function(el){
// searchResultsContainer.insertAdjacentElement("beforeend", el)
// });
// });
// };
// var extractToolName = function(tags) {
// return tags.filter(function(tag){ return tag === "BI Library" || tag === "Automation Hub" || tag === "Atlas"});
// };
// Function.prototype.debounce = function (delay) {
// var outter = this,
// timer;
// return function () {
// var inner = this,
// args = [].slice.apply(arguments);
// clearTimeout(timer);
// timer = setTimeout(function () {
// outter.apply(inner, args);
// }, delay);
// };
// };
// if(searchBox != undefined || searchForm != undefined){
// searchBox.addEventListener("input", runSearch.debounce(250));
// searchForm.addEventListener("submit", (e) => e.preventDefault());
// }

BIN
icon.xcf Normal file

Binary file not shown.

15
tox.ini
View file

@ -55,18 +55,3 @@ deps =
commands =
pytest --cov=src/djlint --cov-branch --cov-report xml:coverage.xml --cov-report term-missing {posargs:}
skip_install: false
[testenv:docs]
changedir = docs
deps =
sphinx
myst-parser
sphinx_copybutton
sphinx-sitemap
commands =
sphinx-build -E -b dirhtml . _build
setenv =
PYTHONDONTWRITEBYTECODE=1
DEBUG=False
whitelist_externals =
rm