yusk -ユースク-

  • WordPress
  • Twitter
  • RSS
  • Facebook

201111-01

カスタム投稿タイプとカスタムタクソノミーをプラグインを使わずに実現する

WordPress

カスタム投稿タイプをカスタムタクソノミーも含めプラグインを使わずにfunctions.phpに記述し、それを固定ページからループさせてさらにページネーションも実現したい。(長っ!)
という場合、色々と調べたりハマりながらも学べたので、忘れないために自分なりの備忘録です。

それもこれも、WordPressで構築する際には極力プラグインを使わないで出来ないかと意地になってなんとかしました。
もちろんプラグインを使えばカスタム投稿タイプは簡単に導入できるのですが、それに頼りっきりだと、PHP初心者な自分にとっては後々のバージョンアップで対処が出来なくなったり、なにより“動いている仕組み”を知らないで使えてしまうこと自体が怖かったりするんですよね。

functions.phpに記述をしていると、多少なりとも勉強になるでしょう!

カスタム投稿タイプとカスタムタクソノミーを作ろう!

まずカスタム投稿タイプですが、手軽に使えるプラグインが幾つか存在してますが、あえてfunctions.phpに記述して作成します。

ただ、普段functions.phpには他に色々記述していたり、カスタム投稿タイプを複数記述する時に長くなるので、別途カスタム投稿タイプ記述用にcustom-post-type.phpを作ってfunction.phpにインクルードさせました。

<?php
// カスタム投稿タイプを読み込む
include_once($_SERVER['DOCUMENT_ROOT'] ."/inc/custom-post-type.php");
?>

さて、今回は求人情報専用の投稿タイプを作ることにします。
求人情報はセオリーの「地域カテゴリー」と「職種タグ」で分類できるようにします。
WordPressの場合は、カテゴリーとタグを他で使用していても、新たに“タクソノミー(分類)”を作ることができるんですね。
これもプラグインがありますが、カスタム投稿タイプも直に記述するので、まとめてしまいましょう。

ちなみに、カスタム投稿タイプについては色々解説されているサイトがあるけど、今回はカスタム投稿タイプとカスタムタクソノミーを一緒に指定したかったので、

こちらを参考に、作成しました。上記サイトは、物凄く解り易い解説だと思います。目から鱗です。(@_@)

<?php
// カスタム投稿タイプを作成
// 求人投稿タイプ
function jobinfo_custom_post_type() 
{
$labels = array(
'name' => _x('求人情報', 'post type general name'),
'singular_name' => _x('求人情報', 'post type singular name'),
'add_new' => _x('求人情報を追加', 'jobinfo'),
'add_new_item' => __('新しい求人情報を追加'),
'edit_item' => __('求人情報を編集'),
'new_item' => __('新しい求人情報'),
'view_item' => __('求人情報を編集'),
'search_items' => __('求人情報を探す'),
'not_found' => __('求人情報はありません'),
'not_found_in_trash' => __('ゴミ箱に求人情報はありません'), 
'parent_item_colon' => ''
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true, 
'query_var' => true,
'rewrite' => true,
'capability_type' => 'post',
'hierarchical' => false,
'menu_position' => 5,
'has_archive' => true,
'supports' => array('title','editor','author','excerpt','comments'),
'taxonomies' => array('jobinfo_category','jobinfo_tag')
); 
register_post_type('jobinfo',$args);
// カスタムタクソノミーを作成
//カテゴリータイプ
$args = array(
'label' => '地域カテゴリー',
'public' => true,
'show_ui' => true,
'hierarchical' => true
);
register_taxonomy('jobinfo_category','jobinfo',$args);
//タグタイプ
$args = array(
'label' => '職種タグ',
'public' => true,
'show_ui' => true,
'hierarchical' => false
);
register_taxonomy('jobinfo_tag','jobinfo',$args);
} 
add_action('init', 'jobinfo_custom_post_type');
?>

上記内でWordPressのVer3.1以降から追加された重要な要素として、

'has_archive' => true,

