Как использовать операторы if else с несколькими блоками в шаблонах Django?
Я хочу загружать различные метатеги в зависимости от получаемых контекстных данных.
Как видите, в случае 1 я получаю имя из '2. name'
, а в случае 2 - из 'name'
. Когда я использую этот оператор if-else, я сталкиваюсь с ошибкой, говорящей о том, что использование нескольких блоков недопустимо.
{% extends 'base.html' %}
{% load static %}
{% load custom_filters %}
{% if context.api_name == 'case 1' %}
{% block meta_keywords %}
<meta name="keywords" content="some keywords">
{% endblock %}
{% block meta_description %}
<meta name="description" content="{{ context.json_data | get_key:'2. name' |default:'Unknown' }}">
{% endblock %}
{% elif context.api_name == "case 2" %}
{% block meta_keywords %}
<meta name="keywords" content="some keywords">
{% endblock %}
{% block meta_description %}
<meta name="description" content="{{ context.json_data | get_key:'name' |default:'Unknown' }}">
{% endblock %}
{% endif %}
TemplateSyntaxError
django.template.exceptions.TemplateSyntaxError: 'block' tag
with name 'meta_keywords' appears more than once
Попробуйте развернуть логику, например, так:
{% block meta_keywords %}
{% if context.api_name == 'case 1' %}
<meta name="keywords" content="some keywords">
{% elif context.api_name == "case 2" %}
<meta name="keywords" content="some keywords">
{% endif %}
{% endblock %}
{% block meta_description %}
{% if context.api_name == 'case 1' %}
<meta name="description" content="{{ context.json_data | get_key:'2. name' |default:'Unknown' }}">
{% elif context.api_name == "case 2" %}
<meta name="description" content="{{ context.json_data | get_key:'name' |default:'Unknown' }}">
{% endif %}
{% endblock %}
Я предполагаю, что content="some keywords"
в каждом случае будет разным.
Django's template parsing for the {% extends … %}
template tag [Django-doc] looks for all {% block … %}
template tags [Django-doc] and essentially it ignores all the rest.
Но писать такие {% if … %} … {% else %} … {% endif %}
блоки не имеет особого смысла: это плохой дизайн кода. В программном обеспечении такие проблемы решаются с помощью динамического связывания наследования, или ad-hoc полиморфизма. В шаблонах вы можете просто определить два шаблона:
case_1.html
{% extends 'base.html' %}
{% load static %}
{% load custom_filters %}
{% block meta_keywords %}
<meta name="keywords" content="some keywords">
{% endblock %}
{% block meta_description %}
<meta name="description" content="{{ context.json_data | get_key:'2. name' |default:'Unknown' }}">
{% endblock %}
case2.html
{% extends 'base.html' %}
{% load static %}
{% load custom_filters %}
{% block meta_keywords %}
<meta name="keywords" content="some keywords">
{% endblock %}
{% block meta_description %}
<meta name="description" content="{{ context.json_data | get_key:'name' |default:'Unknown' }}">
{% endblock %}
Представление может определять необходимый шаблон динамически, переопределяя .get_template_names()
[Django-doc]:
class MyTemplateView(TemplateView):
# …
def get_template_names(self):
if context.api_name == 'case 1':
return ('case_1.html',)
else:
return ('case_2.html',)