Wagtail CMS(Django)で簡単なブログを立ち上げる-パート2

Wagtail CMSに関する第1部の執筆以来、バージョン1.6.3が既にリリースされています-シンプルなブログの作成に向けての旅を続ける時が来ました。



パート1

パート3



最初の部分では、最初のブログ投稿のみを作成しました。 これはサイトの本格的な作業には十分ではないため、本格的なサブセクションを作成し、最後の3つの投稿、ナビゲーション、ブレッドクラム、スライダーを表示するときが来ました。



Wagtail CMS(Django)で簡単なブログを立ち上げる-パート2



最後の部分では、ブログのメインページを作成しました。デフォルトでは、メインイメージ'main_image'があります。



Wagtailでは、画像を操作するためのロジックは非常に単純です。 models.pyで画像を管理するには、次の行が担当します。



from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
      
      





管理パネルでは、画像の追加は次のように表示されます。







ページへの画像の追加は、次のブロックによって決定されます。



 class BlogPage(Page): main_image = models.ForeignKey( 'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) content_panels = Page.content_panels + [ FieldPanel('date'), ImageChooserPanel('main_image'), #     .  FieldPanel('intro'), FieldPanel('body'), ]
      
      





blog / templates / blog / blog_page.htmlのコードのおかげで、画像がページに表示されます:



 {% load wagtailcore_tags wagtailimages_tags %} {% if page.main_image %} {% image page.main_image width-500 %} #    500px {% endif %}
      
      





投稿に写真を追加した場合は、次のようなページを取得する必要があります。







ドキュメントでセキレイの画像の操作の詳細を読むことができます



ここで、すべてのblogindexpage.html投稿が含まれるサブセクションを作成します。 次のコードをblog / models.pyに追加します。



 class BlogIndexPage(Page): intro = RichTextField(blank=True) content_panels = Page.content_panels + [ FieldPanel('intro', classname="full") ]
      
      





テンプレートフォルダーで、新しいものを作成します-blog / templates / blog / blog_index_page.html

次のコードを追加します:



 {% extends "base.html" %} {% load wagtailcore_tags %} {% block body_class %}template-blogindexpage{% endblock %} {% block content %} <h1>{{ page.title }}</h1> <div class="intro">{{ page.intro|richtext }}</div> {% endblock %}
      
      





移行-python manage.py makemigrationsおよびpython manage.py migrate



現在、blogindexpageページテンプレートが管理パネルに表示されています。このパネルには、イントロテキストブロックのみがあります。 このテンプレートを含むページをメインページの子として追加します。 最初の投稿で以前に作成したページは、 blogindexpageページの子セクションに移動する必要があります



サイト構造の例: ホームページ→サブセクションブログ→投稿ページ



「ブログ」サブセクションのページにすべての投稿を表示する必要がありますが、それらが多数ある場合、ページは非常に大きくなる可能性があります。 したがって、最後の9つの投稿のみを表示し、 django.core.paginatorモジュールのdjangoページネーションを使用して、残りの投稿を表示します。



models.pyを変更します:



 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger class BlogIndexPage(Page): intro = RichTextField(blank=True) @property def blogs(self): #    ,      blogs = BlogPage.objects.live().descendant_of(self) #    blogs = blogs.order_by('-date') return blogs def get_context(self, request): blogs = self.blogs #  page = request.GET.get('page') paginator = Paginator(blogs, 9) #  9  try: blogs = paginator.page(page) except PageNotAnInteger: blogs = paginator.page(1) except EmptyPage: blogs = paginator.page(paginator.num_pages) #    context = super(BlogIndexPage, self).get_context(request) context['blogs'] = blogs return context content_panels = Page.content_panels + [ FieldPanel('intro', classname="full") ]
      
      





次に、はがき用のテンプレートを作成する必要があります。 blog / templates / blogフォルダーで、htmlテンプレートblog_list_item.htmlを作成するincludeフォルダーを作成します-パスの例:/blog/templates/blog/includes/blog_list_item.html



次のコンテンツ:



 {% load static wagtailcore_tags wagtailimages_tags %} #       <div class="row media-object"> {% if blog.main_image %} <div class="media-object-section"> {% image blog.main_image fill-200x200 as img %} #   200px  200px <a href="{% pageurl blog %}"><img class="image_tmb" src="{{ img.url }}" /></a> </div> {% endif %} <div class="media-object-section"> <p class="data"><strong>{{ blog.date }}</strong></p> <a href="{% pageurl blog %}"><span>{{ blog.title }}</span></a> <p>{{ blog.intro }}</p> </div> </div>
      
      





blog / templates / blog / blog_index_page.htmlテンプレートで、コンテンツブロックに次のコードを追加する必要があります。



 {% for blog in blogs %} {% include "blog/includes/blog_list_item.html" %} {% empty %}    {% endfor %}
      
      





ページネーションを実装するには、同じページに次のブロックを追加します:



 #  -  django.core.paginator # <div class="row"> <ul class="pagination center"> {% if blogs.has_previous %} <li class="waves-effect"><a href="?page={{ blogs.previous_page_number }}{% for key,value in request.GET.items %}{% ifnotequal key 'page' %}&{{ key }}={{ value }}{% endifnotequal %}{% endfor %}""><i class="material-icons">chevron_left</i></a></li> {% endif %} {% if blogs.has_previous %} <li class="waves-effect"><a href="?page={{ blogs.previous_page_number }}{% for key,value in request.GET.items %}{% ifnotequal key 'page' %}&{{ key }}={{ value }}{% endifnotequal %}{% endfor %}"">{{ blogs.previous_page_number }}</a></li> {% endif %} {% if blogs.has_next %} <li class="active"><a href="">{{ blogs.number }}</a></li> <li class="waves-effect"><a href="?page={{ blogs.next_page_number }}{% for key,value in request.GET.items %}{% ifnotequal key 'page' %}&{{ key }}={{ value }}{% endifnotequal %}{% endfor %}">{{ blogs.next_page_number }}</a></li> {% else %} <li class="active"><a href="">{{ blogs.number }}</a></li> {% endif %} {% if blogs.has_next %} <li class="waves-effect"><a href="?page={{ blogs.next_page_number }}{% for key,value in request.GET.items %}{% ifnotequal key 'page' %}&{{ key }}={{ value }}{% endifnotequal %}{% endfor %}"><i class="material-icons">chevron_right</i></a></li> {% endif %} </ul> </div>
      
      





私たちはすべてを更新していますが、ブログセクションで最後の9つの投稿を表示できるようになり、ページネーションもできました。



ブログのページ間の移行を容易にするために、メニューを追加することは今でもすべてです。



Wagtailのメニューはそのまま使用できます。ページを編集するときは、[プロモーション]セクションのパラメーター[メニューに表示:]を使用します。



Wagtailでメニューを実装する方法に関する詳細な記事があります。



サイトに管理パネルから制御できるメニューがあるように、どこに何を追加する必要があるかを簡単に説明します。



base.htmlに追加します



 {% load home_tags %} #home_tags.py    {% block menu %} {% get_site_root as site_root %} {% top_menu parent=site_root calling_page=self %} {% endblock %}
      
      





プロジェクトフォルダー/ home / folder / templatestag /に、ファイルhome_tags.pyを次の内容で作成します。



 from django import template from home.models import * from blog.models import * register = template.Library() @register.assignment_tag(takes_context=True) def get_site_root(context): return context['request'].site.root_page def has_menu_children(page): return page.get_children().live().in_menu().exists() @register.inclusion_tag('home/tags/top_menu.html', takes_context=True) def top_menu(context, parent, calling_page=None): menuitems = parent.get_children().live().in_menu() for menuitem in menuitems: menuitem.show_dropdown = has_menu_children(menuitem) menuitem.active = (calling_page.url.startswith(menuitem.url) if calling_page else False) return { 'calling_page': calling_page, 'menuitems': menuitems, 'request': context['request'], } @register.inclusion_tag('home/tags/top_menu_children.html', takes_context=True) def top_menu_children(context, parent): menuitems_children = parent.get_children() menuitems_children = menuitems_children.live().in_menu() return { 'parent': parent, 'menuitems_children': menuitems_children, 'request': context['request'], }
      
      





メニューのスタイルを設定するために、フォルダ/ home / templates / home / tags /に 2つのテンプレートtop_menu.htmltop_menu_children.htmlを作成します



top_menu.htmlに書き込みます。



 {% load home_tags wagtailcore_tags %} {% get_site_root as site_root %} <li class="nav-item"><a href="{% pageurl site_root %}" class="menu_link_main" title="{{ site_root.title }}"></a></li> {% for menuitem in menuitems %} <li class="nav-item"> {% if menuitem.show_dropdown %} <a data-toggle="dropdown" class="menu_link_item" href="#">{{ menuitem.title }}</a> {% top_menu_children parent=menuitem %} {% else %} <a href="{% pageurl menuitem %}">{{ menuitem.title }}</a> {% endif %} </li> {% endfor %}
      
      





top_menu_children.htmlに書き込みます。



 {% load home_tags wagtailcore_tags %} <ul class="dropdown-menu"> <li><a href="{% pageurl parent %}">{{ parent.title }}</a></li> {% for child in menuitems_children %} <li><a href="{% pageurl child %}">{{ child.title }}</a></li> {% endfor %} </ul>
      
      



{%load%}ブロックでは、 home_tagsを呼び出す必要があることに注意してください。そうしないと何も機能しません。 そしてもちろん、すべてのメニュースタイルをcssファイルに書き込むことを忘れないでください。



メインページをより楽しくするためにスライダーを作成し、ブログセクションの最後の3つの投稿の出力を追加する必要があります。 これを行うには、 以前に作成したhome_tagsが必要です。



次のコードは、スライダーの操作を担当します。



フォルダー/ home / templates / home /フォルダーを作成/ includes / 、その中にファイルSlider.htmlを作成します:



 {% load wagtailimages_tags wagtailembeds_tags %} {% if slider_items %} <div class="slider" id="homeSlider"> <ul class="slides"> {% for slider_item in slider_items %} <li> {% image slider_item.image width-1200 as imageslider %} <img src="{{ imageslider.url }}" class='home_slider' alt="{{ imageslider.alt }}" /> </li> {% endfor %} </ul> </div> {% endif %}
      
      





Nivo Slider、WOWなどのセキレイのスライダーを使用するか、独自のスライダーを作成できます。 このチュートリアルでは、 materializecss.com/ media.htmlにバンドルされているスライダーを使用します 。 サイトのスライダーを選択することは、好みと習慣の問題です。 スライダーが機能したことは、すべての必要な依存関係(css、js)を追加することを忘れないでください。



次に、次のコードを追加してhome / models.pyを編集します。



 from django.db import models from wagtail.wagtailcore.models import Page, Orderable from wagtail.wagtailcore.fields import RichTextField from wagtail.wagtailadmin.edit_handlers import (FieldPanel, InlinePanel, MultiFieldPanel, PageChooserPanel) from wagtail.wagtailimages.edit_handlers import ImageChooserPanel from wagtail.wagtailsearch import index from modelcluster.fields import ParentalKey from wagtail.wagtailsnippets.models import register_snippet class HomePage(Page): body = RichTextField(blank=True) disc_t = RichTextField(blank=True) search_fields = Page.search_fields + [ index.SearchField('body'), index.SearchField('disc_t'), ] content_panels = Page.content_panels + [ InlinePanel('slider_items', label=""), #    FieldPanel('body', classname="full"), FieldPanel('disc_t', classname="full"), ] class LinkFields(models.Model): link_external = models.URLField("URL", blank=True) link_page = models.ForeignKey( 'wagtailcore.Page', null=True, blank=True, related_name='+' ) @property def link(self): if self.link_page: return self.link_page.url else: return self.link_external panels = [ FieldPanel('link_external'), PageChooserPanel('link_page'), ] class Meta: abstract = True class SliderItem(LinkFields): image = models.ForeignKey( 'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) panels = [ ImageChooserPanel('image') ] class Meta: abstract = True class HomePageSliderItem(Orderable, SliderItem): page = ParentalKey('HomePage', related_name='slider_items')
      
      





更新、移行、サーバーの再起動、メインページの編集を開いて、スライダー付きの新しいブロックを表示します。



メインページに最後の3つの投稿を表示するには、次のコードを追加します。

/home/templatestag/home_tags.pyに以下を追加します:



 @register.inclusion_tag( 'home/tags/blog_listing_homepage.html', takes_context=True ) def blog_listing_homepage(context, count=3): #count=3  3   blogs = BlogPage.objects.live().order_by('-date') #      return { 'blogs': blogs[:count].select_related('main_image'), 'request': context['request'], }
      
      





フォルダー/ home / templates / home / tagsに 、コンテンツを含むテンプレートblog_listing_homepage.htmlを追加します。



 {% if blogs %} {% for blog in blogs %} {% include "blog/includes/blog_list_item.html" %} {% endfor %} {% endif %}
      
      





メインページに投稿を表示するには、home_page.htmlのスライダーの後に追加します。

{%blog_listing_homepage%}



すべてのコンテンツが1つのヒープにハングアップしないように、ホームページの通常のブロックを必ず行ってください。 移行、更新を行い、メインページにスライダーと最後の3つの投稿を表示します(もちろん、作成した場合)



簡単なブログの準備がほぼ整いました。メインページとブログセクションがあり、各投稿を個別に見ることができます。 新しいセクションの作成、投稿の管理、画像の変更ができます。 手始めに、これで十分です。



ブログのナビゲーションを改善するためにパン粉を追加すると、プロジェクトを開始する準備が整います。

これは、 blog_page.htmlおよびblog_index_page.htmlテンプレートの次のコードによって実装されます。



 {% if self.get_ancestors|length > 1 %} <div class="breadcrumb_page"> {% for page in self.get_ancestors %} {% if page.is_root == False %} <a class="breadcrumb" href='{% pageurl page %}'>{{ page.title }}</a> {% endif %} {% endfor %} <span class="breadcrumb_active">{{ self.title }}</span> </div> {% endif %}
      
      





ブロックをスタイルで装飾し、サイトメニューに加えて便利なナビゲーションを取得します。



残りの機能はすべて、類推によって追加でき、他のセクションを作成し、ページごとに異なるテンプレートを使用し、バナーを添付できます。



この基本的なチュートリアルがWagtail CMSを使い始めるのに役立つことを願っています。 次のパートでは、 StreamFieldの使用について説明します



All Articles