独自のステータスを追加する
WordPressの投稿や固定ページには、「公開」「下書き」「レビュー待ち」「非公開」のようなステータスがあります。
WordPress本体には投稿や固定ページにステータスを追加するための register_post_status()
という関数が用意されていますが、これを使ってステータスを追加しても
- 投稿画面のステータスのプルダウンにステータスを追加してくれない (自力でする)
- そもそもCodexが「This function does NOT add the registered post status to the admin panel. This functionality is pending future development. (この関数は、登録された投稿ステータスを管理画面に追加しません。その機能はまだ開発されていません。)」と言っている
- がんばって自力で追加しても、「下書きとして保存」ボタンなどの表示調整も自力でする必要がある
- 投稿一覧のクイック編集にあるステータスのプルダウンにステータスを追加してくれない (自力でする)
- 特定の投稿タイプにのみステータスを追加するようなことができない (自力でする)
という課題があります。
整合性をしっかり取ってステータスを追加するのは2016年時点ではかなり大変だと思うので、カテゴリーやタグ、カスタムタクソノミーで代用できるならそうしたほうがよいのではと思います。
一例
どういう対応が必要になってくるのか、参考のために一例を記載します。(もしもっと簡単な方法があれば教えて下さい)
例として、「投稿に『公開候補 (candidate)』という公開直前の最終チェック用のステータスを追加する」(レビュー待ちに近い、関係者向けステータス)ケースの対応を行います。この対応のためには、functions.phpに下記のように記載します。
※ このコードはWordPress 4.4 (4.4.2)での確認をしていますが、他のバージョンで上手く動く保証はありません。
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
/** * 独自のステータスを追加します。(例: 公開候補(candidate)) */ function init_custom_status() { register_post_status( 'candidate', array( // ステータスの表示名 'label' => '公開候補', // 公開するステータスの場合はpublic, ログインユーザーのみの場合はprotected 'protected' => true, // 管理画面に表示するテキスト 'label_count' => _n_noop( '公開候補 <span class="count">(%s)</span>', '公開候補 <span class="count">(%s)</span>' ), ) ); } add_action( 'init', 'init_custom_status' ); /** * 投稿画面のステータスに独自のステータスを追加します。 */ function post_submitbox_custom_status() { global $post; $screen = get_current_screen(); // 投稿以外の投稿タイプは中断 if ( 'post' != $screen->post_type ) return; ?><script> jQuery(function($){ // プルダウンにステータスを追加します。 var postStatus = $('#post_status'); postStatus.append('<option value="candidate">公開候補</option>'); <?php // 投稿ステータスが標準以外のステータスの場合、ステータス表示を調整します。 if ( ! in_array( $post->post_status, array('public', 'private', 'pending', 'draft', 'auto-draft'), true ) ) { ?> postStatus.val('<?php echo esc_js( $post->post_status ) ?>'); $('#post-status-display').html($('option:selected', postStatus).text()); <?php } ?> // 各操作がされた際に「下書きとして保存」ボタンのテキストを変更します。 // (wp-admin/js/post.jsのupdateText()に外から手を入れられないため、1秒ごとに監視して調整します) var updateTextEx = function(){ if ( $('option:selected', postStatus).val() == 'candidate' ) { $('#post-status-display').html($('option:selected', postStatus).text()); $('#save-post').show().val( '公開候補として保存' ); } }; updateTextEx(); setInterval(updateTextEx, 1000); }); </script><?php } add_action( 'post_submitbox_misc_actions', 'post_submitbox_custom_status' ); /** * クイック編集のステータスに独自のステータスを追加します。 */ function inline_edit_custom_status() { $screen = get_current_screen(); // 投稿以外の投稿タイプは中断 if ( 'post' != $screen->post_type ) return; ?><script> jQuery(function($){ var postStatus = $('[name=_status]'); postStatus.append('<option value="candidate">公開候補</option>'); }); </script><?php } add_action( 'admin_footer-edit.php', 'inline_edit_custom_status' ); /** * 投稿一覧のステータスリンクの並びを変更します。(変更しないと独自のステータスがゴミ箱より後になる) */ function views_edit_custom_status($views) { if ( isset($views['trash']) ) { $trash = $views['trash']; unset($views['trash']); $views['trash'] = $trash; } return $views; } add_filter( 'views_edit-post', 'views_edit_custom_status' ); // 投稿一覧 /** * 「すべて」の投稿一覧の際に投稿タイトルの脇に表示されるステータス表示を追加します。 */ function display_post_states_custom_status( $states ) { global $post; $status = get_query_var( 'post_status' ); if ( 'candidate' != $status && 'candidate' == $post->post_status ) { return array( '公開候補' ); } return $states; } add_filter( 'display_post_states', 'display_post_states_custom_status' ); |
結果
(投稿一覧。「公開候補」というステータスが追加されています)
(クイック編集)
(投稿画面。ステータス表示、プルダウン、ボタンが調整されます。ボタンはステータスによって名前が変わりますが、本体側がこの部分を拡張できるように作っていないため、表示が不自然になるときがあります)
公開日が自動でセットされないようにする
下書きやレビュー待ち、自動保存で保存した場合は、公開日が設定されていなければ公開日はセットされないようになっています(その他のステータスでは公開日が設定されていないと自動的に現在日時がセットされます)。独自のステータスでも公開日が自動でセットされないようにしたい場合は、functions.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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
/** * 下書きやレビュー待ち、自動保存と同じように公開日が自動でセットされないようにします。 */ function wp_insert_post_data_custom_status( $data, $postarr ) { // 更新かどうか(wp_update_post()内の判定と同じ) $update = ! empty( $postarr['ID'] ); // 更新時、前のステータスが公開候補で、公開日が明示的にセットされていなければ公開日をクリアします。(現在日時にセットし直す) // (wp_update_post()のdraft, pending, auto-draftの挙動に合わせる) $clear_date = false; if ( $update ) { $post = get_post($postarr['ID'], ARRAY_A); if ( isset( $post['post_status'] ) && in_array($post['post_status'], array( 'candidate' )) && empty($postarr['edit_date']) && ('0000-00-00 00:00:00' == $post['post_date_gmt']) ) $clear_date = true; else $clear_date = false; if ( $clear_date ) { $postarr['post_date'] = current_time('mysql'); $postarr['post_date_gmt'] = ''; } } // 公開日をクリアした場合、またはステータスが公開候補の場合は日付関連のデータを再調整します。 $post_status = empty( $postarr['post_status'] ) ? 'draft' : $postarr['post_status']; if ( $clear_date || 'candidate' == $post_status ) { // 公開日がセットされていない場合、現在日時またはpost_date_gmtからのローカルの日時をセットします。 // (wp_insert_post()の挙動に合わせる) if ( empty( $postarr['post_date'] ) || '0000-00-00 00:00:00' == $postarr['post_date'] ) { if ( empty( $postarr['post_date_gmt'] ) || '0000-00-00 00:00:00' == $postarr['post_date_gmt'] ) { $post_date = current_time( 'mysql' ); } else { $post_date = get_date_from_gmt( $postarr['post_date_gmt'] ); } } else { $post_date = $postarr['post_date']; } // post_date_gmtが未設定の場合、初期値をセットします。 // (下書きなどと同じように投稿画面上で公開日が表示されないようにするには // post_date_gmtを0000-00-00 00:00:00にしておく必要がある) if ( empty( $postarr['post_date_gmt'] ) || '0000-00-00 00:00:00' == $postarr['post_date_gmt'] ) { if ( ! in_array( $post_status, array( 'candidate' ) ) ) { $post_date_gmt = get_gmt_from_date( $post_date ); } else { $post_date_gmt = '0000-00-00 00:00:00'; } } else { $post_date_gmt = $postarr['post_date_gmt']; } // 更新で公開日がセットされていない場合、更新日を調整 // (wp_insert_post()の挙動に合わせる) if ( $update || '0000-00-00 00:00:00' == $post_date ) { $post_modified = current_time( 'mysql' ); $post_modified_gmt = current_time( 'mysql', 1 ); } else { $post_modified = $post_date; $post_modified_gmt = $post_date_gmt; } // 変更した日時データを保存データとしてセット $new_data = compact( 'post_date', 'post_date_gmt', 'post_modified', 'post_modified_gmt' ); $data = array_merge($data, $new_data); } return $data; } add_filter( 'wp_insert_post_data', 'wp_insert_post_data_custom_status', 10, 2 ); |
その他
- 「投稿ステータスにオリジナルのステータスを追加する | WEBPAPRIKA」さんで紹介されているものは大元のブログ(「Custom Post Status Creation | WordPress | James Collings」)が2013年のためか手元の環境では上手く動かせませんでした…
更新履歴
- 2016/08/03 「公開日が自動でセットされないようにする」のコードで、公開日を設定せずに公開ボタンを押した時に公開日が現在日時にならない問題を修正しました。
- 2016/07/11 「公開日が自動でセットされないようにする」を追加しました。
- 2016/04/17 「Custom Post Status Creation | WordPress | James Collings」さんを参考に、「すべて」の投稿一覧の際に投稿タイトルの脇に表示されるステータス表示を追加しました。また、WordPress 4.5で確認した上説明やスクリーンショットなどを少し修正しました。
- 2016/04/11 初版