2016-09-08 33 views
0

私はJinja2を使用してjsonドキュメントを作成しようとしていますが、そのドキュメントにはネストされたスクリプトがあります。スクリプトには、{{<variables>}}が含まれています。非json文字と一緒に置き換える必要があります。したがって、後でjson.dumps()を使用してスクリプトをjson-escapする必要があります。jinja2:スクリプトを含み、{{変数}}を置き換え、結果をエンコードするjson

str = '{ "nestedScript" : {% include "scripts/sc.ps1" | json %} }'

完成した製品は、有効なHTMLではなく、JSON文字が含まれているためescape機能は、十分ではありません。

私はの線に沿って何かを考えている:カスタムフィルタか何かいくつかを使用して

str = '{ "nestedScript" : {{ include("scripts/sc.ps1") | json}} %} }'

、私はそれがまた、変数の置換を行うようにすることを含んで関数を書くように見えることはできませんスクリプト。これは、これまでのところ、私はグローバルとして含めていますというのが私のスクリプトです:

完全な例

フォルダ構造:

. 
└── templates 
    ├── test.json 
    └── scripts 
        └── script.ps1 

テンプレートファイル:

test.json = '{ 
    "nestedScript" : {{ include("scripts/script.ps1") | json}} 
}' 

スクリプト:

loader = jinja2.FileSystemLoader("templates") 
env = jinja2.Environment(loader=self.loader) 
template = env.get_template("test.json") 
template.render({ 
     'service_name': 'worker', 
     'context_name': 'googlesellerratings', 
    }) 

結果:

{ 
    "nestedScript" : "echo {{service_name}}" 
} 
+0

あなたが失敗した競合の例を与えることができますか? 'include()'関数が動作するためにはJSONを返さなければなりません。テンプレートが '{{...}}'プレースホルダーを持つテキストファイルである場合、その関数は置換を行う必要があります。次にそれを逆シリアル化して '| jsonフィルタを使用します。意味がないようです。 – BlackJack

+0

レンダリングを呼び出すときにテンプレートに提供されるコンテキスト変数を使用してレンダリングされていないのは、実際にはJSONのシリアル化ではありません。現在の例では、 '{{..}}'ブロックはレンダリングされず、どうやって安全なjsonに変換するのか分かりません。 – Paddie

+0

'scripts/script.ps1'の内容は、例と実際の結果が間違っているか、実際に望みたい結果が分からない場合があります。また、プログラムが完全ではなく、 'jinja2'のインポートがありません。未定義の' self'があり、テンプレートの結果は印刷されずに破棄されます。 – BlackJack

答えて

0

は少しハック感じている方法でこれを解決しましたので、私はいくつかのフィードバックを大好きです。

def render_script_func(env): 
    def render_script(name): 
     ctx = env.globals['context'] 
     tmpl = env.get_template(name) 
     raw = tmpl.render(ctx)    
     return json.dumps(raw) 
    return render_script 

を今すぐ:

loader = jinja2.FileSystemLoader(templates_folder) 
env = inja2.Environment(loader=self.loader) 

env.globals['include_script'] = render_script_func(env) 

render_script_funcが環境からコンテキストを取得し、私が参照されたファイルをレンダリングするためにそれを使用する関数を返します。私のクラスをインスタンス化するとき、私はinclude_scriptと呼ばれるグローバル関数を定義しました、レンダリングの前に、すべての1が関係している、グローバルcontextオブジェクトにレンダリングコンテキストを追加です:

template = env.get_template(template_name) 
template.environment.globals["context"] = ctx 
renderedData = template.render(ctx) 

テンプレートで{{ include_script("path/to/script") }}を使用すると、スクリプトはレンダリングされてからjsonエンコードされます。

まだ少し間違っているように感じますが、そうでもあります。

0

(不完全な)例を考えると、filterタグを検索しているようです。

まず、実際に実行可能だとjson.dumps()の面でjsonフィルタを定義して、フォーム内のスクリプト:

import json 
import jinja2 

loader = jinja2.FileSystemLoader('templates') 
env = jinja2.Environment(loader=loader) 
env.filters['json'] = json.dumps 
template = env.get_template('test.json') 
print(
    template.render({ 
     'service_name': 'worker', 
     'context_name': 'googlesellerratings', 
    }) 
) 

使用した場合JSONであるとして問題を起こす文字で不足しているPowerShellスクリプト("):

echo "{{service_name}}" 

test.jsonテンプレートのためのソリューション:

{ 
    "nestedScript" : {% filter json %}{% include "scripts/script.ps1" %}{% endfilter %} 
} 

そして最後に印刷された結果:

​​
関連する問題