Компилировать подраздел Jinja2 AST
-
29-09-2019 - |
Вопрос
Может ли один компилировать или вернуть часть jinja2 ast?
Например, можно ли вызвать функцию или метод от jinja2.environment
или jinja2.compiler.generate
Или какой-то эквивалент по списку узлов, извлеченных из шаблона?
Например, с учетом шаблона y.html
:
avant-tag
{% xyz %}
tag content {{ 3 + 5 }}
{% endxyz %}
apres-tag
и расширение y.py
:
# -*- coding: utf-8 -*-
from jinja2 import nodes, Environment, FileSystemLoader
from jinja2.ext import Extension
class YExtension(Extension):
tags = set(['y'])
def __init__(self, environment):
super(YExtension, self).__init__(environment)
def parse(self, parser):
tag = parser.stream.next()
body = parser.parse_statements(['name:endy'], drop_needle=True)
return nodes.Const("<!-- slurping: %s -->" % str(body))
env = Environment(
loader = FileSystemLoader('.'),
extensions = [YExtension],
)
print env.get_template('x.html').render()
Бег python y.py
Результаты в ожидаемом выходе:
avant-tag
<!-- slurping: [Output(nodes=[TemplateData(data=u'\n tag-content '),
Add(left=Const(value=3), right=Const(value=5)),
TemplateData(data=u'\n ')])] -->
sous-tag
в parse
Метод, как можно либо:
- компилировать
body
к Unicode (т.е.tag-content 8
); или, альтернативно - возвращаться
body
к его первоначальному источнику (т.е.tag-content {{ 3 + 5 }}
).
В качестве вещества этот вопрос относится к двум предыдущим вопросам:
- Рассылка с компиляцией Jinja2 после включения; и
- Вставьте JavaScript в верхней части, включая файл в Jinja 2
Спасибо за чтение.
Брайан
Решение
Компиляция Unicode еще не возможно в parse()
Способ, поскольку у вас нет контекста, доступного в этот момент. Вы можете взломать его, но это, вероятно, не будет лучшим способом пойти.
Обратите внимание, что то parse()
Шаг обычно выполняется только один раз в файле HTML, после этого он будет использовать анализируемый байт-код для рендера шаблона. Результаты шага анализа могут быть отображены с учетом среды.
У вас просто нет контекста, доступных там, и получить контекст там ... довольно сложно;)
Однако получить первоначальный источник ... не намного проще без взлома, но взлом не слишком плох;)
class YExtension(Extension):
tags = set(['y'])
def preprocess(self, source, name, filename=None):
# insert some code here that replaces '{% xyz %}foo bar{% endxyz %}'
# with something like: '{% xyz %}foo bar{% raw %}foo bar{% endraw %}{% endxyz %}'
return source
После этого вы можете прочитать текст как value
от {% raw %}
узел. Обязательно выберите его после этого, или он покажет в вашем шаблоне.