既存のプロジェクトに途中参加した際の出来事です。
新しいカテゴリーのページを追加したいということでカスタム投稿タイプを作成したのですが、既存のページのレイアウトが変わってしまっていると連絡をもらってしまいました。調べた所このプロジェクトではwordpressの固定ページをカスタム投稿のトップページの様に使っていて、固定ページのslug(URL)とカスタム投稿タイプ名(URLになる部分)が同じ文字列になっていました。新しくカスタム投稿タイプを追加する前は固定ページで表示されていたものが、機能追加後はカスタム投稿のアーカイブページが表示されてしまっていたのが原因だったようです。
まぁそもそも固定ページのslugと同じカスタム投稿タイプを作成するのどうなの?って感じなのですが、
- カスタム投稿のトップページを
example.com/hoge
- カスタム投稿の記事ページを
example.com/hoge/single-page
と表示させたかったのでこのような処置になっていたのだと思います。
折角なので、プレーンなWordpress 固定ページのslug(URL)とカスタム投稿タイプ名がかぶっている時どうなるか調べてみました。
固定ページを作成する
WordPressの固定ページから新規作成を選びslugをworks
としてページを作成します。イェー!!
この時local.wordpress/works
は当然ですが固定ページが表示されています。
カスタム投稿タイプ(works)を作成する
固定ページのslugと同じworks
という名前のカスタム投稿タイプを作成します。
<?php // function.php add_action('init', 'add_my_post_type'); function add_my_post_type() { $post_type = 'works'; $labels = array( 'name' => _x('works', 'works'), 'singular_name' => _x('works', 'works'), 'add_new' => __('worksを新規作成'), 'add_new_item' => __('worksを作成'), 'edit_item' => __('worksを編集'), 'new_item' => __('新しいworks'), 'view_item' => __('worksを見る'), 'search_items' => __('worksを探す'), 'not_found' => __('worksはありません'), 'not_found_in_trash' => __('ゴミ箱にworksはありません'), ); $args = array( 'labels' => $labels, 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'show_in_menu' => true, 'query_var' => true, 'capability_type' => 'post', 'has_archive' => true, 'hierarchical' => false, 'menu_position' => null, 'menu_icon' => 'dashicons-art', 'supports' => array('title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments') ); register_post_type($post_type, $args); }
管理画面にworksというメニューが追加されているのでworksの投稿を作成して公開します。いちごちゃん is かわいい。OK?
カスタム投稿のURLはhttp://local.wordpress/works/my-work01/
となっています。
なのでこのカスタム投稿のアーカイブページはhttp://local.wordpress/works/
となるはず。なのですが、固定ページのURLと同じになってしまいます。。。
worksページを見に行く
http://local.wordpress/works/
にアクセスします。
固定ページが表示されていました。
カスタム投稿のページ(http://local.wordpress/works/my-work01/
)を確認します。
404ページが表示されていました。。。
どうやら固定ページを先に作成して固定ページのslugと同じ名前でカスタム投稿タイプを作成しただけでは、カスタム投稿のアーカイブページは先に作成した固定ページが表示され、カスタム投稿のページは404になってしまうようです。
パーマリンク設定を更新する
カスタム投稿を作成した時にページが404になってしまう時の解決方法の常套手段が管理画面のパーマリンク設定を更新するだと思います。
そもそもカスタム投稿のページが表示されていないので、ココを更新してみます。
管理画面 > 設定 > パーマリンク
にアクセスして何も変更せずに保存ボタンを押します。
再度各ページを確認します。
- Worksページ (
http://local.wordpress/works/
)
カスタム投稿のアーカイブページが表示されます - カスタム投稿の個別ページ (
http://local.wordpress/works/my-work01/
)
カスタム投稿の個別ページが表示されます
管理画面のパーマリンク設定を更新すると
新しく作成したカスタム投稿のアーカイブページが優先されるみたいです。
flush_rewrite_rules関数を使ってみる。
Wordpressにはリライトルールを変更するflush_rewrite_rules
という関数があるようです。
ざっくりいえば管理画面からパーマリンク設定の更新を行える関数でしょうか。
Function Reference/flush rewrite rules
Description
Remove rewrite rules and then recreate rewrite rules.
This function is useful when used with custom post types as it allows for automatic flushing of the WordPress rewrite rules (usually needs to be done manually for new custom post types). However, this is an expensive operation so it should only be used when absolutely necessary. See Usage section for more details.
<?php flush_rewrite_rules( $hard ); ?>
Parameters
$hard
(boolean) (optional) Whether to update .htaccess (hard flush) or just update rewrite_rules transient (soft flush). Default: true (hard flush)
関数リファレンス/register post type - WordPress Codex 日本語版
参考:プラグインの内部で投稿タイプを登録する場合は、有効化と無効化のフック(下記の「有効化するときリライトルールをフラッシュする」を参照)の中で flush_rewrite_rules() を呼び出すこと。もし flush_rewrite_rules() を使わない場合は、カスタム投稿タイプが正しいパーマリンク構造を表示するために、管理画面の 設定 > パーマリンク設定 を開いてパーマリンク構造を更新(変更を保存)する必要がある。
Flushing the rewrite rules is an expensive operation, there are tutorials and examples that suggest executing it on the 'init' hook. This is bad practice.
と書かれますが、まぁいいや。テストって事でカスタム投稿タイプを追加した時にこの関数をを呼んでリライトルールを変更してみます。
まずは設定を固定ページを作成した段階に戻すしたいので、カスタム投稿タイプの追加を削除して、管理画面のパーマリンク設定を更新してhttp://local.wordpress/works/
で固定ページが表示されていた状態に戻します。
続いてflush_rewrite_rules()
を追加したカスタム投稿タイプの追加をします。
function.phpを編集します。
<?php // function.php add_action('init', 'add_my_post_type'); function add_my_post_type() { $post_type = 'works'; $labels = array( 'name' => _x('works', 'works'), 'singular_name' => _x('works', 'works'), 'add_new' => __('worksを新規作成'), 'add_new_item' => __('worksを作成'), 'edit_item' => __('worksを編集'), 'new_item' => __('新しいworks'), 'view_item' => __('worksを見る'), 'search_items' => __('worksを探す'), 'not_found' => __('worksはありません'), 'not_found_in_trash' => __('ゴミ箱にworksはありません'), ); $args = array( 'labels' => $labels, 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'show_in_menu' => true, 'query_var' => true, 'capability_type' => 'post', 'has_archive' => true, 'hierarchical' => false, 'menu_position' => null, 'menu_icon' => 'dashicons-art', 'supports' => array('title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments') ); register_post_type($post_type, $args); // リライトルールを更新する flush_rewrite_rules(); // ← 追加 }
function.php
を保存して、管理画面のパーマリンク設定は触らずに各ページを確認してみます。
- Worksページ (
http://local.wordpress/works/
)
カスタム投稿のアーカイブページが表示されました - カスタム投稿の個別ページ (
http://local.wordpress/works/my-work01/
)
カスタム投稿の個別ページが表示されました
flush_rewrite_rules()
を実行することで管理画面のパーマリンク設定を保存したのと同じ状態になるので、予想通りカスタム投稿のページが表示されていました。
引数で.htaccess
の書き換えをするかどうかが変更できますが、true
でもfalse
でも同じ挙動になりました。
まとめ
固定ページのslug(URl)と同じ名前のカスタム投稿タイプを作成してしまった場合
パーマリンクの設定を保存し直すと、カスタム投稿のアーカイブページが優先されるというのが仕様なようです。
カスタム投稿のトップページは固定ページないでサブクエリを呼び出すのではなく、ちゃんとアーカイブページのテンプレートで作成しましょう。って事ですね!
複数人で開発をしているような場合は、本番環境のWordPressの管理画面から作成したものを各自の開発環境と合わせておかないと、意図せず同じURLを作ってしまい、リリースしたら元の○○が表示できなくなった!みたいな事もあるかもなので注意が必要かなと思いました。
[参考]
- Function Reference/flush rewrite rules « WordPress Codex
- 関数リファレンス/register post type - WordPress Codex 日本語版
- flush_rewrite_rules:WordPress私的マニュアル
- WordPress » パーマリンクの設定がうまく反映されない時の対処法 | MORILOG
【早期購入特典あり】劇場版アイカツ! 超豪華版 大スター宮いちごBOX(とび出す!たためる!特製いちごちゃんうちわ付き) [Blu-ray]
- 出版社/メーカー: Happinet(SB)(D)
- 発売日: 2015/06/02
- メディア: Blu-ray
- この商品を含むブログ (2件) を見る