В Jinja2, как я могу использовать макросы в сочетании с тегами блока? - PullRequest
10 голосов
/ 21 января 2010

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

Мой базовый шаблон содержит этот код (отредактировано для простоты):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
{% from "foo.html" import macro1, macro2, macro3 %}
{% macro base_template(title=none, arg2=none, urls={}, arg3=false) %}
<html>
  <title>{{ title }} | Site.com</title>
  ....
  {{ caller() }}
  ....
</html>
{% endmacro %}

{% block content %}{% endblock %}

А мои страницы, которые его расширяют, выглядят так:

{% extends "base.html" %}
{% block content %}
{% call base_template(title="home", arg2="active", arg3="true") %}
(html code here)
{% endcall %}
{% endblock %}

Таким образом, в основном все страницы расширяют базу, они вызывают макрос и передают аргументы этому макросу. Я не совсем все понимаю, но суть в том, что это допускает значения по умолчанию и степень гибкости, которая не требует переопределения целого блока: это дает некоторую степень гибкости и мощности. Опять же, это сильно упрощено.

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

{% block title %}<title>{{ title }} | Site.com</title>{% endblock %}

Сбой, потому что он скажет, что заголовок не определен.

В конечном итоге я ищу способ использовать как мощные, так и организационные аспекты блоков, но все же быть в состоянии использовать логику и краткость макросов. Если бы кто-нибудь мог мне помочь с решением этой проблемы, я был бы очень признателен.

1 Ответ

20 голосов
/ 21 января 2010

Блоки можно определить только на верхнем уровне шаблона. Если вы расширяете шаблон, любые значения, заданные в дочернем шаблоне с помощью тега set, будут доступны из шаблона, который он расширяет. Например, если у вас есть шаблон с именем layout.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
  <title>{{ title }} | Site.com</title>
  ....
  {% block content %}{% endblock content %}
  ....
</html>

И у вас есть этот дочерний шаблон, index.html:

{% extends "layout.html" %}
{% set title = 'Homepage' %}
{% block content %}
(html code here)
{% endblock content %}

Тогда ссылка на title в родителе преобразуется в 'Homepage'. Вы можете сделать это с любым типом переменной. Для того, что вы делаете, я не думаю, что есть необходимость в макросах - если вы воспользуетесь этой функцией и правильно разместите блоки, вы сможете сделать практически все, что вам нужно сделать, что касается макетов , Я хотел бы взглянуть на некоторые шаблоны, используемые Plurk Solace , написанные одним из авторов Jinja2, если вы хотите получить представление о том, когда использовать различные функции Jinja2.

...