目次

一般的なブログ形式の場合は、カテゴリーとタグで十分なんですが、カスタム投稿タイプとカスタムタクソノミーの使い方が理解できると、もう手放せなくなりそうです。

ブログ、お知らせ、イメージギャラリー、ポートフォリオ、店舗紹介、Q&A などなど、様々な投稿タイプにあった使い方や表示が実現できます。

日本でもようやくその情報を目にする事が増えてきましたが、それでも思うようにいかないことも多かったので、表示方法やテンプレートに施したカスタマイズの例を中心にメモしたいと思います。

カスタム投稿タイプを使えるようにする

functions.php にコードを追加したり、CMS Press というプラグインも試しましたが、僕には Custom Post Type UI というプラグインが便利だと感じました。

設定方法はこちらのサイトが詳しいです。参考にさせていただきました。
http://www.odysseygate.com/archives/1624

・・・・・・

よし、設定完了。カスタムポストタイプ「videos」を投稿できるようになりました。

シングルページの表示

カスタム投稿タイプが videos の場合:single-videos.php

カスタム投稿タイプで作った投稿は、通常 single.php で表示されます。専用のレイアウトにしたい場合は、single-[post-type].php というテンプレートを用意するか、条件分岐でカスタマイズする必要があります。

条件分岐

if (get_post_type() === 'post type')

今のところ is_single() のような関数は用意されていない様子。
投稿タイプ pictures の場合 こんにちは! と出力し、投稿タイプ videos の場合専用のテンプレートを読み込む。

<?php
if ( get_post_type() === 'pictures' ) {
    echo 'こんにちは!';
}
elseif ( get_post_type() === 'videos' ) {
    get_template_part( 'loop', 'videos' );
}
?>

アーカイブページ

従来の投稿(post)の場合は、カテゴリーでの分類が必須なので、category.php(なければ archive.php や index.php)にそのアーカイブを表示してくれますが、カスタム投稿タイプを含める場合にはちょっと準備が必要です。

