web-dev-qa-db-ja.com

Jinjaテンプレートの{%spaceless%}タグ?

Djangoには、HTMLから余分な空白を取り除く便利な{% spaceless %}タグがあります。

私のテンプレートは多くの空白を生成しており、空白を制御するために{%--%}をどこにでも追加するのは非常に面倒です。 Jinjaの{% spaceless %}、または{% htmltidy %}のようなフィルターを見たことがありますか?開発中にクリーンなHTMLを表示できますか?

29
a paid nerd

Jinja2開発者によって作成された、この効果を実現するjinja2拡張機能があります

https://github.com/mitsuhiko/jinja2-htmlcompress

20
Mr Hyde

インラインブロックレベルの要素を分離せずに印刷したい場合(たとえば、ブロックの流動的なグリッドをレンダリングする場合)にこの問題が発生しましたが、見栄えの良いマークアップが必要でした。

jinja2-htmlcompress HTMLタグ間だけでなく、jinjaタグと変数の間の空白も削除します。 {{ ' ' }}などの回避策または などのハードコードされたhtmlエンティティを使用する必要があるため、これは理想的ではありません。

coffin のスペースレスタグは理想的なソリューションのように見えますが、依存関係(Django)と多くの不要な機能が追加されています。

Djangoのスペースのないタグのみを使用したい場合は、棺桶から適応させた次のコードを使用できます。

jinja_extensions.py

# -*- coding: utf-8 -*-

from jinja2 import nodes
from jinja2.ext import Extension

import re


class SpacelessExtension(Extension):
    """
    Removes whitespace between HTML tags at compile time, including tab and newline characters.
    It does not remove whitespace between jinja2 tags or variables. Neither does it remove whitespace between tags
    and their text content.
    Adapted from coffin:
        https://github.com/coffin/coffin/blob/master/coffin/template/defaulttags.py
    """

    tags = set(['spaceless'])

    def parse(self, parser):
        lineno = parser.stream.next().lineno
        body = parser.parse_statements(['name:endspaceless'], drop_needle=True)
        return nodes.CallBlock(
            self.call_method('_strip_spaces', [], [], None, None),
            [], [], body,
        ).set_lineno(lineno)

    def _strip_spaces(self, caller=None):
        return re.sub(r'>\s+<', '><', caller().strip())

jinja2環境を定義する場所

extensions=['path.to.jinja_extensions.SpacelessExtension']

使用例

<style>
    *, *:before, *:after { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }
    .features {
        text-align: center;
    }
        .features div {
            display: inline-block;
            text-align: left;
            width: 25%;
            padding: 20px;
        }
        /* A style to help us identify the blocks */
        .features div:nth-child(odd) {
            background: #f5f5f5;
        }
    @media only screen and (max-width: 319px) {
        /* For small screens, display a single feature per line */
        .features div {
            width: 100%;
        }
    }
</style>
{% spaceless %} {# We remove whitespace between these inline-block tags without affecting the markup #}
<div class="features">
    <div>
        <h2>Feature 1</h2>
        <p>Content</p>
    </div>
    <div>
        <h2>Feature 2</h2>
        <p>Content</p>
    </div>
    <div>
        <h2>Feature 3</h2>
        <p>Content</p>
    </div>
    <div>
        <h2>Feature 4</h2>
        <p>Content</p>
    </div>
    <div>
        <h2>Feature 5</h2>
        <p>Content, second line on desktop</p>
    </div>
</div>
{% endspaceless %}

スペースのない結果

with

スペースのない結果(非表示の空白が4番目のブロックを次の行に移動したことに注意してください)

without

8
Joel Santirso

{% filter trim %}{% spaceless %}と同等です。

7
{% filter replace("\t", " ")|replace("    ", " ")|replace("   ", " ")|replace("  ", " ")|replace("\n ", "\n")|replace("\n\n", "\n") %}

これを使用して、複数のスペースを1つの区切り文字だけに置き換えます。ニースではありませんが、拡張なしで効率的です。

3
Filandre

私がやっている:

{% filter trim %}
... code ...
{% endfilter %}
1
Thomas Decaux