私のニーズにあっては、これに対する簡単な解決策はありませんでした。ですから、私がこれについてどのように行ったかの例を共有したいのですが、説明が欠落している可能性があります。ご不明な点がございましたら、お返事ありがとうございます。
これはしばらくの間苦労しましたが、ツリーをトラバースする方法が簡単な場合もありますが、私はニーズが拡大したので次の方法を構築しました。これにより、サイトのすべてのライブページをトラバースし、現在のページがいつメニューでレンダリングされているかを確認し、レンダリングを細かく制御することができます。ここで
、これは我々がする必要があることを意味:
{% load demo_tags %}
- コール
{% top_menu calling_page=self %}
には、サイトのルートのすべて 直接の子を取得し、レンダリングし、当社のカスタムテンプレートタグをインポートします。これらは、標準メニューバーに表示されるアイテムです。
- コール
{% top_menu_children parent=menuitem %}
に{% top_menu %}
によってレンダリングテンプレート 内のすべての2次と 下位レベルの子ページを取得し、レンダリングします。これは、親のメニュー項目をホバリングするときに表示されるすべてのメニュー項目を網羅しています。
ここにカスタムdemo_tagsがあります。pyファイルページ階層のすべてのレベルをトラバースするために作成しました。これの美しさは、カスタムコンテキストデータを提供する必要がないことです。それはWagtailと一緒に箱から出ます!
- サイトのルートが
{% get_site_root %}
- 第1レベルの子によって呼び出され
{% top_menu %}
- 2次と小文字によって呼び出されます。本質的には
@register.assignment_tag(takes_context=True)
def get_site_root(context):
'''
Returns a core.Page, not the implementation-specific model used
so object-comparison to self will return false as objects would differ
'''
return context['request'].site.root_page
def has_menu_children(page):
'''
Returns boolean of whether children pages exist to the page supplied
'''
return page.get_children().live().in_menu().exists()
@register.inclusion_tag('info_site/tags/top_menu.html', takes_context=True)
def top_menu(context, parent, calling_page=None):
'''
Retrieves the top menu items - the immediate children of the parent page
The has_menu_children method is necessary in many cases. For example, a bootstrap menu requires
a dropdown class to be applied to a parent
'''
root = get_site_root(context)
try:
is_root_page = (root.id == calling_page.id)
except:
is_root_page = False
menuitems = parent.get_children().filter(
live=True,
show_in_menus=True
).order_by('title')
for menuitem in menuitems:
menuitem.show_dropdown = has_menu_children(menuitem)
return {
'calling_page': calling_page,
'menuitems': menuitems,
'is_root_page':is_root_page,
# required by the pageurl tag that we want to use within this template
'request': context['request'],
}
@register.inclusion_tag('my_site/tags/top_menu_children.html', takes_context=True)
def top_menu_children(context, parent, sub=False, level=0):
''' Retrieves the children of the top menu items for the drop downs '''
menuitems_children = parent.get_children().order_by('title')
menuitems_children = menuitems_children.live().in_menu()
for menuitem in menuitems_children:
menuitem.show_dropdown = has_menu_children(menuitem)
levelstr= "".join('a' for i in range(level)) # for indentation
level += 1
return {
'parent': parent,
'menuitems_children': menuitems_children,
'sub': sub,
'level':level,
'levelstr':levelstr,
# required by the pageurl tag that we want to use within this template
'request': context['request'],
}
、レンダリングされたページの3つのレベルがあります{% top_menu_children %}
によって呼び出されます。これは、メニューに表示されるページに子供があるときに呼び出され、このタグをレンダリングしているときに呼び出されます。。これを行うために
、私たちはtop_menu
とtop_menu_children
テンプレートタグによってレンダリングされるテンプレートを作成する必要があります。
注:これらはすべてBootstrap 3のnavbarクラス向けに作成され、私のニーズに合わせてカスタマイズされています。あなたのニーズに合わせてカスタマイズしてください。メニュー構築プロセス全体が{% top_menu_children %}
によって呼び出されるので、メニューをレンダリングする基本テンプレートにこのタグを配置します。 top_menu.html
にメニューの全体的な構造と各レンダリング方法を反映するように変更してくださいmenuitem
。 children_items.html
を変更して、すべてのトップメニュー項目の子どもがどんな深さでレンダリングされるかを反映させます。
my_site /タグ/ top_menu.html
{% load demo_tags wagtailcore_tags static %}
{% get_site_root as site_root %}
{# FOR TOP-LEVEL CHILDREN OF SITE ROOT; In a nav or sidebar, these are the menu items we'd generally show before hovering. #}
<div class="container">
<div class="collapse navbar-collapse" id="navbar-collapse-3">
<ul class="nav navbar-nav navbar-left">
{% for menuitem in menuitems %}
<li class="{% if menuitem.active %}active{% endif %}">
{% if menuitem.show_dropdown %}
<a href="{{ menuitem.url }}">{{ menuitem.title }}
<span class="hidden-lg hidden-md hidden-sm visible-xs-inline">
<span class="glyphicon glyphicon-chevron-right"></span>
</span>
</a>
{% top_menu_children parent=menuitem %}
{% else %}
<a href="{% pageurl menuitem %}">{{ menuitem.title }}</a>
{% endif %}
</li>
{% endfor %}
</ul>
</div>
</div>
my_site /タグ/ children_items.html今
{% load demo_tags wagtailcore_tags %}
{# For second- and lower-level decendents of site root; These are items not shown prior to hovering on their parent menuitem, hence the separate templates (and template tags) #}
<ul class="dropdown-menu">
{% for child in menuitems_children %}
{% if child.show_dropdown %}
<li>
<a href="{% pageurl child %}">
{% for i in levelstr %}  {% endfor %}
{{ child.title }}
<span class="glyphicon glyphicon-chevron-right"></span>
</a>
{# On the next line, we're calling the same template tag we're rendering. We only do this when there are child pages of the menu item being rendered. #}
{% top_menu_children parent=child sub=True level=level %}
{# ^^^^ SmartMenus is made to render menus with as many levels as we like. Bootstrap considers this outside of best practices and, with version 3, has deprecated the ability to do so. Best practices are made to be broken, right :] #}
</li>
{% else %}
<li>
<a href="{% pageurl child %}">
<!-- Allows for indentation based on depth of page in the site structure -->
{% for i in levelstr %}  {% endfor %}
{{ child.title }}
</a>
</li>
{% endif %}
{% endfor %}
</ul>
、お使いのベースレベルテンプレートの(あなたがいずれかを使用していると仮定しましょう;そうでなければ、それを得る:))あなたは、あなたので使用されているテンプレートに乱雑を取り除いたままで、メニューを横断することができます。詳細についてはcheck it out -
my_site/base.html
<ul class="nav navbar-nav navbar-left">
{% for menuitem in menuitems %}
<li class="{% if menuitem.active %}active{% endif %}">
{% if menuitem.show_dropdown %}
<a href="{{ menuitem.url }}">{{ menuitem.title }}
<span class="hidden-lg hidden-md hidden-sm visible-xs-inline">
<span class="glyphicon glyphicon-chevron-right"></span>
</span>
</a>
{% top_menu_children parent=menuitem %}
{% else %}
<a href="{% pageurl menuitem %}">{{ menuitem.title }}</a>
{% endif %}
</li>
{% endfor %}
</ul>
が、私はこのことについてブログ記事を書きました。または、実際には深さが複数のレベルではないと思うが、それを実際に見るにはThermaline.comに向かう。その場合は自動的にレンダリングされます:)
ここでは、この例はナビゲーションバーですが、サイドバーにも簡単に適用できます。
すべてを行う必要がある:
- あなたのメニューをレンダリングしたい
demo_tags
-
あなたのベーステンプレートのCall
{% top_menu %}
を含めます。
top_menu.html
およびchildren_items.html
をカスタマイズして、最初に を、次にすべてのレベルのページをレンダリングします。
post on two-level menusのためにTivixに声をかけてください。それは私にとって大きな出発点でした。
うわー、なんて投稿! :)私はあなたのサイトを過去に数回チェックアウトしました。私は応答する前にこれをすべて消化して試してみる必要があります。あなたの時間をありがとう。 –
非常にクール、聞くのは素晴らしい!私はより積極的に投稿するという意味を持ち続けています。読者がいることを聞くには、バットで素敵なキックです:) –