WordPressでカスタムタクソノミーを利用する際、そのまま特にカスタマイズ等もせずにタクソノミーを選択していない状態で記事公開するとタクソノミーが未設定状態となりますが、それを回避したいというときに使えるカスタマイズです。
デフォルト投稿タイプの「投稿」では、カテゴリーを選択し忘れたとしても「設定 > 投稿設定」にある「投稿用カテゴリーの初期設定」で設定しているカテゴリーが自動的に適用されますが、カスタムタクソノミーの場合はそういったものが用意されていません。
投稿者が忘れずに設定をするとか「WordPress:投稿画面でタイトル、コンテンツ、カテゴリー選択、アイキャッチなどを入力必須にする方法」で紹介しているようなバリデーション機能をつけたりすることで防ぐことも十分できるのですが、なにか良い方法ないかと思い試してみた方法を紹介します。
記事作成時に特定のタクソノミーにチェックを入れてしまう
方法としてはそのカスタム投稿でデフォルトとしたい特定のタクソノミーに記事の新規作成のタイミングであらかじめチェックを入れてしまい、タクソノミーがひとつも選択されていない状態で記事が投稿されるのを防ぐという方法になります。
チェックを入れる動きについてはjQueryを使用し、実装にはテーマ内のfunctions.php
に下記のように記述します。
add_action( 'admin_head-post-new.php', 'default_taxonomy_select' );
function default_taxonomy_select() {
?>
<script type="text/javascript">
jQuery(function($) {
$('#post_type_name-categorychecklist li:first-child input[type="checkbox"]').prop('checked', true);
});
</script>
<?php
}
上記記述後にタクソノミーがあるカスタム投稿で記事を作成しようとすると、タクソノミー選択部分の先頭にあるタクソノミーにチェックが入っているのを確認できます。
動きとしてはタクソノミー選択部分にあるチェックボックスにチェックを入れているだけで、ここではひとまず先頭のタクソノミーということでli:first-child input[type="checkbox"]
と指定して、一番上にあるタクソノミーへチェックが入るようにしています。
別のタクソノミーにチェックを入れたい場合はli:first-child
の部分を:nth-child()
を使用するなどして任意で変更するか、<input type="checkbox">
にそれぞれ付与されているidを用いて直接指定するなどして変更できます。
また、li
の前に#post_type_name-categorychecklist
と記述しているように、カスタム投稿でタクソノミーを設定する箇所に使用されているid名を調べる必要もあります。
調べると言っても基本的に上記サンプルコードでpost_type_name
としている箇所がカスタム投稿名になっていると思うので、この動きを実装したいカスタム投稿名に変更してもらえばいいと思いますが、上手く動作しないようであればデベロッパーツール等でどのようなidがついているかを直接確認してください。
デフォルトの投稿と同じようにしたい場合
とにかくタクソノミーが未選択状態になってしまうのを回避したかったので一旦上で紹介した方法を実装しようと思ったのですが、少し調べてみたら「Simple Colors」さんで紹介されている方法がデフォルトの動きに合わせた感じで良かったので、結局こちらを参考に利用させてもらうことにしました。
function add_default_term_setting_item() {
$post_types = get_post_types( array( 'public' => true, 'show_ui' => true ), false );
if ( $post_types ) {
foreach ( $post_types as $post_type_slug => $post_type ) {
$post_type_taxonomies = get_object_taxonomies( $post_type_slug, false );
if ( $post_type_taxonomies ) {
foreach ( $post_type_taxonomies as $tax_slug => $taxonomy ) {
if ( ! ( $post_type_slug == 'post' && $tax_slug == 'category' ) && $taxonomy->show_ui ) {
add_settings_field( $post_type_slug . '_default_' . $tax_slug, $post_type->label . '用' . $taxonomy->label . 'の初期設定' , 'default_term_setting_field', 'writing', 'default', array( 'post_type' => $post_type_slug, 'taxonomy' => $taxonomy ) );
}
}
}
}
}
}
add_action( 'load-options-writing.php', 'add_default_term_setting_item' );
function default_term_setting_field( $args ) {
$option_name = $args['post_type'] . '_default_' . $args['taxonomy']->name;
$default_term = get_option( $option_name );
$terms = get_terms( $args['taxonomy']->name, 'hide_empty=0' );
if ( $terms ) :
?>
<select name="<?php echo $option_name; ?>">
<option value="0">設定しない</option>
<?php foreach ( $terms as $term ) : ?>
<option value="<?php echo esc_attr( $term->term_id ); ?>"<?php echo $term->term_id == $default_term ? ' selected="selected"' : ''; ?>><?php echo esc_html( $term->name ); ?></option>
<?php endforeach; ?>
</select>
<?php
else:
?>
<p><?php echo esc_html( $args['taxonomy']->label ); ?>が登録されていません。</p>
<?php
endif;
}
function allow_default_term_setting( $whitelist_options ) {
$post_types = get_post_types( array( 'public' => true, 'show_ui' => true ), false );
if ( $post_types ) {
foreach ( $post_types as $post_type_slug => $post_type ) {
$post_type_taxonomies = get_object_taxonomies( $post_type_slug, false );
if ( $post_type_taxonomies ) {
foreach ( $post_type_taxonomies as $tax_slug => $taxonomy ) {
if ( ! ( $post_type_slug == 'post' && $tax_slug == 'category' ) && $taxonomy->show_ui ) {
$whitelist_options['writing'][] = $post_type_slug . '_default_' . $tax_slug;
}
}
}
}
}
return $whitelist_options;
}
add_filter( 'whitelist_options', 'allow_default_term_setting' );
function add_post_type_default_term( $post_id, $post ) {
if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || $post->post_status == 'auto-draft' ) { return; }
$taxonomies = get_object_taxonomies( $post, false );
if ( $taxonomies ) {
foreach ( $taxonomies as $tax_slug => $taxonomy ) {
$default = get_option( $post->post_type . '_default_' . $tax_slug );
if ( ! ( $post->post_type == 'post' && $tax_slug == 'category' ) && $taxonomy->show_ui && $default && ! ( $terms = get_the_terms( $post_id, $tax_slug ) ) ) {
if ( $taxonomy->hierarchical ) {
$term = get_term( $default, $tax_slug );
if ( $term ) {
wp_set_post_terms( $post_id, array_filter( array( $default ) ), $tax_slug );
}
} else {
$term = get_term( $default, $tax_slug );
if ( $term ) {
wp_set_post_terms( $post_id, $term->name, $tax_slug );
}
}
}
}
}
}
add_action( 'wp_insert_post', 'add_post_type_default_term', 10, 2 );
エントリー内で紹介されている上記コードをfunctions.php
に記述すれば、デフォルトの投稿カテゴリーと同じように「設定 > 投稿設定」にある「投稿用カテゴリーの初期設定」下に各タクソノミーの初期設定をするためのプルダウンが追加され、投稿のカテゴリー未選択時と同じ挙動でデフォルトのタクソノミーを設定することができます。