すてきな気分〜ナイスフィーリングブログ〜

WordPress(ワードプレス)カスタム投稿タイプのアレコレ

結構浸透しているのは知っていたけど、自分で初めて構築してみたら何気に手強かったWordPressの「カスタム投稿タイプ」。
名前からして「ナンじゃこりゃ???」と若干敬遠してた(^_^;Aけど、理解してみれば、サイト構築の幅がより広がるな〜と実感しました。
実際の導入は、コレまた実地で行くしかないというか、やりたいことを自分で動かしながらでないと解りづらいというか、とにかく手強かったので、ちょっとメモ。

今回のお仕事の場合、カスタムフィールドをカスタマイズしてのデータベース構築と、お客様が日々更新する部分とに分けたかったので、データベースをカスタム投稿タイプ・日々の更新をデフォルト投稿という具合に分離させました。

何はともあれ、カスタム投稿タイプの設定から。
普通はfunctions.phpに書く所だけど、ソースが長くなるので、カスタム投稿タイプ用のファイル(custom-post.php)を別途用意して読み込ませます。

functions.phpに記述

// カスタム投稿タイプ読み込み
include_once ("custom-post.php");

custom-post.phpには以下を記述

<?php
// カスタム投稿タイプ設定(「Webサイト」は例)
function website_custom_post () {
	$labels = array(
		'name' => _x('Webサイト', 'post type general name'),
		'singular_name' => _x('Webサイト', 'post type singular name'),
		'add_new' => _x('Webサイトを追加', 'website'),
		'add_new_item' => __('新しいWebサイトを追加'),
		'edit_item' => __('Webサイトを編集'),
		'new_item' => __('新しいWebサイト'),
		'view_item' => __('Webサイトを編集'),
		'search_items' => __('Webサイトを探す'),
		'not_found' => __('Webサイトはありません'),
		'not_found_in_trash' => __('ゴミ箱にWebサイトはありません'),
		'parent_item_colon' => ''
	);
	$args = array(
		'labels' => $labels,
		'menu_position' => 5,
		'public' => true,
		'publicly_queryable' => true,
		'show_ui' => true,
		'query_var' => true,
		'rewrite' => true,
		'capability_type' => 'post',
		'hierarchical' => false,
		'has_archive' => true,
		'supports' => array('title','editor','thumbnail','custom-fields','excerpt','revisions','page-attributes'),
		'taxonomies' => array('website_category','website_tag')
	);
	register_post_type('website',$args); // 「website」はカスタム投稿タイプ名


// カスタムタクソノミー カテゴリータイプ
	$args = array(
		'label' => 'Webサイトのカテゴリー',
		'labels' => array(
			'name' => 'Webサイトカテゴリ',
			'singular_name' => 'Webサイトカテゴリ',
			'search_items' => 'Webサイトカテゴリを検索',
			'popular_items' => 'よく使われているWebサイトカテゴリ',
			'all_items' => 'すべてのWebサイトカテゴリ',
			'parent_item' => 'Webサイトカテゴリ',
			'edit_item' => 'Webサイトカテゴリの編集',
			'update_item' => '更新',
			'add_new_item' => 'Webサイトカテゴリを追加',
			'new_item_name' => '新しいWebサイトカテゴリ',
		),
		'public' => true,
		'show_ui' => true,
		'hierarchical' => true, // 通常投稿のカテゴリ設定(チェックボックス) ※falseはタグ扱い
	);
	register_taxonomy('color','website',$args); // 「color」はカテゴリ名


// カスタムタクソノミー タグタイプ
	$args = array(
		'label' => '種類タグ',
		'public' => true,
		'show_ui' => true,
		'hierarchical' => false
	);
	register_taxonomy('business','website',$args); // 「business」はタグ名
}
add_action('init', 'website_custom_post');


// 管理画面記事一覧にカスタムタクソノミーの表示追加
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, 'color'); // カテゴリ「色」
	}
	if( 'fcategory2' == $column_name ) {
		$fcategory = get_the_term_list($post_id, 'business'); // タグ「業種」
	}
	if ( isset($fcategory) && $fcategory ) {
		echo $fcategory;
	} else {
		echo __('None');
	}
}
add_filter('manage_edit-website_columns', 'manage_posts_columns');
add_action('manage_posts_custom_column',  'add_column', 10, 2);


