Создавайте макросы Jinja2, которые размещают контент в разных местах - PullRequest
3 голосов
/ 19 мая 2010

Я хочу создать оглавление и сноски в шаблоне Jinja2. Как можно решить эти задачи?

Например, я хочу иметь следующий шаблон:

 {% block toc %}
 {# ... the ToC goes here ... #}
 {% endblock %}

 {% include "some other file with content.jnj" %}

 {% block endnotes %}
 {# ... the endnotes go here ... #}
 {% endblock %}

Где some other file with content.jnj имеет такой контент:

{% section "One" %}
Title information for Section One (may be quite long); goes in Table of Contents
...
Content of section One

{% section "Two" %}
Title information of Section Two (also may be quite long)

<a href="#" id="en1">EndNote 1</a> 
<script type="text/javsacript">...(may be reasonably long)
</script> {# ... Everything up to here is included in the EndNote #}

Там, где я говорю «может быть довольно / достаточно долго», я имею в виду, что его нельзя поместить в кавычки в качестве аргумента для макроса или глобальной функции.

Мне интересно, есть ли шаблон для этого, который мог бы приспособиться к этому, в рамках Jinja2.

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

{% section "One" %}
Title information goes here.
{% endsection %}

{% endnote "one" %}
<a href="#">...</a>
<script> ... </script>
{% endendnote %}

Тогда есть глобальные функции (которые передаются в среде Jinja2):

{{ table_of_contents() }}

{% include ... %}

{{ endnotes() }}

Однако, хотя это будет работать для концевых сносок, я бы предположил, что для оглавления требуется второй проход чего-либо.

Спасибо, что прочитали. Я был бы очень признателен за ваши мысли и вклад.

Brian

1 Ответ

2 голосов
/ 16 августа 2010

Похоже, вы идете по правильному пути в определении согласованной структуры для каждого раздела (то есть заголовок, тело, сноски).Будет ли приемлемым хранение этой информации в обычных структурах данных Python, а не в блоках Jinja и / или пользовательских расширениях?Пример ниже.

в content.jnj:

{% set sections = [] %}
{% do sections.append({
'title': 'Section One title',
'body': 
"""
Section one main body text...
""",
'endnotes': 
"""
<a href='#'>...</a>
<script> ... </script>
""",
})
%}
{# append more sections #}

в template.jnj:

{% from 'content.jnj' import sections as sections %}
{# table of contents #}
{% for section in sections %}
    {{ loop.index }}. {{ section['title'] }}
{% endfor %}
{# body #}
{% for section in sections %}
    {{ section['title'] }}
    {{ section['body'] }}
{% endfor %}
{# endnotes #}
{% for section in sections %}
    {{ loop.index }}. {{ section['endnotes'] }}
{% endfor %}

Обратите внимание, что content.jnj требует расширения Jinja2 do длябыть включенным (например, env = jinja2.Environment(extensions=['jinja2.ext.do']).)

Это может быть излишним для ваших целей, но другой вариант - сохранить содержимое на языке разметки, например reStructuredText, и спроектировать уровень представления как Тема Sphinx (Jinja2 является форматом шаблона по умолчанию).

...