カスタムポストのパーマリンクを投稿IDにする / よくあるWordPress


カスタムポストを利用するとパーマリンクがイマイチな感じになるので、試行錯誤してみました。
WordPress3.5 で、ブログサイトではなくビジネスサイトのCMSとして使用する前提です。
試したのはマルチサイトでしたが、そうでなくても大丈夫と思います、たぶん。

カスタムポストを使用するとパーマリンクは /custom_post_name/slug のようになります。
これだとお客さんとかに使ってもらう時にうっかりタイトル日本語で入れるとイロイロ面倒です。
管理画面からパーマリンクの設定を変更していたりするとスラッグの書き換えもできなくなったりしますし。

これを通常の投稿のように post_id で出来ないかとイロイロ調べていたら下記ページが見つかりました。
http://memocarilog.info/wordpress/theme-custom/3909
http://webpaprika.com/387.html

ただ、$wp_rewrite ルールの中を見ると既にイロイロ登録されているみたいです。
なので、参考にしつつもなるべく余計なルールを追加しない方向で検討しました。

まずは通常の投稿設定

カスタム投稿の前に通常の投稿を /blog のように使いたいので、管理画面の「設定 → パーマリンク設定」から、カスタム構造で「/blog/%post_id%」とします。

固定ページで blog ページをつくっておいて「設定 → 表示設定」からフロントページの表示を固定ページに、投稿ページを先ほどの blog ページにしておきます。

ここまではカスタムポスト関係ないんですが、後で関連してきます。

カスタムポストを登録する

試しにお知らせを news として登録する場合は、下記のように function.php に記述するかプラグイン作成します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function custom_post_types() {
    $label = 'お知らせ';
    $slug = 'news';
    $option = array(
        'label' => $label,
        'labels' => array(
            'name' => $label,
            'singular_name' => $label,
            'add_new_item' => $label . 'を追加',
            'add_new' => '新規追加',
            'new_item' => '新規' . $label,
            'view_item' => $label . 'を表示',
            'not_found' => $label . 'は見つかりませんでした',
            'not_found_in_trash' => 'ゴミ箱に' . $label . 'はありません。',
            'search_items' => $label . 'を検索',
        ),
        'capability_type' => 'post',
        'menu_position' => 5,
        'rewrite' => array(
            'slug' => $slug,
            'with_front' => false
        ),
        'public' => true,
        'query_var' => true,
        'has_archive' => true,
        'hierarchical' => false,
        'supports' => array('title', 'editor'),
    );
    register_post_type('news', $option);
}
add_action('init', 'custom_post_types');

register_post_type の説明はリファレンス見て下さい。

ココでのポイントは ‘rewrite’ オプションですかね。
with_front を false にしないと、先のパーマリンク設定の影響を受けて /blog/news となってしまいます。
あと、’public’ オプション忘れるとページが見れなかったり、’has_archive’ がないと一覧ページがでなかったりします。

で、実はこの時点で /news から一覧ページ、/news/slug でパーマリンクが見えるので細かいこと気にしないという方はそれでもよかったりします。
ちょっと検索するとこの部分でも rewrite ルールの設定が必要という情報出てきますが、3.5からなのか特に設定しなくても大丈夫です。

2013.02.02追記
内容変更するたびに「設定 → パーマリンク設定」から変更を保存しないと反映されません。
自分もファイルアップしてから、ああそうだったと気づくことが多かったです。

パーマリンクを投稿IDに設定する

ここでようやく本題ですが、気にしないと言いつつも、facebook でシェアした時にURLの見栄えがよろしくないのは気になると思います。
日本語だとURLエンコードされちゃいますし。

そこでひかかったのですが、既に rewrite ルールが設定してあるので、先に紹介した参考サイトのように新たにルールを追加しても、適用済みのルールが優先されるので NOT FOUND になってしまいます。
※パーマリンクを POST ID にしたので、一致するスラッグがないからだ思われます

なので登録済みのルールを変更することにします。
パーマリンクの設定はカスタムポスト名(この場合 ‘news’)で登録されているので、参考サイトのようにスラッグの部分を投稿IDに変更します。

1
2
3
4
5
6
7
8
9
10
11
function myposttype_permalink($post_link, $id = 0, $leavename) {
    global $wp_rewrite;
    $post = &get_post($id);
    if ( is_wp_error( $post ) )
        return $post;
    $newlink = $wp_rewrite->get_extra_permastruct($post->post_type);
    $newlink = str_replace('%'.$post->post_type.'%', $post->ID, $newlink);
    $newlink = home_url(user_trailingslashit($newlink));
    return $newlink;
}
add_filter('post_type_link', 'myposttype_permalink', 1, 3);

リライトルールは既に追加してあるのですが、get_extra_permastruct のように取得する方法はどうもないみたいです。
ただ、ソース見た感じ、既にあるものは上書きしてくれるみたいです。
なので、そのまま %news% を置き換えることにします。

1
2
3
4
5
function myposttype_rewrite() {
    global $wp_rewrite;
    $wp_rewrite->add_rewrite_tag('%news%', '([0-9]+)', 'post_type=news&p=');
}
add_action('init', 'myposttype_rewrite');

参考サイトにある add_permastruct は既に登録済みなので add_rewrite_tag で上書きするだけでOKです。
以上で、ビジネスサイトとしてだいぶ理想的なURLに設定できたと思います。
マルチサイトに対応してるのがありがたかったです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です