2016-06-29 17 views
2

私はDjango Wagtailを使用してサイトを構築していますが、親インデックスページのすべての子ページをリストするサイドバーメニューを追加する方法がわかりません。たとえば、standard_index_page.htmlをAdminで作成した親ページを作成した後、standard_page.htmlテンプレートを使用して子ページを追加しました。私standard_index_page.htmlテンプレートでインデックスページでDjango Wagtailサイドバーを作成する子リンク

、私は次のコード

{% standard_index_listing calling_page=self %} 

を持っており、それがリンクを持つすべての子ページを表示しますが、私も子供にすべての子リンクのリストを表示したいと思いますページも同様です。

私はこれが意味を成して誰かが手を貸してくれることを望みます。ありがとうございました。

答えて

6

本質的には、Wagtailに提供されたページ階層のツリー構造をトラベリングします(Django-Treebeard)。

多くのフロントエンドフレームワークでは、いくつかのベストプラクティスを考慮していないため、複数のレベルのメニューは使用できません。しかし、SmartMenusのようなライブラリでは、小さな肘グリースでこの構造を表示することができます。

私のニーズにあっては、これに対する簡単な解決策はありませんでした。ですから、私がこれについてどのように行ったかの例を共有したいのですが、説明が欠落している可能性があります。ご不明な点がございましたら、お返事ありがとうございます。

これはしばらくの間苦労しましたが、ツリーをトラバースする方法が簡単な場合もありますが、私はニーズが拡大したので次の方法を構築しました。これにより、サイトのすべてのライブページをトラバースし、現在のページがいつメニューでレンダリングされているかを確認し、レンダリングを細かく制御することができます。ここで

は、私たちがやろうとしているものです:

  • サイトのルートの直接の子を 現在のサイト、ループのサイトのルートを取得するいくつかのテンプレートタグを作成し、 子どもの下位レベルのループの各レベルで発見された現在のメニューアイテムの子孫をループしている。お使いのベースのテンプレートで

、これは我々がする必要があることを意味:

  • {% 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_menutop_menu_childrenテンプレートタグによってレンダリングされるテンプレートを作成する必要があります。

注:これらはすべてBootstrap 3のnavbarクラス向けに作成され、私のニーズに合わせてカスタマイズされています。あなたのニーズに合わせてカスタマイズしてください。メニュー構築プロセス全体が{% top_menu_children %}によって呼び出されるので、メニューをレンダリングする基本テンプレートにこのタグを配置します。 top_menu.htmlにメニューの全体的な構造と各レンダリング方法を反映するように変更してくださいmenuitemchildren_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 %}&nbsp&nbsp{% 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 %}&nbsp&nbsp{% 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に声をかけてください。それは私にとって大きな出発点でした。

+2

うわー、なんて投稿! :)私はあなたのサイトを過去に数回チェックアウトしました。私は応答する前にこれをすべて消化して試してみる必要があります。あなたの時間をありがとう。 –

+0

非常にクール、聞くのは素晴らしい!私はより積極的に投稿するという意味を持ち続けています。読者がいることを聞くには、バットで素敵なキックです:) –

関連する問題