WordPressの管理メニュー設定項目の中に「ホームページの表示」という設定がありますよね。
サイトのトップページに関する重要な設定ですが、これによってどこがどう変わるのか、皆さんちゃんと把握していますか?
(ちなみに「ホームページの表示」設定とは、以下のエリアで設定できる項目のことです。)
おそらく、皆さん見かけたことはあると思います。
WordPressでサイトを制作する人なら「ホームページ」に固定ページを指定する時にここで設定することもよくあるでしょう。
ですが、詳しいことはあまり知らないまま放置してるんじゃないでしょうか...?
私もその1人だったのですが、今回はこの「ホームページの表示」設定で
- 「最新の投稿」を設定している時
- 固定ページを「ホームページ」や「投稿ページ」として指定した時
でどのように違いがあるのか、がっつりと検証してみました。
条件分岐タグの挙動やテンプレートの優先度、メインループの挙動などにかなり違いが出てくることが分かりましたので、WordPress関係の制作者さんは是非これを機に一緒に理解を深めていただけたらなと思います。
かなり重要な設定なのに、なんとな〜くの理解しかしていない、そこのあなた。
とりあえずis_home() || is_front_page()
って条件分岐してるけどこれもよく分かっていない、そこのあなた。
一緒に勉強していきましょう。笑
「最新の投稿」に設定した場合
デフォルトではこの「最新の投稿」が設定されています。 冒頭の画像の状態ですね。
この設定の場合、トップページでの挙動がどうなるのか。
重要な項目について 以下の表にまとめました。
表示されるテンプレートの優先度 | front-page.php > home.php > index.php |
---|---|
Trueを返す条件分岐タグ | is_front_page() is_home() |
メインループで呼び出せる対象 | 最新の投稿一覧 |
get_queried_object()の情報 | null |
表だけ見てもよくわからない人もいると思うので、それぞれ説明していきます。
テンプレート優先度について
「最新の投稿」が設定されている時、サイトのトップページ(//example.com)には、front-page.php の内容が最優先で表示されます。
front-page.php がなければ home.phpを、どちらもなければ、index.phpの内容を表示します。
条件分岐タグについて
is_front_page() と is_home() が true を返すようになっています。
アーカイブページのような挙動をしますが、is_archive() は false です。
メインループについて
メインループがどうなっているのかも重要なので 確認してみます。
front-page.php を設置し、以下のようにループを回してみました
if(have_posts()):
while(have_posts()):the_post();
the_title();
endwhile;
endif;
すると、投稿が最新のものから順に表示されます。
ちなみに、表示される投稿数の上限値については今回検証中の「ホームページの表示」設定のすぐ下にある「1ページに表示する最大投稿数 」という設定項目の値で変更可能です。デフォルトでは 10件 です。
get_queried_object()の情報
ページ種別によって取得できる情報オブジェクトが異なる便利なget_queried_object()
。
この関数で取得できる情報を確認することで、そのページがどういう種類のページとして機能しているかを確認できます。
ですが、トップページで取得できる情報はnullでした。
「固定ページ」を設定した場合
「固定ページ」を選択すると、好きな固定ページをサイトのトップページとして表示させることが出来ます。
また、「ホームページ」と「投稿ページ」という2種類の項目に対して、それぞれ固定ページを指定することができるようになっています。
なので、
- 「ホームページ」にのみ固定ページを指定
- 「投稿ページ」にのみ固定ページを指定
- どちらにも固定ページを指定
の3パターンについて、それぞれ挙動をまとめていこうと思います。
「ホームページ」だけを設定した場合
コーポレートサイトなどの、トップページにしっかりコンテンツを表示させたい場合によくある設定パターンだと思います。
この設定パターンでは、指定した固定ページの内容がトップページとして表示されます。
指定された固定ページは固定ページとしては存在せず、IDを用いて直接アクセス(/?p={id}
でアクセス)してもトップページへリダイレクトされます。
この時のトップページの各種挙動を以下にまとめると、次のようになりました。
表示されるテンプレートの優先度 | front-page.php > page.php* > index.php |
---|---|
Trueを返す条件分岐タグ | is_front_page() is_page |
メインループで呼び出せる対象 | 指定した固定ページ1件 |
get_queried_object()の情報 | 指定した固定ページのWP_Postオブジェクト |
テンプレート優先度について
優先度の2番目が home.php ではなく、page.phpとなります。
*この時のpage.phpですが、「ホームページ」に指定されたページの「固定ページテンプレート」がデフォルトの場合です。
別の固定ページテンプレートを指定した場合は、そのテンプレートファイルに置きかわります。(/* Template Name:テンプレート名*/
のような記述を入れたファイルのことですね。)
条件分岐タグについて
is_front_page()とis_page() が true を返すようです。
先ほどと違い、is_home() は false になるのもポイントです!
メインループについて
front-page.php を設置し、以下のようにループを回してみました
if ( have_posts() ) :
while( have_posts() ) : the_post();
the_title();
endwhile;
endif;
すると、指定した固定ページのタイトルだけが表示されました。
通常の固定ページを表示するときのメインループと同じで、その固定ページ1件分だけ取得できるようです。
get_queried_object()の情報
通常の固定ページと同じく、その固定ページに関するWP_Postオブジェクトが取得されました。
固定ページを確認してみると
固定ページの一覧画面を見ると、「ホームページ」に指定したページのタイトルに「- フロントページ」と分かりやすく表示してくれるようになっています。
(なんで「ホームページ」の設定なのにここの表示は「フロントページ」なんだ、というツッコミは置いておきましょう。)
また、編集画面でURLを確認すると、その固定ページのURLがトップのドメインと同じものになっていることもわかります。
「投稿ページ」だけを設定
これは、ほぼあり得ない設定パターンかなとは思います。
とは言っても、そのように設定することができてしまうので、一応考えておかなくてはなりません。
このパターンでは、先ほどの「ホームページ」にだけ固定ページを指定した時とは異なり、「投稿ページ」に指定したページは固定ページとして残り、トップページは「最新の投稿」の場合とほぼ同じ内容のページになります。
一番ややこしいところだと思うので、少し注意してください。
トップページと、「投稿ページ」に指定したページは固定ページの両方での各種挙動をまとめてみます。
トップページ | 「投稿ページ」に設定された固定ページ | |
---|---|---|
表示されるテンプレートの優先度 | home.php > index.php | home.php > index.php |
Trueを返す条件分岐タグ | is_home() | is_home() |
メインループで呼び出せる対象 | 最新の投稿一覧 | 最新の投稿一覧 |
get_queried_object()の情報 | null |
指定した固定ページのWP_Postオブジェクト |
テンプレート優先度について
この設定では、トップページでも「投稿ページ」に設定された固定ページでも front-page.php は一切関係なくなり、home.php が最優先となります。
条件分岐タグについて
どちらでも is_home() のみ true を返すようになります。
- トップページなのに is_front_page() が false を返す
- 固定ページなのに is_page() も false を返す
という点は非常に注意すべき点だと思います。検証してみて焦りました。笑
(is_single() や is_archive() も検証してみましたが、いずれも false でした。)
メインループについて
home.php にて、以下のようにループを回してみました
if ( have_posts() ) :
while ( have_posts() ) : the_post();
the_title();
endwhile;
endif;
すると、どちらのページでも 投稿が最新のものから順に表示されます。
つまり、メインループは「最新の投稿」を設定した時と同じ挙動になるようですね。
get_queried_object()の情報
さて、ポイントはこのget_queried_object()
の返り値です。
この検証パターンでは、トップページと「投稿ページ」に指定した固定ページでほぼ同じ状態が続いていましたが、唯一違いが見られたのです。
トップページではnull
が返ってきました。これは「最新の投稿」に設定されている場合のトップページと同じ値ですね。
そして「投稿ページ」に指定した固定ページでは、通常の固定ページと同じく、その固定ページに関するWP_Postオブジェクトが取得されました。(じゃあなんで is_page() が false なんだよと叫びたくなりますが、少し落ち着きましょう。)
固定ページを確認してみると
一覧を見ると、「ホームページ」に指定したページの名前の横に「- 投稿ページ」と分かりやすく表示されています。
また、編集画面でURLを確認すると、その固定ページのURLがそのまま存在していることがわかります。
やはり、ここを見ても「ホームページ」だけを設定した時と異なりますよね。
試しにこのURLにアクセスして確認してみると、サイトのトップページと全く同じ内容のページが現れます。(テーマによってはこのパターンの設定を考慮しておらずエラーページとかになってるかも)
すでに確認してきた通り、 get_queried_object()
の値だけが異なる、表示は全く同じページが2ページも存在するということになるんですよね。
これらを踏まえると、
「投稿ページ」の設定は単体で使うべきでない
というのが個人的な結論です。
「ホームページ」と「投稿ページ」の両方を設定
この時、サイトのトップページ(//example.com)には、「ホームページ」に指定した固定ページ(テストページA)の情報が渡されます。
そして、「投稿ページ」に設定した「テストページB」(//example.com/test-b/)では、投稿一覧ページとして扱われるようになります。
各ページでの検証項目の挙動は、それぞれ単体で設定した時と同じです。
一応簡単に表にまとめておくと、以下のようになります。
ページA (「ホームページ」に設定) |
ページB (「投稿ページ」に設定) |
|
---|---|---|
表示URL | //example.com | //example.com/test-b/ |
テンプレート優先度 | front-page.php > page.php > index.php | home.php > index.php |
条件分岐タグ | is_front_page() is_page() |
is_home() |
メインループで呼び出せる対象 | 指定した固定ページ1件 | 最新の投稿一覧 |
get_queried_object()の情報 | 指定した固定ページの情報 |
指定した固定ページの情報 |
なるほど、両方設定してみると、いい具合に両者の役割が分かれていることがわかりますね。
トップページには好きなコンテンツを表示し、最新の投稿一覧は別ページで表示したい。という時に両者の設定を同時に使うと良さそうです。
使用しているテーマがしっかり両者の役割に合うように中身を構築していれば、ですが。
データベースのどこに設定が保存されているのか
最後に、「ホームページの表示」の設定はデータベースのどこに保存されているのかを確認しておきましょう。
wp_optionsテーブル内の以下の3つのフィールドに値が保存されています。
- show_on_front(データ型: 文字列)
- フロントページに何を表示するかの設定が保存されている。
'posts'
または'page'
の値をとる。posts : 最新の投稿が設定されている
page : 固定ページ が設定されている - page_on_front(データ型: 整数)
- フロントページに表示されるページのIDが保存されている。
show_on_frontフィールドの値が 'posts' の時とページが選択されていない時は、0
- page_for_posts(データ型: 整数)
- 投稿を表示するページの IDが保存されている。
show_on_frontフィールドの値が 'posts' の時とページが選択されていない時は、0
on_なのか for_なのかどっちかに統一すればいいのに... というのは置いといて、
画像でもわかりやすくまとめておきますね。
結論:「トップページ」を判別するコードとは
全パターンを検証してみると、やはりis_home() || is_front_page()
で「トップページ」を判別させるのは危険ですね。
「ホームページ」と「投稿ページ」を両方指定した場合に、トップページではない「投稿ページ」でもこの式はtrue
になってしまいます。
(「投稿ページ」もトップページと同じ挙動をさせたい場合のみ、is_home() || is_front_page()
という分岐を使うようにしましょう。)
では、どのような判別をすればいいのでしょう。
改めて考えてみましょう。
【「投稿ページ」だけを指定するパターン】を考慮しない場合
この場合、is_front_page()
だけで十分ですね。
特定のクライアントさんのサイトを制作する場合や、自分のサイトを制作する場合はこれで大丈夫だと思います。
ただ、一般に頒布させたいWordPressテーマを制作する場合はそうもいきませんので、もう少し考えてみましょう。
全パターンを考慮する場合
どうすれば、全パターンで破綻せずに「トップページ」(「サイトアドレス」で設定しているURLに表示されるページ)を判別できるでしょうか。
何パターンかの記述方法があると思いますが、私はひとまず以下のように落ち着きました。
if ( is_front_page() ) {
//「最新の投稿」 or 「ホームページ」を指定された固定ページ
define( 'IS_TOP', true );
} elseif ( is_home() ) {
if ( get_queried_object() === null ) {
//「投稿ページ」だけ指定されている場合のトップページ
define( 'IS_TOP', true );
} else {
//「投稿ページ」に指定されたページ
define( 'IS_TOP', false );
}
} else {
define( 'IS_TOP', false );
}
IS_TOP
という定数に「トップページかどうか」を保存しています。
「ホームページの表示」設定、ややこしすぎました
ここまで読んでくれた方、お疲れ様でした。
いや~、ややこしかったですね。
ややこしいというか、WordPressは設定の幅が広いんだな〜ということが分かりました。
- 「最新の投稿」に設定するパターン
- 「ホームページ」だけを指定するパターン
の2パターンがほとんだと思いますので、せめてこの2つの違いだけでも覚えておくといいでしょう。
「ホームページ」だけを指定するパターンでは、トップページなのにis_home()
がfalse
になる。
というのは個人的にびっくりでした。
- 「投稿ページ」だけを指定するパターン
については、必要が出てくるまでは放置でもいいかもですね。
普通のサイト制作ではほぼほぼあり得ない状況だと思いますので。笑