Как ссылаться на статические файлы в шаблоне handlebars-django

Резюме:

Как мне ссылаться на статические файлы в части handlebars в шаблоне django? Я могу использовать руль, если я использую verbatim теги, но тогда я не могу использовать Django static тег.

подробности

При преобразовании приложения в Django я натолкнулся на часть, которая использует handelbars.js для рендеринга ajax-call-результатов. Через, среди прочего, " Handlebars.js в шаблонах Django" я узнал о {% verbatim %} тег.

Простой кусок руля прекрасно работает с этим. Но у меня также есть часть, где изображения динамически отображаются на основе результата, который выглядит примерно так:

<img src="path/{{ result }}.png">

Теперь, когда это работает нормально, если я устанавливаю путь вручную, я считаю, что в Django хорошей практикой будет ссылаться на ваши статические файлы следующим образом:

<img src="{% static 'path/file.png' %}">

Просто получаю static_url константа не рекомендуется, см., например, этот блог

Поэтому, если у кого-то нет веской причины исправить это, я считаю, что лучше всего использовать {% static %} метод.

Наивным решением было бы объединить 2 техники и буквально распылить шаблон дословно / окончательно. Помимо того, что это выглядит некрасиво, неразборчиво и кажется плохой идеей с самого начала, оно также не работает.

{% verbatim %}
    <!-- handlebars -->
    {% endverbatim %}
    <img src="{% static 'path{% verbatim %}{{ result }}{% endverbatim %}' %}">
    {% verbatim %}
    <!-- handlebars -->
{% endverbatim %}

Это заканчивается слезами, как результат

TemplateSyntaxError at /
Не удалось разобрать остаток: ''path{%' from ''path{%'

Может быть возможно сгенерировать правильный статический URL на стороне бэкенда и отрендерить его. Но бэкэнд не должен знать, какое изображение мы хотим показать в шаблоне.

Единственное решение может заключаться в том, чтобы сделать дополнительный вызов к бэкэнду с помощью "относительной" строки (например, path/result.png) к бэкэнду, и попросить правильную статическую ссылку? Это не так сложно, но требует дополнительного вызова, что не должно быть.

Итак, как мне правильно ссылаться на эти статические файлы?

2 ответа

Решение

Вы не хотите разграничивать границы между тегами на руле и тегами Django. Возможно, самым чистым решением является явное объявление тегов на руле следующим образом:

{{ "handlebars_variable"|handlebars }}

где фильтр handlebars определяется как так ( источник):

from django import template
register = template.Library()

@register.filter
def handlebars(value):
    # str.format would require ugly escaping, so we use '%'
    return '{{%s}}' % value

Но этого недостаточно: вы хотите передать тег руля static и даже с фильтром вы не можете сделать это напрямую. Но, возможно, вы могли бы попробовать использовать с:

{% with "handlebars_variable"|handlebars as handlebars_tag %}
  <img src="{% static handlebars_tag %}">
{% endwith %}

Но даже этого недостаточно. Вы хотите подготовить path/, Есть несколько вариантов для вас:

  • Вы могли бы использовать add фильтр на основе этого ответа и вложенный with заявления (тьфу).
  • Вы можете определить тег шаблона с именем setvar как здесь сделано (если хотите).
  • Вы можете определить специальный тег шаблона как этот (возможно, не элегантный):

    @register.filter
    def static_result_path(value):
        return 'result/{{%s}}' % value   
    

    а затем измените код шаблона на:

    <img src="{% static "handlebars_variable"|static_result_path %}">
    
  • использование get_static_prefix (простейший!):

    <img src="{% get_static_prefix %}result/{{ "handlebars_variable"|handlebars }}" />
    
  • (И всегда есть Джинджа.)

Хотя шаблоны django не поддерживают какой-либо escape-символ, они поддерживают тег templatetag, который позволяет встраивать специальный текст в этом случае.

Предполагая, что у вас не слишком много замен рулей, вы можете просто сделать что-то вроде этого по мере необходимости:

<img src="{% get_static_prefix %}path/{% templatetag openvariable %} result {% templatetag closevariable %}.png" />

Однако, если у вас есть много замен, использование пользовательского фильтра в соответствии с ответом yarthathrock является более кратким и, следовательно, его легче поддерживать в долгосрочной перспективе.

Другие вопросы по тегам