// 管理画面でカスタムタクソノミーの検索枠
function todo_restrict_manage_posts() {
	global $typenow;
	$args=array( 'public' => true, '_builtin' => false ); 
	$post_types = get_post_types($args);
	if ( in_array($typenow, $post_types) ) {
	$filters = get_object_taxonomies($typenow);
		foreach ($filters as $tax_slug) {
			$tax_obj = get_taxonomy($tax_slug);
			wp_dropdown_categories(array(
				'show_option_all' => __(''.$tax_obj->label ),
				'taxonomy' => $tax_slug,
				'name' => $tax_obj->name,
				'orderby' => 'term_order',
				'selected' => $_GET[$tax_obj->query_var],
				'hierarchical' => $tax_obj->hierarchical,
				'show_count' => false,
				'hide_empty' => true
			));
		}
	}
}
function todo_convert_restrict($query) {
	global $pagenow;
	global $typenow;
	if ($pagenow=='edit.php') {
		$filters = get_object_taxonomies($typenow);
		foreach ($filters as $tax_slug) {
		$var = &$query->query_vars[$tax_slug];
		if ( isset($var) && $var>0)  {
			$term = get_term_by('id',$var,$tax_slug);
			$var = $term->slug;
		}
		}
	}
	return $query;
}
add_action( 'restrict_manage_posts', 'todo_restrict_manage_posts' );
add_filter('parse_query','todo_convert_restrict');


// ポスト名変更
add_action('init', 'website_rewrite');
function website_rewrite() {
	global $wp_rewrite;  
	$queryarg = 'post_type=website&p=';
	$wp_rewrite->add_rewrite_tag('%website_id%', '([^/]+)',$queryarg);
	$wp_rewrite->add_permastruct('website', '/website/%website_id%.html', false);
}
add_filter('post_type_link', 'website_permalink', 1, 3);
function website_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.'_id%', $post->ID, $newlink);
	$newlink = home_url(user_trailingslashit($newlink));
	return $newlink;
}

これで、通常投稿と同じようなことが、カスタム投稿タイプで実現できる。
あとはカスタムフィールドをカスタマイズして、焼くなり煮るなりしてOK!
通常投稿は関係ないのでお客様を惑わすことなく、更新して頂けるというところまで辿り着きました!長かった・・・ (;´Д`)

でもこれ、優秀なプラグインもアリ。
カスタム投稿タイプの設定は、Types – Complete Solution for Custom Fields and Types。
管理画面の設定は、PS Taxonomy Expander。
この2本を入れれば、上記のことがほぼ実現できる。
個人的には、Custom Post Type UIよりTypesの方がいいかな、と思う。
でも今回はソースを書いたことで、またphpの勉強になった〜!

ちなみに実際の表示は、archive-website.phpに

<ul> 
	<?php while (have_posts()) : the_post(); ?>
	<li><?php wp_list_categories (array('title_li' => '', 'taxonomy' => 'color') ); ?> </li>
	<?php endwhile; ?>
</ul>

とかで一覧表示できるし、単体ページは、single-website.phpで設定。
でもこれ、カスタム設定を変えたら、パーマリンクをカスタムしていたら、一旦デフォルトに戻してあげないと反映されない・・・結構ハマりどころ。(;^ω^)

投稿を独自にカスタマイズできるのでホントに自由度が高いけど、設計はそれなりに考えてしないと結構コワいかも(^_^;Aと感じました。

トラックバック

このエントリーのトラックバックURL:

コメントを残す

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