があります。
これにより、今までは無理矢理チックだったカスタム投稿タイプのアーカイブページがしっかりと実現できるのです。
確か以前はページングが色々ハマった記憶があります。プラグインで回避するしかなかったような気もします。
これが自然に生成できるようになったのは、大きな進化ですよね。

さて、こうすると管理画面にこのように「カスタム投稿タイプ」と「カスタムタクソノミー2種類」が追加されます。

カスタム投稿タイプ

カテゴリー仕様のタクソノミー
カスタムタクソノミー

タグ仕様のタクソノミー
カスタムタクソノミー

カスタム投稿タイプの管理画面の投稿一覧に項目を追加したい

ここまでの内容でも投稿として使えますが、管理画面の記事一覧の所にタクソノミー2種類を表示したいですよね。

カスタム投稿一覧

というわけで、下記を参考に追加しました。大変勉強になります。

//管理画面記事一覧にカスタムタクソノミーの表示追加
function manage_posts_columns($columns) {
        $columns['fcategory1'] = "地域";
        $columns['fcategory2'] = "職種";
        return $columns;
}
function add_column($column_name, $post_id){
	//カテゴリー名取得
    if( 'fcategory1' == $column_name ) {
        $fcategory = get_the_term_list($post_id, 'jobinfo_area');
    }
    if( 'fcategory2' == $column_name ) {
        $fcategory = get_the_term_list($post_id, 'jobinfo_type');
    }
    //該当カテゴリーがない場合「なし」を表示
    if ( isset($fcategory) && $fcategory ) {
        echo $fcategory;
    } else {
        echo __('None');
    }
}
add_filter('manage_edit-jobinfo_columns', 'manage_posts_columns');
add_action('manage_posts_custom_column',  'add_column', 10, 2);

これで実現できました。

カスタム投稿一覧

ここまでで基本的なカスタム投稿タイプとカスタムタクソノミーのオリジナル追加ができたのですが、もし複数のカスタム投稿タイプやカスタムタクソノミーを使う場合には、同じように追記で作ってやれば良いです。
もちろん変数名とか被らないようにしましょう。

カスタム投稿タイプを固定ページ内でループさせる

ここまで出来たら、投稿は問題ないでしょう。
さて、次は出力です。

カスタム投稿タイプを使うということは、通常のhave_posts()とは別の独立したものになるので、取得も気をつける必要があります。
いつもの

have_posts()

だと駄目なんですよね。
今回の場合、

'post_type' => 'jobinfo'

とかすれば良いんですが、それだけだとどうも上手くいかない。。
取得とループ自体は出来ても、ページネーションが発生した際に次ページ以降の取得がうまくいかずに404.phpになってしまう現象が発生するのです。

そんな状態を解決できたのは、以下の素晴らしいサイトです。

ここから、このように記述。

<?php //'jobinfo'というカスタム投稿タイプ呼び出し
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$wp_query = new WP_Query( array( 'post_type' => 'jobinfo', 'posts_per_page' => 10, 'paged' => $paged ) ); ?>
<?php if (have_posts()) : while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
~コンテンツ~
<?php endwhile;endif; ?>

そしてページネーションはコリスさんの所のこれを使ってます。

上記を参考にfunctions.phpに記述。
これを記述しておくと、ページネーションを出力したい場所に

<?php if (function_exists("pagination")) {
pagination($additional_loop->max_num_pages);
} ?>
<?php wp_reset_query(); ?>

で出力OKなのです。

これで固定ページ内にカスタム投稿タイプをループさせてページングも実現。ふぅ。完成。

と思ったら。。。(以下、余談と注意点になります)

今度はどのページに遷移しても“最新の投稿内容しか取得できない”という謎のハマりに遭遇。
これはパーマリンクのカスタム構造 /%category%/%postname%.html にしているせいかな~と思って調べるも、なんか違う。
解決の糸口を探してリライトを変更するプラグインなどを入れたり四苦八苦。
そして極めつけは、なんとかページネーションが解決したと思ったら、今度は何故かsingleページが404エラーに^^; 絶対にpermalink関係がおかしいぞ・・

