企業系ホームページを作っていると、固定ページのURLにぶら下げる形で投稿を追加したいことがある。
固定ページで簡単な説明を書いて、その下に記事一覧を表示する。
その場合、固定ページのスラッグと投稿のスラッグを同じにするのだが、そう単純には行かない。
特にカスタム投稿の場合。
標準の「投稿」を「お知らせ」記事、カスタム投稿を追加して「ブログ」記事。
その逆の場合もある。
やりたいこと
今回は、「投稿」を「お知らせ」、カスタム投稿を「ブログ」として作る。
固定ページ
http://sample.com/blog
個別記事ページ
http://sample.com/blog/123 (「123」は記事ID)
タクソノミー(カテゴリー)ページ
http://sample.com/blog/category/abc (「abc」はタクソノミーのスラッグ)
アーカイブページ
http://sample.com/blog/date/2018/5 (「2018」は年、「5」が月)
こんな感じの仕上がりにする。
なお、「投稿」を「お知らせ」とするため、パーマリンク設定は
http://sample.com/information/%post_id%
としている。
また、固定ページとして
http://sample.com/information と http://sample.com/blog
を作っている。
カスタム投稿を追加する
カスタム投稿を追加する場合、functions.php に以下のコードを追加する。
function register_post_type_and_taxonomy() { // カスタム投稿 register_post_type( 'blog_item', array( 'labels' => array( 'name' => __('ブログ'), 'all_items'=> __('ブログ一覧'), 'add_new' => __('ブログを追加する'), 'add_new_item' => __('ブログの追加'), 'edit_item' => __('ブログの編集'), 'singular_name' => __('ブログタイプ'), 'new_item' => __('新しいブログ'), 'view_item' => __('ブログを見る'), 'search_items' => __('ブログを探す'), 'not_found' => __('ブログはありません'), 'not_found_in_trash' => __('ゴミ箱にブログはありません'), 'parent_item_colon' => '' ), 'public' => true, 'hierarchical' => false, 'has_archive' => true, 'menu_position' => 4, 'supports' => array( 'title', 'editor', 'excerpt', 'custom-fields', 'thumbnail', 'page-attributes' ), 'rewrite' => array('slug'=>'blog', 'with_front' => false ), ) ); // カスタムタクソノミー register_taxonomy( 'blog_type', 'blog_item', array( 'labels' => array( 'name' => 'ブログカテゴリー', 'add_new_item' => 'ブログカテゴリーを追加', 'edit_item' => 'ブログカテゴリーの編集', ), 'public'=>true, 'hierarchical' => true, 'show_admin_column' => true, 'rewrite' => array('slug'=>'blog/category', 'with_front' => false ), ) ); } add_action('init','register_post_type_and_taxonomy');
ここでポイントになるのは、カスタム投稿のスラッグを「blog_item」(4行目)としているところ。
固定ページのスラッグと重複しないように名付ける必要がる。
もう1つのポイントが
'rewrite' => array('slug'=>'blog', 'with_front' => false )
だ。(32行目)
rewiteでスラッグを「blog」にする。
with_fronはをtrueにすると
http://sample.com/information/blog/
となってしまうので、falseにする。
with_fronをかんたんに説明すると「ベースとなるパーマリンクを引き継ぐかどうか」ということ。
URLを変更する
上記の「カスタム投稿を追加する」で設定した内容は、あくまでもルール決めをしただけで、実際に動作はしない。
そこで、URLをリライトする必要がある。
function prefix_movie_rewrite_rule() { // ブログカテゴリー add_rewrite_rule('blog/category/([^/]+)/?$', 'index.php?blog_type=$matches[1]', 'top'); // ブログ年別 add_rewrite_rule('blog/date/([0-9]{4})/?$', 'index.php?post_type=blog_item&year=$matches[1]', 'top'); // ブログ月別 add_rewrite_rule('blog/date/([0-9]{4})/([0-9]{2})/?$', 'index.php?post_type=blog_item&year=$matches[1]&month=$matches[2]', 'top'); // ブログ(個別記事) add_rewrite_rule('blog/([0-9]+)/?$', 'index.php?post_type=blog_item&p=$matches[1]', 'top'); // ブログ(固定ページ) add_rewrite_rule('blog/?$', 'index.php?pagename=blog', 'top'); } add_action( 'init', 'prefix_movie_rewrite_rule' );
これをfunctions.php に追加することで、目標としていたURLで動作するようになる。
忘れていけないのは、上記コードを追加したあとに、パーマリンク設定を保存すること。
何も変更していなくても、「変更を保存」ボタンを押すこと。
プラグインの力を借りる
基本的にプラグインは使いたくないのだが、ここから先は面倒なのでプラグインの力をお借りします。
と言うのも、wp_get_archivesで日別アーカイブの一覧を出力すると、カスタム投稿のパーマリンクが
http://sample.com/information/date/2018/5?post_type=blog_item
となるのだ。
これを回避するには、日別アーカイブを自力で作るしかない。面倒だ。
そこで登場するのが「Custom Post Type Permalinks」プラグイン。
こいつをインストールすることで、wp_get_archivesが出力するパーマリンクを
http://sample.com/blog/date/2018/5
にすることができる。
日本語翻訳済でわかりやす。ありがとう。
どのテンプレートが使われる?
固定ページ(http://sample.com/blog)
固定ページなので当然、page.phpが摘要される。
固定ページのコンテンツ+記事一覧とすることが一般的なので、page-blog.phpを使用するのが常套手段であろう。
個別記事ページ(http://sample.com/blog/123)
個別記事なので、single.phpが摘要される。
標準の「投稿」を「お知らせ」と使用しているので、「カスタム投稿」の「ブログ」とデザインを変えたい時はsingle-blog_item.phpとする。
注意したいのは、single_information.phpではなくsingle.phpである。あくまでも「お知らせ」は標準の投稿だからだ。
そして「カスタム投稿」はsingle-blogphpではなく、single-blog_item.phpだ。
register_post_type_and_taxonomyでカスタム投稿を追加したときのスラッグになることに注意。
タクソノミーページ(http://sample.com/blog/category/abc)
タクソノミーのテンプレートはtaxonomy-blog_type.phpになる。
これもregister_post_type_and_taxonomyでカスタム投稿タイプを追加した時のスラッグになる。
ちなみに標準の投稿のカテゴリーページはcategory.phpが摘要される。
アーカイブページ(http://sample.com/blog/date/2018/5)
標準のアーカイブはarchive.phpなので、カスタム投稿のアーカイブはarchive-information_item.phpとなる。
ここもregister_post_type_and_taxonomyでカスタム投稿を追加したときのスラッグになることに注意。
アーカイブページで「年」「年月」を判別するには、is_year() (年)、is_month()(年月)を使用する。
また、get_query_var(‘year’)で年の値、get_query_var(‘monthnum’)で月の値を取得できる。
最後のこだわり
以上で、目的は達成したが、現状ではダッシュボードの記事編集画面に表示されるパーマリンクが
http://sample.com/information/123
となってします。
ユーザーには見えない部分だが、どうせならここも
http://sample.com/blog/123
としたい。
function my_post_type_link( $link, $post ){ if ('information_item' == $post->post_type ) { return home_url( '/information/' . $post->ID ); } else { return $link; } } add_filter('post_type_link', 'my_post_type_link', 1, 2 );
これをfunctions.php に追加することで、編集画面でも目標のURLとなる。
おしまし。