質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.02%
Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

Pythonのjinja2テンプレートの中で文字列をフォーマットしようとするとエラーが出る

Alice1017
Alice1017

総合スコア24

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

2回答

0グッド

0クリップ

8913閲覧

投稿2017/08/18 02:44

編集2017/08/18 05:04

jinja2テンプレートの中で文字列をフォーマット

いまPythonでjinja2テンプレートを出力するプログラムを作っているのですが、jinja2テンプレートの中で文字列をフォーマットしようとすると、いろいろな問題が起きてしまったので質問します。

追記

質問がわかりにくかったようです。申し訳ございませんでした。
私の目的は Jinja2テンプレートファイルをgenerateする ことです。
生成するJinja2テンプレートファイルの内容は以下の通りです。

{%- set title="[main_title]" %} {%- set description="[description]" -%} {%- extends "outer.jinja2" -%} {% block breadcrumb %} <nav class="BreadCrumb" data-element="foundation"> <div class="bread-crumb-container" data-element="container"> <ol class="bread-crumb" data-grid="12" data-element="component" itemscope itemtype="http://schema.org/breadcrumblist"> <li class="crumb" itemprop="itemlistelement" itemscope itemtype="http://schema.org/listitem"> <a class="link" href="/" itemprop="item"> <span itemprop="name">top</span> </a> </li> <li class="crumb" itemprop="itemlistelement" itemscope itemtype="http://schema.org/listitem"> <a class="link" href="[parent_link]" itemprop="item"> <span itemprop="name">[parent]</span> </a> </li> <li class="crumb" itemprop="itemlistelement" itemscope itemtype="http://schema.org/listitem"> <a class="link" href="[link]" itemprop="item"> <span itemprop="name">[title]</span> </a> </li> </ol> </div> </nav> {% endblock %} {% block article %} <article class="main-contents" data-grid="9" data-element="component"> <header class="content-header" data-element="component"> <h3 class="entypo-chart-pie title">[title]</h3> </header> <section class="content-toc" data-element="component"> <h4 class="heading">目次</h4> <p class="title">[title]</p> <ul class="toc"> <li class="item"><a class="link" href="#"></a></li> </ul> </section> <section id="" class="content-article" data-element="component"> <h4 class="heading"></h4> <p class="sentence"></p> </section> <footer class="content-footer" data-element="component"> </footer> </article> </div> </main> {% endblock %}

この内容を生成したいがために [main_title] の部分をフォーマットする必要があるのです。

パターン1 {} の場合

{%- set title="{title}" -%}

このようなjinja2テンプレートを出力しようとすると、

py

1print "{%- set title='{title}' -%}".format(title=u"タイトル") 2 File "<console>", line 1 3 print "{%- set title="{title}" -%}".format(title=u"タイトル") 4 ^ 5SyntaxError: invalid syntax

jinja2テンプレートである{%- -%}部分をフォーマット文字列と勘違いしてInvarid Syntaxエラーが出てしまいます。

パターン2 %()s の場合

では古いバージョンのフォーマット文字列である%を使おうと考えました。

{%- set title="%(title)s" -%}

これを出力しようとすると、

py

1print "{%- set title='%(title)s' -%}" % {"title": u"タイトル"} 2Traceback (most recent call last): 3 File "<console>", line 1, in <module> 4TypeError: not enough arguments for format string

jinja2テンプレートである{%- -%}部分をフォーマット文字列と勘違いしてType Errorが出てしまいます。

このようにどうやってもエラーが出てしまいます。どのようにして文字列をフォーマットしたらよろしいのでしょうか…
ご教授ください。よろしくお願いいたします。

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答2

1

ベストアンサー

  • {{{}}}とエスケープする必要があります。
  • 書式指定文字列もunicode型である必要があります。(u"{~}"とする)

参考:7.1.3. 書式指定文字列の文法

書式指定文字列は波括弧 {} に囲まれた “置換フィールド” を含みます。波括弧に囲まれた部分以外は全て単純な文字として扱われ、変更を加えることなく出力へコピーされます。波括弧を文字として扱う必要がある場合は、二重にすることでエスケープすることができます: {{ および }} 。

Python

1#print "{{%- set title='{title}' -%}}".format(title=u"タイトル") 2# UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128) 3 4print u"{{%- set title='{title}' -%}}".format(title=u"タイトル")
{%- set title='タイトル' -%}

投稿2017/08/18 05:40

編集2017/08/18 05:42
can110

総合スコア36264

Alice1017👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

Alice1017

2017/08/21 01:11

僕が求めていた答えでした。ありがとうございました

0

質問にjinja2はまったく登場していないのですが、つまりこのようにして文字列を組み立てて、それからjinja2のテンプレートを生成したい、ということでしょうか?
テンプレートエンジンに渡す文字列を、より貧弱なテンプレートエンジンである%演算子やfomat関数で作るのはとても無駄に思うのですが。

あるいはjinja2の機能を勘違いしていないでしょうか。

素直にjinja2にやらせたら

Python

1from jinja2 import Template 2 3template = Template(u'''set title="{{title}}"''') 4print template.render(title=u'タイトル')

というコードで

set title="タイトル"

と出力する(出力させる)と思うのですが。


(追記)
jinja2で{%- -%}は、テンプレート用のデリミタではなくて、制御構造を記述するデリミタですよ。


