時間は、)HTMLを含んでいます、私はpresent
メソッドで直接HTMLマークアップで混乱したくありません。そこで私はPythonでメニュー定義を実装しました。これはJinjaのプレゼンテーションで、ギャップを橋渡しする相互再帰があります。メニュー項目の
異なるタイプは、異なるサブクラスで表される:上記参照
class MenuItem(object):
def present(self, macromap):
return macromap[type(self).__name__](self, macromap)
class TextLink(MenuItem):
def __init__(self, url, text):
self.url, self.text = url, text
class Section(MenuItem):
def __init__(self, text, items):
self.text, self.items = text, items
class ImageLink(MenuItem):
...
macromap
はrepresenationを実装マクロにメニュー項目のタイプをマッピングする辞書です。これは、すべての神社で定義されています:
{% macro TextLink(l, macromap) %}
<a class="menuitem" href="{{l.url|escape}}">
{{ l.text|escape }}
</a>
{% endmacro %}
{% macro Section(s, macromap) %}
<div class="heading">{{s.text}}</div>
<ul class="items">
{% for item in s.items %}
<li>{{ item.present(macromap) }}</li>
{% endfor %}
</ul>
{% endmacro %}
{% set default_map = {'TextLink': TextLink, 'Section': Section, ...}
実際のメニュー定義がきれいMenuItem
サブクラスの木のように表現されていますプレゼンテーションをキックオフするには
main_menu = section("Main Menu", [
section("Product Line 1", [
TextLink("/products/...", "A product"),
...
]),
section(...),
])
、テンプレートはトップレベルのセクションのを呼び出す必要がありますpresent
メソッドで、メニューを表示する方法を指定するマクロマップを渡します。 main_menu.present(default_map)
。 Section
マクロで最もよく分かるように、メニュー項目は、子どもたちに自分自身を提示するよう依頼することができ、present
メソッドは別のJinjaマクロを呼び出すなど、再帰的に呼び出すことができます。
マクロマップを明示的に渡すことはあまり美しいものではありませんが、メニューの定義に全く触れることなくメニューデータの表現を簡単に変えることができます。例えば、メインのウェブサイトメニューをレンダリングするためにマクロマップを定義したり、モバイルデバイス用のバリアント(CSSが不十分な場合)やXMLサイトマップ、またはプレーンテキストバージョンをレンダリングすることができます。 (実際には、このシステムをウェブサイトのメニューやサイトマップのケースに使用してしまいました)
多態性は実際にこの問題に役立ちます。しかし、プレゼンテーションにはHTMLが含まれていなければなりません。これは本当にJinjaテンプレートに分けておきたいものです。あなたの提案は、私が問題を解決するために必要な最後の手がかりを提供しました。 –