How can I use if else statements with multiple blocks in Django templates?

I want to load different meta tags based on the context data I receive.

As you can see, in case 1, I retrieve the name from '2. name', while in case 2, it comes from 'name'. When I use this if-else statement, I encounter an error stating that the use of multiple blocks is not allowed.

{% 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

Try turning the logic around, like:

{% 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 %}

I'm guessing that content="some keywords" will be different in each case.

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.

But it makes not much sense to write such {% if … %} … {% else %} … {% endif %} blocks: it is bad code design. In software, such problems are resolved by the dynamic binding of inheritance, or ad-hoc polymorphism. In templates, you can just define two templates:

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 %}

The view can determine the required template dynamically by overriding .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',)
Вернуться на верх