The publish_post
hook is one I’ve seen a lot in tutorials and such. Even has its own page in the codex.
But surprise! That hook doesn’t actually exist, at least not if you search for do_action\(\s?.publish_post
.
When I was learning to dig into core, this baffled me. What was this publish_post sorcery? Why wouldn’t it work on my custom post types???
Here’s a secret: The actual hook in core looks like this "{$new_status}_{$post->post_type}"
. It’s part of a small function in wp-includes/post.php
(line 3321 at the time of writing), and there’s another equally useful variable hook right before it.
function wp_transition_post_status($new_status, $old_status, $post) { do_action('transition_post_status', $new_status, $old_status, $post); do_action("{$old_status}_to_{$new_status}", $post); do_action("{$new_status}_{$post->post_type}", $post->ID, $post); }
There are quite a few of these variable hooks in core, I encourage you to go look at them, here’s a list I scraped together:
Actions
"add_option_{$option}" "add_site_option_{$option}" "add_{$meta_type}_meta" "added_{$meta_type}_meta" "admin_head-$hook_suffix" "admin_head-$hook_suffix"); "admin_head_{$content_func}" "admin_print_scripts-$hook_suffix" "admin_print_scripts-$hook_suffix"); "admin_print_styles-$hook_suffix" "admin_print_styles-$hook_suffix"); "after-{$taxonomy}-table" "after_plugin_row_$plugin_file" "after_theme_row_$stylesheet" "comment_{$new_status}_{$comment->comment_type}" "comment_{$old_status}_to_{$new_status}" "create_$taxonomy" "created_$taxonomy" "delete_$taxonomy" "delete_option_$option" "delete_site_option_{$option}" "delete_{$meta_type}_meta" "delete_{$meta_type}meta" "deleted_{$meta_type}_meta" "deleted_{$meta_type}meta" "edit_$taxonomy" "edited_$taxonomy" "get_template_part_{$slug}" "in_plugin_update_message-{$file}" "in_theme_update_message-{$theme_key}" "install_plugins_$tab" "install_plugins_pre_$tab" "install_themes_pre_{$tab}" "install_themes_{$tab}" "manage_{$post->post_type}_posts_custom_column" "media_upload_$tab"); "media_upload_$type"); "save_post_{$post->post_type}" "update-custom_{$action}" "update_option_{$option}" "update_site_option_{$option}" "update_{$meta_type}_meta" "updated_{$meta_type}_meta" "{$new_status}_{$post->post_type}" "{$old_status}_to_{$new_status}" "{$taxonomy}_add_form" "{$taxonomy}_add_form_fields" "{$taxonomy}_pre_add_form" "{$taxonomy}_pre_edit_form" "{$taxonomy}_term_new_form_tag"
Filters
"_wp_post_revision_field_$field" "add_{$meta_type}_metadata" "async_upload_{$type}" "auth_post_meta_{$meta_key}" "blog_option_{$option}" "bulk_actions-{$this->screen->id}" "comment_form_field_{$name}" "current_theme_supports-{$feature}" "customize_sanitize_js_{$this->id}" "customize_sanitize_{$this->id}" "delete_{$meta_type}_metadata" "edit_$field" "edit_post_{$field}" "edit_term_{$field}" "edit_user_{$field}" "edit_{$field}" "edit_{$taxonomy}_{$field}" "extra_{$context}_headers" "get_$taxonomy" "get_the_generator_{$type}" "get_user_option_{$option}" "get_{$adjacent}_post_join" "get_{$adjacent}_post_sort" "get_{$adjacent}_post_where" "get_{$meta_type}_metadata" "install_plugins_table_api_args_$tab" "manage_taxonomies_for_{$post_type}_columns" "manage_{$post_type}_posts_columns" "manage_{$this->screen->id}_sortable_columns" "manage_{$this->screen->taxonomy}_custom_column" "nav_menu_items_{$post_type_name}" "option_page_capability_{$option_page}" "post_type_labels_{$post_type}" "post_{$field}" "postbox_classes_{$page}_{$id}" "pre_$field" "pre_post_{$field}" "pre_term_{$field}" "pre_user_{$field}" "pre_{$field}" "pre_{$taxonomy}_{$field}" "sanitize_option_{$option}" "sanitize_{$meta_type}_meta_{$meta_key}" "shortcode_atts_{$shortcode}" "term_links-$taxonomy" "term_{$field}" "term_{$field}_rss" "theme_action_links_$stylesheet" "theme_mod_{$name}" "update_{$meta_type}_metadata" "user_{$field}" "user_{$name}_label" "views_{$this->screen->id}" "wp_nav_menu_{$menu->slug}_items" "{$adjacent}_image_link" "{$adjacent}_post_link" "{$adjacent}_post_rel_link" "{$boundary}_post_rel_link" "{$field_no_prefix}_edit_pre" "{$field_no_prefix}_save_pre" "{$field}_pre" "{$taxonomy}_row_actions" "{$taxonomy}_{$field}" "{$taxonomy}_{$field}_rss" "{$type}_template"