Расширение Jinja2 выводит экранированный html вместо html-тега
Я пытаюсь написать простую jinja2
расширение, которое сделает <meta>
тег на странице с некоторым свойством и содержанием attr. Это выглядит примерно так:
from jinja2 import nodes
from jinja2.ext import Extension
class MetaExtension(Extension):
"""
returns a meta tag of key, value
>> env = jinja2.Environment(extensions=[MetaExtension])
>> env.from_string('{% meta "key", "value" %}').render()
u'<meta property="keyword" content="value" />'
"""
# we'll use it in the template with
tags = set(['meta'])
def __init__(self, environment):
super(MetaExtension, self).__init__(environment)
def parse(self, parser):
tag = parser.stream.next()
args = [parser.parse_expression()]
if parser.stream.skip_if('comma'):
args.append(parser.parse_expression())
return nodes.Output([self.call_method('_render', args)]).set_lineno(tag.lineno)
def _render(self, *args):
return '<meta property="{}" content="{}" />'.format(args[0], args[1])
meta = MetaExtension
Используя это в приложении фляги:
# register the extension in the app file
from flask import Flask
app = Flask(__name__)
app.jinja_env.add_extension('flask_meta.MetaExtension')
А также
<!-- use it in the template -->
<head>
{% meta "key", "value" %}
</head>
Хотя тег прекрасно отображается в консоли, когда я использую его в приложении-колбе, он экранирует HTML и выводит экранированный тег на страницу. Итак, вместо
<meta property="keyword" content="value" />
я получил
<meta property="key" content="value" />
Что я делаю неправильно? Благодарю.
Обновление: см. Мой ответ ниже.
2 ответа
Оказывается, я должен был использовать nodes.CallBlock
вместо nodes.Output
, Применяя это изменение, parse
а также _render
функции теперь выглядят так:
...
def parse(self, parser):
tag = parser.stream.next()
args = [parser.parse_expression()]
if parser.stream.skip_if('comma'):
args.append(parser.parse_expression())
return nodes.CallBlock(self.call_method('_render', args),
[], [], []).set_lineno(tag.lineno)
def _render(self, value, name, *args, **kwargs):
return '<meta property="{}" content="{}" />'.format(value, name)
Надеюсь, это кому-нибудь поможет, так как справка по расширению Jinja2 (особенно для неблочных тегов) не так просто найти:)
Этот код производит...
<meta property="('this', 'that')" content="('this2', 'that2')" />
попробуй это...
from jinja2 import nodes
from flask import Flask
from jinja2.ext import Extension
app = Flask(__name__)
class MetaExtension(Extension):
"""
returns a meta tag of key, value
>> env = jinja2.Environment(extensions=[MetaExtension])
>> env.from_string('{% meta "key", "value" %}').render()
u'<meta property="keyword" content="value" />'
"""
# we'll use it in the template with
tags = set(['meta'])
def __init__(self, environment):
super(MetaExtension, self).__init__(environment)
def parse(self, parser):
tag = parser.stream.next()
args = [parser.parse_expression()]
if parser.stream.skip_if('comma'):
args.append(parser.parse_expression())
return nodes.Output([self.call_method('_render', args)]).set_lineno(tag.lineno)
def _render(self, *args):
return '<meta property="{0}" content="{1}" />'.format(args[0], args[1])
meta = MetaExtension
@app.route("/")
def index():
#return 'hi'
try:
return MetaExtension._render('', ("this", 'that') , ("this2", 'that2') )
except Exception as e:
print(str(e))
app.jinja_env.add_extension(meta)
if __name__ == "__main__":
app.run()
Надеюсь это поможет!