djangoテンプレート:組み込みと拡張
-
05-07-2019 - |
質問
2つの異なるベースファイル内に同じコンテンツを提供したいと思います。
だから私はこれをやろうとしている:
page1.html:
{% extends "base1.html" %}
{% include "commondata.html" %}
page2.html:
{% extends "base2.html" %}
{% include "commondata.html" %}
問題は、extendsとincludeの両方を使用できないように見えることです。それを行う方法はありますか?そうでない場合、どうすれば上記を達成できますか?
commondata.htmlは、base1.htmlとbase2.htmlの両方で指定されたブロックをオーバーライドします
これの目的は、pdfとhtmlの両方の形式で同じページを提供することであり、形式はわずかに異なります。ただし、上記の質問は、問題を解決するという答えを得ることができれば、私がやろうとしていることを単純化します。
解決
extends templateタグを使用すると、現在のテンプレートは別のテンプレートを拡張している、つまり、親テンプレートに依存する子テンプレートであるということになります。 Djangoは子テンプレートを見て、そのコンテンツを使用して親にデータを取り込みます。
子テンプレートで使用するすべてのものは、Djangoが親の設定に使用するブロック内にある必要があります。その子テンプレートでincludeステートメントを使用したい場合は、Djangoがそれを理解できるように、ブロック内に配置する必要があります。それ以外の場合は意味がなく、Djangoはそれをどうするかわかりません。
Djangoのドキュメントには、親テンプレート内のブロックを置き換えるためにブロックを使用するいくつかの本当に良い例があります。
https://docs.djangoproject.com/en / dev / ref / templates / language /#template-inheritance
他のヒント
Django docsから:
includeタグは、「このサブテンプレートを解析し、親の一部であるかのようにコンテンツを含める」ではなく、「このサブテンプレートをレンダリングしてHTMLを含める」の実装と見なす必要があります。これは、含まれるテンプレート間で共有状態がないことを意味します-各インクルードは完全に独立したレンダリングプロセスです。
したがって、Djangoはcommondata.htmlからブロックを取得せず、ブロック外でレンダリングされたhtmlをどうするかを知りません。
これはあなたのためのトリックを行う必要があります:ブロックセクションの内側にインクルードタグを置きます。
page1.html:
{% extends "base1.html" %}
{% block foo %}
{% include "commondata.html" %}
{% endblock %}
page2.html:
{% extends "base2.html" %}
{% block bar %}
{% include "commondata.html" %}
{% endblock %}
将来の人々に役立つ場合に備えて、なぜ私にとって役に立たなかったのかについての詳細:
機能しなかった理由は、djangoの{%include%}は派手なアポストロフィのような特殊文字を好まないからです。含めようとしていたテンプレートデータは、単語から貼り付けられました。これらの特殊文字をすべて手動で削除する必要があり、その後正常に含まれました。
親テンプレートのブロックをオーバーライドするために、インクルードファイルから子テンプレートにブロックをプルすることはできません。ただし、変数で親を指定し、コンテキストでベーステンプレートを指定できます。
ドキュメントから:
{%extends variable%}は、変数の値を使用します。変数が文字列に評価される場合、Djangoはその文字列を親テンプレートの名前として使用します。変数がTemplateオブジェクトに評価される場合、Djangoはそのオブジェクトを親テンプレートとして使用します。
個別の" page1.html"の代わりにおよび" page2.html"を" commondata.html"の上部に {%extends base_template%}
を配置します。次に、ビューで、 base_template
を" base1.html"のいずれかに定義します。または" base2.html"。
グーグル経由でこれを見つけた将来の人々への参照用に追加:このような場合のためにメザニンライブラリによって提供される{%overextend%}タグを見たいかもしれません。
2015年12月10日編集:コメントで指摘されているように、 ssi はバージョン1.8以降廃止されました。ドキュメントによると:
このタグは廃止され、Django 1.10で削除されます。代わりにincludeタグを使用してください。
私の意見では、この質問に対する正しい(最良の)答えは、 podshumok からのものです。これは、継承とともに使用する場合のインクルードの動作の理由を説明しているためです。
しかし、Djangoテンプレートシステムが提供する ssi タグに言及していないことに驚きました。このタグは、の外部部分を含むインライン専用に設計されていますテキスト。ここで、インラインは、外部テキストが解釈、解析、または補間されるのではなく、単に「コピー」されることを意味します。呼び出しテンプレート内。
詳細については、ドキュメントを参照してください(ページの右下にあるセレクタで適切なバージョンのDjangoを確認してください)。
https://docs.djangoproject.com/en/ dev / ref / templates / builtins /#ssi
ドキュメントから:
ssi Outputs the contents of a given file into the page. Like a simple include tag, {% ssi %} includes the contents of another file – which must be specified using an absolute path – in the current page
この手法のセキュリティへの影響と、設定ファイルに追加する必要があるALLOWED_INCLUDE_ROOTS定義も注意してください。