Шаблоны Django - могу ли я установить переменную, которая будет использоваться в родительском шаблоне?

У меня есть родительский шаблон, содержащий общее меню навигации. Я хочу добавить class="selected" в соответствующий пункт меню.

Я хочу иметь возможность установить переменную в дочернем шаблоне, например:

{% set menu = "products" %}

и выполните:

{%ifequal menu "products" %}class="selected"{% endifequal %}

Я не хочу устанавливать значение в представлении, потому что мне нужно было бы добавить это ко всем моим методам представления, и я не хочу повторять все меню html на каждой дочерней странице, потому что, если в меню изменений я хочу только для изменения HTML в одном месте.

Я подхожу к этому из "не-Django" умыслов?

Любая помощь будет действительно оценена. спасибо.

Ответ 1

Контекст, который вы передаете в своем представлении, также доступен в шаблонах, которые вы расширяете. Добавляя "menu_class": "selected" в контексте, вы можете установить

<div id="menu" class="{{ menu_class }}">

в базовом шаблоне.

Другой способ:

<div id="menu" class="mymenu {% block menu_attrib %}{% endblock %}">

который затем расширяется в вашем дочернем шаблоне

{% block menu_attrib %}selected{% endblock %}

Ответ 2

для записи, это считается плохой практикой... но вы можете это сделать

{% with "products" as menu %}
    {{ menu }}
{% endwith %}

Так как это фактически не решает вашу конкретную проблему, это возможное приложение...

<div class='menu'>
    {% block menuitems %}
        <a class='{% ifequal menu 'products' %}selected{% endifequal %}' href='/whereever/'>products</a>
        ...
    {% endblock %}
</div>

и в дочернем шаблоне

{% block menuitems %}
    {% with 'products' as menu %}
        {{ block.super }}
    {% endwith %}
{% endblock %}

Ответ 3

Здесь, конечно, более одного ответа!

Вы можете использовать собственные теги шаблонов для рисования меню и выбора подходящего.

Итак, ваш тег шаблона:

{% mymainmenu selecteditem %}

Посмотрите документацию по такому шаблону на сайте django, но в итоге получилось бы что-то вроде:

@register.simple_tag
def mymainmenu(selecteditem):

    html = ''

    build the html for the menu here and include selected class

    return html

Ответ 4

Спасибо всем - в конце я последовал за предложением говорящего и поместил имя текущего пункта меню в его контексте и воспользовался my:

{%ifequal menu "products" %}
    class="selected"
{% endifequal %}

в каждом меню opton.

Я не думаю, что это отличное решение, оно связывает мои "взгляды" с моими "шаблонами" больше, чем мне хотелось бы... но, возможно, это просто с django quirk