URLコンテキスト

目次

URLコンテキストの基本

URLコンテキストによって表示ページの出力を制御

a-blog cmsでは、表示しているページがWebサイトの何処なのか、どのような状態であるかをURL上のパスとして表現しています。これを URLコンテキスト(URLによって表現されるページの文脈情報)と呼んでいます。個々のモジュールは、このURLコンテキストで表す条件を元に何を表示するかを決定する事になります。

3つの基本ページ

URLコンテキストを理解する上でa-blog cms の基本テンプレートの概念は欠かせません。 基本テンプレートには以下の3種類が存在します。

  • トップページ
  • 一覧ページ
  • 詳細ページ

ひとつずつ詳しく説明します。

トップページ

一般的な運用として Webサーバのドキュメントルートに a-blog cms が設置された場合には、「http://ドメイン/」というURLでトップページが表示されます。

また、トップページはブログごとに存在できるので、子ブログでもトップのテンプレートを表示可能です。

<!-- ルートブログのトップのテンプレートが表示される場合 -->
http://www.example.com/

<!-- 「recruit」という子ブログのトップのテンプレートが表示される場合 -->
http://www.example.com/recruit/ 

また、個別のディレクトリ内にa-blog cmsを設置することも可能です。その際には、設置先のディレクトリ(下記の例では、http://www.example.com/cms/)まで指定した状態がシステムとしてのトップページという扱いになります。

<!-- 「cms」というディレクトリ以下にa-blog cmsが設置されている場合。ルートブログのトップのテンプレートが表示される -->
http://www.example.com/cms/

一覧ページ

URLがスラッシュで終わっている状態のとき、トップページ以外の場合、一覧ページが表示されます。

<!-- 「news」がカテゴリーなら一覧のテンプレートが表示される -->
http://www.example.com/news/

<!-- 「/」で終わっているが「recruit」がブログの場合はトップのテンプレートが使用される -->
http://www.example.com/recruit/

一覧ページが表示されるパターンの例

  • カテゴリーの一覧
  • キーワード検索結果
  • カスタムフィールドの検索結果
  • タグの一覧
  • ページ(2ページ目、3ページ目)
  • 日付

など

注意点としては、URLコンテキストの特徴として、URLからはコンテンツがブログなのかカテゴリーなのか分からないことです。今適用されているテンプレートを知りたいときはテーマとテンプレートの構成の「表示テンプレートの確認」項目をご覧ください。

詳細ページ

URLが 「.html」 で終わる場合は、エントリーの詳細ページが表示されます。

http://www.example.com/news/entry-1.html

URLコンテキストの表示制御

URLの例を上げて実際の動きをご紹介します。

コンテンツを指定するコンテキスト

ブログコード、カテゴリーコード、エントリーコードなどの情報(=コンテンツの情報)から、どの情報を表示するか指示が可能です。指示した内容に合わせて、テンプレートに設置しているモジュールの表示結果を制御します。

http://www.example.com/というドメインで、「appleple」というブログコードのトップページを表示するためには以下のようなURLになります。

<!-- トップのテンプレートが使用される -->
http://www.example.com/appleple/

http://www.example.com/というドメインで、「appleple」というブログコードかつ、「news」というカテゴリーの一覧を表示するためには以下のようなURLになります。

<!-- 一覧のテンプレートが使用される -->
http://www.example.com/appleple/news/

http://www.example.com/というドメインで、「appleple」というブログコードかつ、「news」というカテゴリーに存在する「entry-1.html」という一記事を表示するためには以下のようなURLになります。

<!-- 詳細のテンプレートが使用される -->
http://www.example.com/appleple/news/entry-1.html

http://www.example.com/というドメインで、ルートブログ内に存在する「news」というカテゴリーの「campaign」という子カテゴリーの一覧を表示するためには以下のようなURLになります。

<!-- 一覧のテンプレートが使用される -->
http://www.example.com/news/campaign/

状況を指定するコンテキスト

キーワードやタグによる検索、日付、ページなどの情報(=状況の情報)が含まれていた場合にも、モジュールの表示結果に影響し、絞り込んだ情報を表示できます。

2ページ目を表示する場合には以下のようなURLになります。

<!-- 一覧のテンプレートが使用される -->
http://www.example.com/news/campaign/page/2/

「2014年1月」を表示する場合には以下のようなURLになります。

<!-- 一覧のテンプレートが使用される -->
http://www.example.com/news/campaign/2014/01/

URLコンテキストの指定

ここでは、URLコンテキストの指定方法を解説していきます。ACMS_POST_2GETを使ってURLコンテキストを生成することが可能です。合わせてご覧ください。

また、URLコンテキストを使ってモジュールの表示内容を指定するには、モジュールID化してそれぞれの項目に対応する引数にチェックをつける必要があります。


URLコンテキストで指定したい項目にチェックをつけます。


IDを使って指定する

通常URL(例: http://example.com/company/access.html )でアクセスした場合、ブログコード、カテゴリーコード、エントリーコード(ファイル名)をもとに、登録データの解析を行い、ブログの情報やカテゴリーの情報やエントリー情報などを取得しています。

この他の書き方として、直接IDを指定してデータを取得する方法もあります。以下ではブログID(bid)、カテゴリーID(cid)、エントリーID(eid)を指定しています。

http://example.com/bid/1/cid/3/eid/16/

年月日を指定する

URLコンテキストを使ってエントリーの年月日を指定できます。

年月日については、yyyy-mm-dd、yyyy-mm、yyyyyの形式でURLコンテキストが記述されている場合に年月日として判定されます。

<!-- 日時を指定 -->
http://example.com/news/2017/ <!-- 2017年の記事 -->
http://example.com/news/2017/06/ <!-- 2017年6月の記事 -->
http://example.com/news/2017/06/23/ <!-- 2017年6月23日の記事 -->

<!-- 期間を指定 -->
http://example.com/news/2016/-/2017/ <!-- 2016, 2017年の記事 -->
http://example.com/news/2017-06-01/-/2017-06-30/ <!-- 2017年6月の記事 -->
http://example.com/news/2017-06-13/-/2017-06-23/ <!-- 2017年6月13日から23日の記事 -->

キーワードを指定する(キーワード検索)

URLコンテキストを使って検索を行います。以下がエントリーの検索対象となるデータになります。

<!-- 検索キーワード「地図」でヒットした記事の一覧が表示されます。 -->
http://example.com/news/keyword/地図/

フィールドを指定(カスタムフィールド検索)

URLコンテキストを使って検索を行います。キーワード検索と違い、検索対象はカスタムフィールドの項目を指定した検索になります。

詳しくは カスタムフィールドの検索 をご覧ください。

<!-- カスタムフィールド「price」の値を「60000」で登録している記事が一覧ページに表示されます。 -->
http://example.com/realestate/field/price/60000/

<!-- カスタムフィールド「price」の値を登録している(空ではない)記事が一覧ページに表示されます。 -->
http://example.com/realestate/field/price/nem/

<!-- カスタムフィールド「price」の値を「60000」以下で登録している記事が一覧ページに表示されます。 -->
http://example.com/realestate/field/price/lte/60000/

並び順を指定する

一覧ページでは、並び順をURLコンテキストで指定することができます。指定できる値は、モジュールIDの表示設定にある、並び順の項目と同じになります。

<!-- 新しい日付順で表示します -->
http://example.com/order/datetime-desc/

<!-- 設定された表示順で表示します。(カテゴリ、ユーザごとのソート設定があるので注意) -->
http://example.com/order/sort-asc/

<!-- ランダムで表示します。(キャッシュされるとランダムで表示できないので注意) -->
http://example.com/order/random/
意味
id-ascIDが小さい順
id-descIDが大きい順
sort-asc昇順
sort-desc降順
code-ascコード昇順
code-descコード降順
title-ascタイトル昇順
title-descタイトル降順
datetime-asc古い順
datetime-desc新しい順
posted_datetime-asc投稿が古い順
posted_datetime-desc投稿が新しい順
updated_datetime-asc更新が古い順
updated_datetime-desc更新が新しい順
user_id-asc投稿ユーザIDが小さい順
user_id-desc投稿ユーザIDが大きい順
blog_id-asc投稿ブログIDが小さい順
blog_id_desc投稿ブログIDが大きい順

カスタムフィールドで並び替えを行う「field-asc」「field-desc」「intfield-asc」「intfield-desc」を使ったorder指定には注意が必要です。 例えば、下記のURLでは対象となるカスタムフィールドがないため、URLコンテキストで指定した並び替えは行われません。

http://example.com/realestate/order/intfield-asc/

次のように「field」を使ってカスタムフィールドを指定します。

http://example.com/field/price/nem/order/intfield-asc/

「price」の値を数値として昇順に並び替えた一覧ページを表示します。

注意点 その1:モジュールIDの設定でURLコンテキストのfield項目をチェックしていない場合、URLコンテキストで指定した並び替えも行われません。

注意点 その2:複数の項目をfield検索している場合、最初のfield(一番左側の)が並び替えに使用されます。

URLコンテキストとは異なるテンプレートを指定する

通常だと、URLコンテキストに沿ったテンプレートファイルが適用されますが、「tpl」を使って、異なるテンプレートを適用できます。

<!-- エントリーの詳細ページに custom.html というURLコンテキストとは異なるテンプレートを適用する -->
http://example.com/entry-21.html/tpl/include/custom.html

「tpl」を使って異なるテンプレートを適用する方法は、ポストインクルード機能と組み合わせてよく使われます。詳しくはポストインクルード機能をご覧ください。

Ver. 2.11.25 より仕様が変更になりました。 https://developer.a-blogcms.jp/blog/news/template-21125.html

private/cofig.system.yaml で以下項目が追加・変更されています。

forbid_tpl_inheritance_when_path_unresolved: on # on | off パス解決に失敗した時、テンプレートを継承しないようにする
forbid_tpl_url_context: on # on | off 読者以下のURLコンテキストのtplを許可しない。(例: https://example.com/news/tpl/custom.html)
allow_tpl_path: [] # forbid_tpl_inheritance_when_path_unresolved や forbid_tpl_url_context が on の場合、除外するパスを設定します。例: [news.html,hoge/custom.html] カンマ区切りで指定

forbid_tpl_url_context

デフォルトで、tplコンテキスト を無効に設定しました。理由として tplを指定すればクライアント側で、好きなテンプレートを指定することができてしまうため、 同一コンテンツの複数のページができてしまうためになります。

forbid_tpl_inheritance_when_path_unresolved

デフォルトで、パス解決失敗時のテンプレート継承を無効にしました。理由として forbid_tpl_url_context と同様、同一コンテンツの複数のページが表示できてしまうためになります。

allow_tpl_path

上記2つの設定の例外パスを設定できます。例えばpost includeしたい箇所などは、tplコンテキストを使いたい場合があるので、 そのような時は、ここで例がテンプレートのパスを記入します。

以上3つのオプションの設定を追加・変更いたしました。バージョンアップでは影響が出ないようになっていますので、Ver. 2.11.25 以上で新規インストールする場合はお気をつけください。

forbid_tpl_inheritance_when_path_unresolvedforbid_tpl_url_contextoff に設定すれば、いままでと同じ動作になりますが、できればここの設定はONのまま、allow_tpl_path で例外設定をするようにお願いいたします。

ポストインクルード・Ajaxの場合(Ver. 3.1.17 以降)

テンプレートファイルを指定する場合は、部分的にHTMLを持ってくるポストインクルードや独自のAjaxリクエストの利用が多いと思います。

ポストインクルードやAjaxでのリクエストの場合、特に上記の「allow_tpl_path」を設定しなくても取得できるようになっています。(Ver. 3.1.16 以下の場合は、「allow_tpl_path」を設定する必要がございます)

設定がいらない理由

private/config.system.yaml の「ajax_security_level」の設定に応じて、ポストインクルード(Ajax)のアクセスを認証することにより、直接のGETリクエストと、ポストインクルード(Ajax)でのリクエストを区別することが出来るようになり、tpl指定の制限をしたまま、ポストインクルード(Ajax)のリクエストは許可するということが出来るようになりました。

ajax_security_level: 2 # ajaxリクエストのセキュリティレベルを設定します。(0: チェックなし 1: RefererとHttpヘッダーを確認 2: CSRFトークン確認)

Ajaxセキュリティレベル

レベル0
ajax_security_level: 0

レベル0は、特になにも認証をしないので、基本的には設定しないでください。

レベル1
ajax_security_level: 1

レベル1は、RefererとHttpヘッダーを確認して、Ajaxリクエストであることを確認します。ポストインクルードを利用すれば自動でHTTPヘッダーは付与されるので、特に意識する必要はありません。

もしポストインクルードではなく独自のAjaxリクエストで、HTMLを取得する場合は以下HTTPヘッダーを付与ください。

Referer: https://example.com/xxxxx/xxxx.html
X-Requested-With: XMLHttpRequest
レベル2
ajax_security_level: 2

レベル2は、レベル1のチェックに加え、CSRFトークンを使った認証を行います。ポストインクルードを利用すれば自動でHTTPヘッダーにCSRFトークンが付与されるので、特に意識する必要はありません。

もしポストインクルードではなく独自のAjaxリクエストで、HTMLを取得する場合は以下HTTPヘッダーを付与ください。

Referer: https://example.com/xxxxx/xxxx.html
X-Requested-With: XMLHttpRequest
X-Csrf-Token: xxxxxxxxxxxxxxxxxxx

X-Csrf-Token に設定する値は、テンプレートに「check-csrf-token」文字列を追加することにより、CMSで追加できます。例えばクラス名で指定するなどです。

<div class="check-csrf-token">
...
</div>

CSRFトークンは、metaタグに生成されています。JavaScriptなどでこの値を取得してご利用ください。

<meta name="csrf-token" content="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
const csrfToken = document.querySelector('meta[name="csrf-token"]').content