Я хочу знать, если это возможно, как проверить в javascript, изменился ли элемент или его атрибут?
Я означает что-то вроде window.onhashchange
для элемента вроде:
document.getElementById("element").onElementChange = function();
Насколько я знаю, onchange
- это что-то вроде этого, но будет ли это работать, если я хочу знать таким образом:
env = Environment (loader = FileSystemLoader ('.'))
template = env ....
В Jinja2 я хотел бы, чтобы следующее работало так, как должно работать, запустив:
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('.'))
template = env.get_template('x.html')
print template.render()
По сути, цель состоит в том, чтобы объединить весь javascript в
теги с использованием aa {% call js ()%} / * некоторого js * / {% endcall%}
макроса.
Some ... text ...
Фактические результаты не обнадеживают. Я получаю несколько типов потенциально важных ошибок, например:
TypeError: макрос 'js' не принимает аргумент ключевого слова 'вызывающий'
или, когда я пытаюсь добавить другой базовый макрос, такой как
{% macro js2() -%}
{%- block head_js -%}
// ... something
{%- endblock -%}
{%- endmacro %}
, я получаю следующее исключение
jinja2.exceptions.TemplateAssertionError: блок 'head_js' определено дважды
Мне кажется, что я столкнулся с проблемой дизайна, касающейся приоритета тегов блока
над тегами макроса
(т.е. макросы, похоже, не инкапсулируют теги блоков в так, как я ожидал).
Я полагаю, что мои вопросы довольно просты:
Может ли Jinja2 делать то, что я пытаюсь сделать? Если да, то как?
Если нет, существует ли другой шаблонизатор на основе Python, который поддерживает этот тип шаблонов (например, mako, genshi и т. Д.), Который без проблем работал бы в Google App Engine.
Спасибо за чтение - я ценю ваш вклад.
Брайан
Я пытаюсь написать расширение, чтобы решить эту проблему. Я на полпути - использую следующий код:
from jinja2 import nodes, Environment, FileSystemLoader
from jinja2.ext import Extension
class JavascriptBuilderExtension(Extension):
tags = set(['js', 'js_content'])
def __init__(self, environment):
super(JavascriptBuilderExtension, self).__init__(environment)
environment.extend(
javascript_builder_content = [],
)
def parse(self, parser):
"""Parse tokens """
tag = parser.stream.next()
return getattr(self, "_%s" % str(tag))(parser, tag)
def _js_content(self, parser, tag):
""" Return the output """
content_list = self.environment.javascript_builder_content
node = nodes.Output(lineno=tag.lineno)
node.nodes = []
for o in content_list:
print "\nAppending node: %s" % str(o)
node.nodes.extend(o[0].nodes)
print "Returning node: %s \n" % node
return node
def _js(self, parser, tag):
body = parser.parse_statements(['name:endjs'], drop_needle=True)
print "Adding: %s" % str(body)
self.environment.javascript_builder_content.append(body)
return nodes.Const('')
env = Environment(
loader = FileSystemLoader('.'),
extensions = [JavascriptBuilderExtension],
)
Это упрощает добавление Javascript в конец шаблона ... например,
{% js %}
some javascript {{ 3 + 5 }}
{% endjs %}
{% js %}
more {{ 2 }}
{% endjs %}
Running env.get_template ('x. Это не проблема.
Я рад, что добиваюсь прогресса, и я благодарен за информацию.
Я открыл связанный вопрос: Расширение компиляции Jinja2 после включения
Решение
class JavascriptBuilderExtension(Extension):
tags = set(['js'])
def __init__(self, environment):
super(JavascriptBuilderExtension, self).__init__(environment)
environment.extend(jbc = "",)
def parse(self, parser):
"""Parse tokens """
tag = parser.stream.next()
body = parser.parse_statements(['name:endjs'], drop_needle=True)
return nodes.CallBlock(
self.call_method('_jbc', [], [], None, None),
[], [], body
).set_lineno(tag.lineno)
def _jbc(self, caller=None):
self.environment.jbc += "\ntry { %s } catch (e) { ; };" % caller()
return ""
После завершения среда будет содержать переменную jbc
, которая содержит весь Javascript. Я могу вставить это, например, с помощью string.Template
.