trans
変数をコンテキストからの値としてではなく、(コンテキストを使用せずに) html としてレンダリングすることにより、 の動作を拡張したいと思います。私の目標は、JavaScript を使用してクライアントにこれらの変数を入力できるようにすることです。
Jinja は、この種のカスタマイズを大幅に許可していないようです。または、適切なフックを見つけることができないだけです。
これが私が達成したいことです:
{% etrans name=username %}
My name is {{ name }}
{% endetrans %}
これは次のようにレンダリングする必要があります。
My name is <span id='#username'></span>
もちろん、通常の{% trans %}
ディレクティブを使用して自分の html コードを に渡すこともできますtemplate.render(html_code_params)
が、その場合、避けたいテンプレートとレンダリング コードでそれらを定義する必要があります。
これまでに得たもの (それほど多くはありません) は、新しいetrans
タグと、提供するあらゆるグッズを使用できる機能を可能InternationalizationExtension
にします。
from jinja2.ext import InternationalizationExtension
from jinja2.runtime import concat
class JavaScriptVariableExtension(InternationalizationExtension):
tagname = 'etrans'
tags = set([tagname])
def _parse_block(self, parser, allow_pluralize):
"""Parse until the next block tag with a given name.
Copy from InternationalizationExtension, as this uses hardcoded
`name:endtrans` instead of relying on tag name
"""
referenced = []
buf = []
while 1:
if parser.stream.current.type == 'data':
buf.append(parser.stream.current.value.replace('%', '%%'))
next(parser.stream)
elif parser.stream.current.type == 'variable_begin':
next(parser.stream)
name = parser.stream.expect('name').value
referenced.append(name)
buf.append('%%(%s)s' % name)
parser.stream.expect('variable_end')
elif parser.stream.current.type == 'block_begin':
next(parser.stream)
# can't use hardcoded "endtrans"
# if parser.stream.current.test('name:endtrans'):
if parser.stream.current.test('name:end%s' % self.tagname):
break
elif parser.stream.current.test('name:pluralize'):
if allow_pluralize:
break
parser.fail('a translatable section can have only one '
'pluralize section')
parser.fail('control structures in translatable sections are '
'not allowed')
elif parser.stream.eos:
parser.fail('unclosed translation block')
else:
assert False, 'internal parser error'
return referenced, concat(buf)
i18n_extended = JavaScriptVariableExtension
より多くのメソッドをオーバーロードしてもかまいません (ただし、上記の理由はおそらくアップストリームで修正する必要があります)。
コードをステップ実行することは、非常に興味深い冒険です。しかし、私は問題を抱えており、誰かがアドバイスをくれるかどうか興味があります.
私が見る問題は、コンパイル中に関数 context.resolve() がコンパイルされたコードに焼き付けられることです。jinja2.jinja2.compiler.CodeGenerator
ここで異なる処理を実際に許可することはありません (間違っている場合は修正してください)。理想的には、(変数用に) 別のノードを定義し、このノードがコンパイル中に処理される方法を処理しますが、これがどのように可能かわかりません。私は解決策としてこれに集中しすぎているかもしれないので、誰かが代替案を提供できるかもしれません。