これに限っては、単純に“jobという固定ページスラッグの指定をしているjobページ内”に、“jobというカスタム投稿タイプ”を読み込んだ為、同じスラッグの競合が起こってしまい、
http://example.com/job (固定ページ)
http://example.com/job/detail/ (カスタム投稿タイプ“job”の詳細ページ)
という“job”が「固定ページ」と「カスタム投稿タイプ“job”」で重複してしまって、パーマリンクが機能しないというなんというイージーミスに気付いたのです。

そもそも、カスタム投稿タイプを使うと、パーマリンク設定ではカスタム構造を
「 /%category%/%postname%.html 」にしてても、「 /カスタム投稿名/%postname% 」になってしまうのです。

これを回避できる方法はあるみたいなのですが、
パーマリンクら辺をプラグインでいじってしまうと、後々のWordPressのバージョンアップとかで色々面倒になりそうな予感もしたので、ひとまず今のデフォルト仕様に沿うことにします。

結局、固定ページをカスタム投稿タイプの基点ページ(カスタム投稿タイプのTOPページ)として使用する場合、jobという固定ページを作り、そのページに出力させるカスタム投稿タイプはjobinfoというスラッグにして、スラッグ名称の回避をしました。現状、たぶんこれしかベストな方法がないんですね^^;

ややこしいんですが、このバグの原因は自分の単なるイージーミスです。

注意点

注意点として、一度カスタム投稿タイプ用の固定ページとページネーション、カスタム投稿タイプ用のsingleページを繋げた後、カスタム投稿タイプの素であるfunctions.php記述内(今回だとcustom-post-type.php)の記述を変更した場合(カスタム投稿タイプの名称を変えたりした時など)、管理画面のパーマリンク設定から「カテゴリーベースの入力欄」に何か文字を入れたりして一度違う内容で保存、そして入力した文字を消して再度保存し直す、という行為が必要な場合があります。
これをしないとキャッシュが残っているのか、パーマリンクが正常に動作しなく、記述は合っているのに404エラーを返すことがあるからです。

カスタムタクソノミーを出力するには

ここまで書いたので、ついでに書いておきます。

オリジナルで作ったカスタムタクソノミーリストの出力には

<?php echo get_the_term_list( $post->ID,'jobinfo_tag',' ' ); ?>

などで行います。
また、

<?php echo  get_the_term_list( $post->ID, 'jobinfo_tag', '<ul><li>','</li><li>','</li></ul>' ); ?>

など、タクソノミーリストも色々な区切りでも出力できるんですね。

今回は随分長くなりましたが、これでもカスタム投稿タイプはまだ完全じゃない気もします。月別アーカイブとかは仕様上まだ微妙ですし^^;

コメント一覧

コメントは承認制をとっておりまして、運営者の判断にて承認いたしますことをご了承ください。誹謗中傷等は削除させて頂きます。また、ご返信が遅れる場合もあります。

  • この記事、大変参考になりました。ありがとうございます。
    ただ、「カスタム投稿タイプの管理画面の投稿一覧に項目を追加したい」のサンプルコードですが、記事の流れからすると、 jobinfo_area は jobinfo_category、jobinfo_type は jobinfo_tag にしたほうが、スムーズだと思います(あるいは、先出の方を変えたほうが意味的にはきれいかもしれませんが)。

    通りすがり

    2012-01-14 / 1:33 PM

  • カスタム投稿タイプの管理画面の投稿一覧に項目を追加したい を参考にさせて頂き、
    カスタム投稿タイプを2つ設置し、fanction.phpに追記しましたが画面が真っ白になってしまします。
    複数のカスタム投稿タイプやカスタムタクソノミーを使う場合には、同じように追記で作ってやれば良いです。もちろん変数名とか被らないようにしましょう。

    ということですが、具体的にどの変数名を重ならない酔おうにすればよろしいのですか?
    初歩的な質問で申し訳ございません。

    pivotak

    2012-02-25 / 11:12 PM

トラックバック一覧

トラックバックURL

コメントを残す

メールアドレスが公開されることはありません。