OctoberCMSのプラグインもJS挿入するものやバックエンド(管理画面)の機能を拡張するものなどなど多岐にわたるが、ブログプラグインがフロントエンド(公開されるサイト)とバックエンドの両方に機能を追加する一般的な良い例になる。
OctoberCMSでブログ機能を使うにはOctoberCMSの作者が提供するRainLab.Blogプラグインを使用すると簡単に実現できる。記事データはOctoberCMSフレームワークで設定したデータベースに保存される。
やることは、2つ
- プラグインをインストール
- テーマにブログリストとブログ記事のページを追加
プラグインのインストール方法はちょうどブログプラグインを例に「プラグインのインストール方法3つ(GUI, Composer, 手動)」で説明しているので、ここでは実際にフロントエンド(公開するウェブサイト)にブログを表示させるためページ実装を説明する。
また、ここではOctoberCMSインストールすると同梱されているテーマ "demo" を使って説明する。
インストール確認
まず、正常にインストールされていればバックエンド(管理ページ)にブログ管理ページが表示される。
すでに、仮の投稿が入ってるが、リストページがわかりやすいようにもう一つ投稿を作っておく。
タイトル、本文に加えてSLUGが最低限必要になる。(SLUGとはURLパスパラメータのことで記事のIDとなる一意の任意の文字列を指定する。)
また、Manageタブで過ぎた日時を指定してPublishedにチェックしておかないと表示されないので、やっておく。
リストページ作成
ブログの投稿リストや投稿表示ページを実装する。ページは通常通りテーマに実装する。
ここではまず、管理画面のCMSタブからページを追加する。
下図の様に最低限の4項目を入力する。内容は基本的に何でもいい。Layoutはテーマに含まれているものから選択できるが、demoテーマの場合defaultしかないので、それを選択。とりあえず、ここで"Save"をクリックして保存する。
これで、ドメイン以下の/blog
をブラウザで開けばページが開ける。が、まだ何も表示されない。
次にサイドメニューの "Components" から "Blog" を開き、 "Post List" コンポーネントを選択する。オレンジ色のページ編集タブにコンポーネントが追加される。
これでコンポーネントが登録できたので、テンプレートからブログデータにアクセスするためのオブジェクトとしてTWIGテンプレートからアクセスすることができる。
しかし、自分で実装してみる前に、デフォルト実装を使ってみる。OctoberCMSではコンポーネントにテンプレートを提供させることができ、このPost Listコンポーネントもデフォルトのテンプレートを提供しているので、とりあえず使ってみる。
使い方は非常に簡単で、ページのマークアップセクションに下記を記述するだけ。{% component %}
タグで、ページに登録したコンポーネントのエイリアスを引数に渡している。
{% component 'blogPosts' %}
これだけで、ページに投稿リストが表示される。
このデフォルトテンプレートはplugins/rainlab/blog/components/posts/default.htm
に格納されており、下記のような内容になっている。自前でテンプレートを実装する参考になる。このデフォルトテンプレートでは記事リストの他に、カテゴリ表示、パジネーションも丁寧に実装してくれている。実際、記事リストは下の方のforループ5行だけで実装されている。
{% set posts = __SELF__.posts %}
<ul class="post-list">
{% for post in posts %}
<li>
<h3><a href="{{ post.url }}">{{ post.title }}</a></h3>
<p class="info">
Posted
{% if post.categories.count %} in {% endif %}
{% for category in post.categories %}
<a href="{{ category.url }}">{{ category.name }}</a>{% if not loop.last %}, {% endif %}
{% endfor %}
on {{ post.published_at|date('M d, Y') }}
</p>
<p class="excerpt">{{ post.summary|raw }}</p>
</li>
{% else %}
<li class="no-data">{{ noPostsMessage }}</li>
{% endfor %}
</ul>
{% if posts.lastPage > 1 %}
<ul class="pagination">
{% if posts.currentPage > 1 %}
<li><a href="{{ this.page.baseFileName|page({ (pageParam): (posts.currentPage-1) }) }}">← Prev</a></li>
{% endif %}
{% for page in 1..posts.lastPage %}
<li class="{{ posts.currentPage == page ? 'active' : null }}">
<a href="{{ this.page.baseFileName|page({ (pageParam): page }) }}">{{ page }}</a>
</li>
{% endfor %}
{% if posts.lastPage > posts.currentPage %}
<li><a href="{{ this.page.baseFileName|page({ (pageParam): (posts.currentPage+1) }) }}">Next →</a></li>
{% endif %}
</ul>
{% endif %}
1行目の__SELF__
はデフォルトテンプレートでのコンポーネントオブジェクトの参照の仕方なので、自前ページのテンプレートではこれをコンポーネントのエイリアスに置き換えてやればいい。
ここの例で言うとblogPosts.posts
でブログ記事のリストが取得できるので、リストをイテレートして記事一覧を表示することができる。
ここで作成したページはthemes/demo/pages/blog.htm
に保存されている(ここの例では"demo"テーマを使用しているため)。
中を見てみるとこれだけ。上からページの設定、コンポーネントの設定、テンプレートセクションとなっている。
title = "Blog"
url = "/blog/:page?"
layout = "default"
is_hidden = 0
[blogPosts]
pageNumber = "{{ :page }}"
postsPerPage = 10
noPostsMessage = "No posts found"
sortOrder = "published_at desc"
categoryPage = 404
postPage = 404
==
{% component 'blogPosts' %}
記事ページ作成
先程と同様に今度は記事本文を表示するためのページを作成する。
記事ページでは、"Post"コンポーネントを追加する。コンポーネントを追加する際に左側のコンポーネントをMarkupセクションにドラッグ&ドロップすると、デフォルトテンプレートを読み込むTWIGマークアップを自動的に挿入してくれる。
また、URLにはコロン':'で始まる:slug
を含んでいるが、これはパスパラメータになる。例えばlocalhost/blog/post/hoge
とブラウザに入れるとhoge
が:slug
変数としてOctoberCMSが扱ってくれる。ブログ記事を作成する際にSLUG
を指定する必要があったが、URLでこのslugを指定することで、表示する記事を指定することになる。ここでは slug = 記事ID と置き換えるとわかりやすい。
ちなみに、記事ページのデフォルトテンプレートはplugins/rainlab/blog/components/post/default.htm
にあるので、自前でテンプレート作成する際に参考になる。
{% set post = __SELF__.post %}
<div class="content">{{ post.content_html|raw }}</div>
{% if post.featured_images.count %}
<div class="featured-images text-center">
{% for image in post.featured_images %}
<p>
<img
data-src="{{ image.filename }}"
src="{{ image.path }}"
alt="{{ image.description }}"
style="max-width: 100%" />
</p>
{% endfor %}
</div>
{% endif %}
<p class="info">
Posted
{% if post.categories.count %} in
{% for category in post.categories %}
<a href="{{ category.url }}">{{ category.name }}</a>{% if not loop.last %}, {% endif %}
{% endfor %}
{% endif %}
on {{ post.published_at|date('M d, Y') }}
</p>
記事リストからのリンクを修正
ブログリストの記事へのリンクが現状では404になってしまっている。これを先程作成した/blog/post/:slug
パスに設定してやる。
ブログリストページのPost Listコンポーネントをクリックするとプロパティ設定ダイアログが表示される。そこの"Links"を開いて"Post page"でドロップダウンリストからblog/post
を選択する。始めの/
と後の:slug
が省かれているが、これが記事ページのURLに指定したパスになる。
以上で、見た目はしょぼいがとりあえずブログを実装できた。