django-page-cmsは、を使用してこのタイプの問題を解決しdjango-mptt
たので、そこで行われている方法を確認することをお勧めします。
具体的には、ツリーメニューをレンダリングするためのテンプレートは、と呼ばれるカスタムテンプレートタグを介して再帰的に含まれpages_dynamic_tree_menu
ます。
これは複雑に聞こえるので(カスタムta-whaaa!)、もう少し詳しく説明します。
Page
inはdjango-page-cms
クラスとほぼ同じと見なすことができますSection
。
ページの99%で共有される基本テンプレートにdjango-page-cms
、次のスニペットを挿入します。
<ul>
{% for page in pages_navigation %}
{% pages_dynamic_tree_menu page %}
{% endfor %}
</ul>
pages_navigation
コンテキストプロセッサ(djangoプロジェクトのすべてのビューのテンプレートコンテキストにアイテムを追加する方法) によって設定され、トップレベルのページ(つまり、親のないページ)が含まれます。
タグは次のpages_dynamic_tree_menu
ように定義および登録されます。
def pages_dynamic_tree_menu(context, page, url='/'):
"""
Render a "dynamic" tree menu, with all nodes expanded which are either
ancestors or the current page itself.
Override ``pages/dynamic_tree_menu.html`` if you want to change the
design.
:param page: the current page
:param url: not used anymore
"""
lang = context.get('lang', pages_settings.PAGE_DEFAULT_LANGUAGE)
page = get_page_from_string_or_id(page, lang)
children = None
if page and 'current_page' in context:
current_page = context['current_page']
# if this node is expanded, we also have to render its children
# a node is expanded if it is the current node or one of its ancestors
if(page.tree_id == current_page.tree_id and
page.lft <= current_page.lft and
page.rght >= current_page.rght):
children = page.get_children_for_frontend()
context.update({'children': children, 'page': page})
return context
pages_dynamic_tree_menu = register.inclusion_tag(
'pages/dynamic_tree_menu.html',
takes_context=True
)(pages_dynamic_tree_menu)
page
その要点は、とchildren
変数を設定すること です。
魔法はif
ステートメントにあり、ページが現在のものである場合(current_page
テンプレート変数はdjango-page-cms
をレンダリングするビューによって設定されるPage
)、またはページが祖先である場合にのみ子が表示されるようにします。lft
&rght
属性はによって提供されdjango-mptt
、このMPTTの2つのプロパティは、親ツリーノードの左の値が子ノードの左の値よりも小さくなり、親ノードの右の値がの右の値よりも大きくなることです。その子ノード。SQLのツリーの記事から下の画像を見ると視覚的に確認できます。
未公開のオブジェクトを非表示にするためのフィルタリングを使用して呼び出すget_children_for_frontend()
メソッド。特別なことは何もありません。Page
MPTTModel.getChildren()
Page
次に、タグはテンプレートと同等のタグを実行します。これにより、タグが再度呼び出され、すべてが繰り返されます。{% include %}
pages/dynamic_tree_menu.html
pages_dynamic_tree_menu
{% load pages_tags cache %}
{% if page.calculated_status %}
<li {% ifequal page current_page %}class="selected"{% endifequal %}>
<a href="{% show_absolute_url page %}">{% show_content page "title" %}</a>
{% if children %}
<ul>{% for child in children %}{% pages_dynamic_tree_menu child url %}{% endfor %}</ul>
{% endif %}
</li>
{% endif %}
したがって、同様の設定を定義し(テンプレートに最上位のセクションと現在のセクションを提供し、「包括的」テンプレートタグとタグに一致するテンプレートを定義する)、スタイルを適用すると、このアプローチを使用して達成できるはずです。あなたの目標。