Удаление разрывов строк из шаблона Django
У меня есть цикл в шаблоне, подобный этому
{% spaceless %}
{% for lang_code, lang_name in LANGUAGES %}
<link hreflang={{ lang_code }} href="#" onclick="location.href='http://example.com/
{% if lang_code|length > 2 %}
{{ some_path }}
{% else %}
{{ other_path }}
{% endif %}
'; return false;">
{% endfor %}
{% endspaceless %}
Что производит что-то вроде этого
<link hreflang="en-gb" href="#" onclick="location.href='http://example.com/
some_path/
'; return false;"><link hreflang="de" ...>
Можно ли перезаписать этот код так, чтобы весь тег был написан в одной строке?
<link hreflang="en-gb" href="#" onclick="location.href='http://example.com/some_path/'; return false;">
<link hreflang="de" href="#" onclick="location.href='http://example.com/other_path/'; return false;">
...
P.S. Это может быть достигнуто, если предложение if/else растянуто на одну строку, но тогда строка становится нечитаемой.
Ответы
Ответ 1
Тег spaceless
удаляет пробелы между тегами html, что невозможно сделать для удаления пробелов внутри тегов, как вы пытаетесь сделать.
Вы можете предотвратить появление новых строк, поставив предложение if/else на одну строку, но, как вы говорите, это затрудняет чтение. Это говорит мне о том, что вы пытаетесь сделать слишком много работы в шаблонах Django и что URL-адреса должны быть построены еще где.
Самый простой вариант - создать список тегов (language_code, url)
в представлении и пропустить их в шаблоне.
{% for lang_code, url in language_urls %}
<link hreflang={{ lang_code }} href="{{ url }}">
{% endfor %}
Если это не удобно сделать в представлении, еще пара опций:
- обработчик контекста шаблона (хорошо, если вы используете одни и те же URL-адреса в каждом представлении
- собственный тег/фильтр шаблона (хорошо, если
some_path
и other_path
являются динамическими)
Ответ 2
Мне нужно то же самое, потому что я использую шаблон для генерации строки темы сообщения (не HTML, поэтому {% spaceless %}
бесполезен). В моем случае шаблон принимал множество разных случаев, и все должно было быть написано в одной строке примерно на 500 символов.
Итак, в мышлении {% spaceless %}
я написал свой собственный {% linebreakless %}
:
import six
from django import template
from django.template.base import Node
from django.utils.functional import allow_lazy
register = template.Library()
@register.tag
def linebreakless(parser, token):
nodelist = parser.parse(('endlinebreakless',))
parser.delete_first_token()
return LinebreaklessNode(nodelist)
class LinebreaklessNode(Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
strip_line_breaks = allow_lazy(lambda x: x.replace('\n', ''), six.text_type)
return strip_line_breaks(self.nodelist.render(context).strip())
Обратите внимание, что он (намеренно!) сохраняет все пробелы, кроме разрывов строк.
Пример использования шаблона электронной почты будет выглядеть следующим образом: предполагается, что указанное выше загружено в модуль тега шаблона под названием linebreakless.py
:
{% load linebreakless %}{% linebreakless %}
{# Email subjects are (encoded) text, not HTML, so we don't need any autoescaping! #}
{% autoescape off %}
New Notification
•
{% if flag %}
about this
{% else %}
about that
{% endif %}
!
{% endautoescape %}
{% endlinebreakless %}
Обратите внимание, что тег {% linebreakless %}
должен находиться в первой строке (и после директив {% load %}
), чтобы предотвратить разрывы строк в сгенерированном файле.
Ответ 3
Альтернативой является использование шаблона Jinja2, который поддерживает Django начиная с версии 1.8. Из документации Jinja2 по управлению пробелами:
Если вы добавите знак минуса (-) в начало или конец блока (например, для тега), комментария или выражения переменной, пробелы до или после этого блока будут удалены:
{% for item in seq -%}
{{ item }}
{%- endfor %}
Преобразование шаблона из Django в Jinja2 не совсем просто. Возможно, это того стоит, если вы используете шаблон для создания текстового файла, а не файла HTML.