タイトル通りですが、WordPress プラグインで、カスタム投稿タイプを取得できずに苦戦してしまった話です。
カスタム投稿タイプが登録されるタイミングは?
カスタム投稿タイプの情報は、データベースに登録されている訳ではありません
そのためデータベースが吹き飛んだとしても、管理画面にあるカスタム投稿タイプは残ります(プラグインなどで登録している場合は、設定をデータベースに保存していることがほとんどなので一緒に消えます)。
カスタム投稿タイプは、register_post_type()
で登録します。
register_post_type()
でカスタム投稿タイプを登録するタイミングは実装者によってまちまちかもしれませんが、例えばinit()
アクションの時に登録していたとします。init()
が呼ばれるのはいつでしょうか?
フックの順番
muplugins_loaded
registered_taxonomy
registered_post_type
plugins_loaded
sanitize_comment_cookies
setup_theme
load_textdomain
after_setup_theme
auth_cookie_malformed
auth_cookie_valid
set_current_user
init <- ここ
widgets_init
register_sidebar
wp_register_sidebar_widget
wp_default_scripts
wp_default_stypes
admin_bar_init
add_admin_bar_menus
wp_loaded
parse_request
send_headers
parse_query
pre_get_posts
posts_selection
wp
template_redirect
get_header
wp_head
wp_enqueue_scripts
wp_print_styles
wp_print_scripts
…そのほかたくさん
つまり、init()
よりも上流のフックでカスタム投稿タイプを取得するget_post_type_object()
を呼び出したとしても、WordPress には「そんな投稿タイプないよ」と言われてしまいます。
同じフックに登録すると登録順に実行される
では、init()
時にget_post_type_object()
を実行するとどうなるか? これは見出しの通り、書いた順になります。
<?php
function my_get_post_type() {
var_dump( get_post_type_object() );
}
add_action( 'init', 'my_get_post_type' );
function my_register() {
... 投稿タイプを登録 ...
}
add_action( 'init', 'my_register' );
?>
こんなコードを書くことは無いと思いますが、
- my_get_post_type … 投稿タイプを取得する
- my_register … 投稿タイプを登録する
この2つの関数はどちらもinit()
時に実行されます。今の状態 だと書いた順で実行されるので、my_get_post_type()
の実行後にmy_register()
が実行される形です。
実行順序を逆にしたい場合、並び替えるだけで対応できますが、数が多かったりファイルが分割されていたりすると、順番が分かりにくくなります。
解決策:実行の優先度を設定する
add_action()
では同じフックに登録しているものに対して、第三引数で順番を設定できるようになっています。
<?php
function my_get_post_type() {
var_dump( get_post_type_object() );
}
add_action( 'init', 'my_get_post_type', 100 );
function my_register() {
... 投稿タイプを登録 ...
}
add_action( 'init', 'my_register' );
?>
優先度は数値が大きければ大きいほど低くなります。初期値は 10 となっているため、設定しなければ全て 10 になります。
上記の例では
- my_get_post_type … 100
- my_register … 10
となるため、my_register
の実行後にmy_get_post_type
が実行される、という順序になります。