(追記)
動機がまったく理解できないのですが、どうしてもというなら、私ならjinja2のraw stringを使って固定部分を記述してレンダリングさせますね。%演算子やformat関数にはそういったデリミタはないので、%%{{などと全部エスケープしてやらないといけないので。
以下はtitleだけ差し挟んだ場合です。

Python

1from jinja2 import Template 2 3template = Template(u"""{% raw %}{%- set title="[main_title]" %} 4{%- set description="[description]" -%} 5 6{%- extends "outer.jinja2" -%} 7 8{% block breadcrumb %} 9 10 <nav class="BreadCrumb" data-element="foundation"> 11 <div class="bread-crumb-container" data-element="container"> 12 <ol class="bread-crumb" data-grid="12" data-element="component" itemscope itemtype="http://schema.org/breadcrumblist"> 13 14 <li class="crumb" itemprop="itemlistelement" itemscope itemtype="http://schema.org/listitem"> 15 <a class="link" href="/" itemprop="item"> 16 <span itemprop="name">top</span> 17 </a> 18 </li> 19 20 <li class="crumb" itemprop="itemlistelement" itemscope itemtype="http://schema.org/listitem"> 21 <a class="link" href="[parent_link]" itemprop="item"> 22 <span itemprop="name">[parent]</span> 23 </a> 24 </li> 25 26 <li class="crumb" itemprop="itemlistelement" itemscope itemtype="http://schema.org/listitem"> 27 <a class="link" href="[link]" itemprop="item"> 28 <span itemprop="name">{% endraw %}{{ title }}{% raw %}</span> 29 </a> 30 </li> 31 32 </ol> 33 </div> 34 </nav> 35 36{% endblock %} 37 38{% block article %} 39 <article class="main-contents" data-grid="9" data-element="component"> 40 <header class="content-header" data-element="component"> 41 <h3 class="entypo-chart-pie title">{% endraw %}{{ title }}{% raw %}</h3> 42 </header> 43 44 <section class="content-toc" data-element="component"> 45 <h4 class="heading">目次</h4> 46 <p class="title">{% endraw %}{{ title }}{% raw %}</p> 47 <ul class="toc"> 48 <li class="item"><a class="link" href="#"></a></li> 49 </ul> 50 </section> 51 52 <section id="" class="content-article" data-element="component"> 53 <h4 class="heading"></h4> 54 <p class="sentence"></p> 55 </section> 56 57 <footer class="content-footer" data-element="component"> 58 </footer> 59 </article> 60 61 </div> 62 </main> 63{% endblock %}{% endraw %} 64""") 65print template.render(title=u'タイトル')

投稿2017/08/18 04:52

編集2017/08/18 05:19
quickquip

総合スコア10421

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

2017/08/18 05:15依頼された後にこの回答は修正されています

こちらの回答が他のユーザーから「過去の低評価」という指摘を受けました。

回答へのコメント

Alice1017

2017/08/18 05:01 編集

回答いただきありがとうございます。 私の書いた質問がわかりにくかったようです。申し訳ございません。 私がやりたいことは、Jinja2テンプレートをコンパイルすることではなく、他でコンパイルするためのJinja2テンプレートファイルを作成したいのです。 質問では略すために一行しか書かなかったのですが、本来の内容は以下のようになっています。 ``` {%- set title="[main_title]" %} {%- set description="[description]" -%} {%- extends "outer.jinja2" -%} {% block breadcrumb %} <nav class="BreadCrumb" data-element="foundation"> <div class="bread-crumb-container" data-element="container"> <ol class="bread-crumb" data-grid="12" data-element="component" itemscope itemtype="http://schema.org/breadcrumblist"> <li class="crumb" itemprop="itemlistelement" itemscope itemtype="http://schema.org/listitem"> <a class="link" href="/" itemprop="item"> <span itemprop="name">top</span> </a> </li> <li class="crumb" itemprop="itemlistelement" itemscope itemtype="http://schema.org/listitem"> <a class="link" href="[parent_link]" itemprop="item"> <span itemprop="name">[parent]</span> </a> </li> <li class="crumb" itemprop="itemlistelement" itemscope itemtype="http://schema.org/listitem"> <a class="link" href="[link]" itemprop="item"> <span itemprop="name">[title]</span> </a> </li> </ol> </div> </nav> {% endblock %} {% block article %} <article class="main-contents" data-grid="9" data-element="component"> <header class="content-header" data-element="component"> <h3 class="entypo-chart-pie title">[title]</h3> </header> <section class="content-toc" data-element="component"> <h4 class="heading">目次</h4> <p class="title">[title]</p> <ul class="toc"> <li class="item"><a class="link" href="#"></a></li> </ul> </section> <section id="" class="content-article" data-element="component"> <h4 class="heading"></h4> <p class="sentence"></p> </section> <footer class="content-footer" data-element="component"> </footer> </article> </div> </main> {% endblock %} ``` なので、今回の場合はJinja2でコンパイルすることはできないのです。
quickquip

2017/08/20 23:36

やはりどう考えても、やりたいことに対して馬鹿な手段、間違えた手段で解決しようとしているようにしか思えません。そんなことをしなければならない理由がまったくわかりません。

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.02%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。