例えば query_posts( 'cat=123' ); として WordPress ループ(while( have_posts() : the_post(); 〜 endwhile;)で記事一覧を表示させてもビルトインの「投稿」しか出てこないのは、デフォルトで 'post_type' => 'post' と指定されているからなんですー。 カスタム投稿タイプのタクソノミの使い方について

なるほど~。ということで、該当テンプレートを修正です。

ケース1:投稿とカスタム投稿タイプを表示

テンプレート(category.php など)を修正

<?php
global $wp_query;
query_posts(array_merge(
    array( 'post_type' => array('post', 'videos') ),
    $wp_query->query
));
if (have_posts()) : while (have_posts()) : the_post();
?>

表示したい投稿タイプを4行目に記述します。これで、該当するカテゴリーの投稿とカスタムタイプ video の記事が表示され、管理画面で設定した表示件数の引き継ぎやページングも機能するはずです。

なお、タグ(tag.php)やカスタムタクソノミー(taxonomy.php)でも実現できますし、年月別アーカイブ(archive.php, date.php)にもカスタム投稿を含めたい場合には、それらのテンプレートに修正が必要です。

ケース2:カスタム投稿タイプ専用のアーカイブページ

現時点では、専用のアーカイブテンプレートファイルが無いので、アーカイブを表示するためのテンプレートを用意する必要があります。ページを利用したり、専用のカテゴリーを作るなどすれば実現できます。

※ここでいうカテゴリーとは、カスタム投稿を表示するためだけに作成したもの。

カスタム投稿タイプ videos のアーカイブをページで作る

1. ページの新規作成
スラッグを videolist としたページを作成。

2. 必要なコードの追加
page-videolist.php というテンプレートを用意するか、page.php に条件分岐を加えて必要なコードを追加します。

<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$newloop = new WP_Query(array(
    'post_type' => videos,
    'posts_per_page' => 10,
    'paged' => $paged
));
if ($newloop->have_posts()) :
    while ($newloop->have_posts()) : $newloop->the_post();
?>
 <!--
ループ内
 -->
<?php endwhile; endif; ?>
 
<?php
if(function_exists('wp_pagenavi')) wp_pagenavi();
?>

$newloop(4箇所)は任意の文字列で。あくまでページにループを追加している状態なので、オリジナルのクエリはそのページのものになります。ですからケース1と違い、必要なループの制御(ページ数や表示件数など)をする必要があると思います。

こちらもご覧ください
ページ機能を使ったカスタム投稿タイプのアーカイブで、ページングに不具合がでます…

気をつけること

この項目は、/%category%/%postname% というパーマリンク設定に慣れていて、
アーカイブ:http://*****/videos
シングル:http://*****/videos/chotto-h-desu

こんな関係のURLを好んでいる方向けです。

アーカイブページに設定したページまたはカテゴリーのスラッグと、カスタム投稿タイプの名前(最終的にはリライトスラッグ)を同じにするとページングに不具合が出ます。(2ページ目以降が表示されません)

回避策としては…

1. 階層形式のURLにこだわらない

アーカイブのスラッグと、カスタムタイプの名前を違うものにすれば悩む必要はありません。これが一番だと思います。

2. それっぽいURLで妥協する

ページスラッグ:videos、カスタム投稿の名前:video
アーカイブページ:http://*****/videos
シングルページ:http://*****/video/chotto-h-kamo

ページスラッグ:videos、カスタム投稿の名前:videos
リライトスラッグ:videos/detail
アーカイブページ:http://*****/videos
シングルページ:http://*****/videos/detail/chotto-h-kamo

3. ページングを利用しない構成にする

1ページだけの表示なら問題なさそうので、アーカイブページはカスタム投稿タイプのトップページのような位置づけにします。

ホーム:http://*****/
  |-- カスタムタイプトップ:http://*****/videos
      # ページを利用(ページングなしでタクソノミーA,Bの記事5件ずつ表示)

    |-- カスタム投稿のタクソノミー A:http://*****/videos/tax-a
        |-- シングルページ 1:http://*****/videos/post-1
        |-- シングルページ 4:http://****/videos/post-4

    |-- カスタム投稿のタクソノミー B:http://*****/videos/tax-b
        |-- シングルページ 2:http://*****/videos/post-2
        |-- シングルページ 7:http://*****/videos/post-7

個人的まとめ

  • カスタム投稿のアーカイブは、ページやカテゴリーなどを利用して実現できる。
  • 余程のこだわりが無い限り、アーカイブのスラッグとカスタム投稿の名前を重複させない。
  • 階層形式のURLにこだわるなら、カテゴリーと投稿を利用したほうが無難。
  • サイト全体の構成を考えて、カテゴリー、タクソノミーとの関係や使い方を考える必要がある。

RSS フィード

残念ながら、デフォルトではフィードにカスタムタイプの投稿は含まれません。フィードのテンプレートをカスタマイズする方法もありますが、以下のコードをテーマの functions.php に追加することで実現できます。

function my_get_posts( $query ) {
    if ( is_feed() ) {
        $query->set( 'post_type', array('post', 'videos') );
        return $query;
    }
}
add_filter( 'pre_get_posts', 'my_get_posts' );

3行目に含めたいポストタイプを記入します。(この場合は投稿と videos)
実はこのコード、ホームやカテゴリーの制御にも有効なんですが、「あっちが上手くいったと思ったらこっちが駄目っ」と使い方に苦労したため、僕はフィードだけの設定にしてあります…。

参考サイト:http://justintadlock.com/

悪戦苦闘した素人のメモです。間違った解釈、方法、記述、コードが含まれている場合があることをご了承ください。危険!なコードがある場合は、ご指摘してくださると嬉しいです。

追記:投稿タイプを変更できる(videos → post → page → やっぱり videos)プラグイン、Post Type Switcher を用意しておくと後々役に立つかもしれません。

こちらの記事もどうぞ
WordPress 3.1 から使う、カスタムポストタイプの設定から表示までのまとめ ...的なもの