元のスレッドから拡張された物語が続きます。
だから、私はPythonコード内でマクロを作成するための何かを持っています:
from flask import get_template_attribute
from jinja2 import Template
class InternalMacro(object):
"""
Creates a macro given a name, internal macro text, and content to fill(as namedtuple(t.var), dict(k,v), list(i), or other)
"""
def __init__(self, name = None,
text = None,
content_is = None):
self.name = name
self.macro_name = "{}_template".format(self.name)
self.macro_var = "{}_macro".format(self.name)
self.text = text
self.content_is = content_is
self.macro_txt = self.format_text
@property
def is_tuple(self):
return "{{% macro {0}(t) %}}{1}{{% endmacro %}}".format(self.macro_var, self.text)
@property
def is_dict(self):
return "{{% macro {0}(items) %}}{{% for k,v in items.iteritems() %}}{1}{{% endfor %}}{{% endmacro %}}".format(self.macro_var, self.text)
@property
def is_list(self):
return "{{% macro {0}(items) %}}{{% for i in items %}}{1}{{% endfor %}}{{% endmacro %}}".format(self.macro_var, self.text)
@property
def format_text(self):
return getattr(self, self.content_is)
@property
def return_template(self):
return Template(self.macro_txt)
@property
def return_callable(self):
return get_template_attribute(self.return_template, self.macro_var)
名前付きタプルを単独で、リストとして、またはdictとして渡します。これは、リストを渡す場合は機能しますが(dictとして完全にテストされていません)、単一の名前付きタプルを渡す場合は機能しません。これまでのところ、namedtupleはユニコードとしてエスケープされています。
そのように与えられた:
test_macro = InternalMacro('test', '{{ t }} <div id="divvy">{{ t.var }}</div>', 'is_tuple')
test_macro.return_callable(Anamedtuple)
戻り値:
u'Anamedtuple(var="A VAR VALUE") <div id="divvy"></div>'
いいえ:
u'Anamedtuple(var="A VAR VALUE")' <div id="divvy">A VAR VALUE</div>
これをリストとして実行すると、.varが正常に呼び出されます。
私が行方不明になっていることは何が起こっているのでしょうか。また、これを回避するにはどうすればよいですか。単一のnamedtupleはエスケープされますが、リストはエスケープされません。私はリストとして単一のものを行うことができ、最初のものをポップするだけで、多分私には汚れているように見えます。これを改善するための提案もありがたいです。
編集:
簡単な解決策は、すべてを渡されたリストに減らし、単一オプションとdictオプションを削除し、1つのリストを渡すことでした。それでも、そこで何が起こっているのかを正確に把握したいと思います。
EDIT2:
より深い調査は、namedtupleを出力する方法が、私が見ていた結果を生成することを示しました。
test_macro = InternalMacro('test', '{{ t }} <div id="divvy">{{ t.var }}</div>', 'is_tuple')
結果:
u'Anamedtuple(var="A VAR VALUE") <div id="divvy"></div>'
一方:
test_macro = InternalMacro('test', '<div id="divvy">{{ t.var }}</div>', 'is_tuple')
結果は
'<div id="divvy">A VAR VALUE</div>'
名前付きのタプルは一度読まれるのか……まあ、詳細な説明はありがたいです。