How to add post meta data before it has been saved or published? Can’t use transitional hooks. After digging through code, you have to use add_meta_boxes action.
Let’s say you have a custom post type book. Each book has several properties (meta data), such as the author, the publisher and the publication date. Now, WordPress has a nice feature called Custom Fields. It is an interface for adding meta data to your posts: a meta key on left and meta value on right. When a new book is created, however, Custom Fields are empty because no meta data has been added to the book yet. The question is: how can we add custom meta data to a post (book) before it has been saved as a draft or published?
add_post_meta function
If we want to add a post meta programmatically, WordPress has a function add_post_meta to do it. The first thought I got was to call this function on each admin_init
. There are two problems with this approach:
- I don’t know the current post ID.
add_post_meta()
queries the database each time it is run (heavy to use).
We need to find a better action hook. Something when a new post of a specific post type is being created.
Finding the right hook
After searching the Internet, I found exactly nothing. There are some Post Status Transitions hooks which are run when saving a post. However, we need to add the meta data before the post (book in our case) is saved, right after we click on ‘Add New’, so the Custom Fields meta box will be populated with the predefined meta data.
When we click on ‘Add New’, we can notice that wp-admin/post-new.php file is loaded. Looking through the file, we can see that before including the form for writing a new post, the function get_default_post_to_edit()
is called. Parameter $create_in_db = true
causes the function to call wp_insert_post()
, which inserts a new post to the database. It means that WordPress automatically creates a post (or a book in our case) before it has been saved or published by us. The post has the status auto-draft. The post needs to be created before we can add meta data to it because they are attached to it by its ID so this behavior helps us.
Scanning the wp-admin/edit-form-advanced.php, we can find the function which adds the Custom Fields meta box:
if ( post_type_supports($post_type, 'custom-fields') ) add_meta_box('postcustom', __('Custom Fields'), 'post_custom_meta_box', null, 'normal', 'core');
There are no usable hooks before this function is run, only afterward. Luckily, the add_meta_box function does not output the Custom Fields meta box right when it is called. It is fired later in the file, with the do_action( 'do_meta_boxes' )
actions.
add_meta_boxes
Between the time the Custom Fields meta box is added and outputted, there are two action hooks: [add_meta_boxes](https://codex.wordpress.org/Plugin_API/Action_Reference/add_meta_boxes%5D and add_meta_boxes_ . $post_type
. Great! We are interested only in the second hook because it is run only for a specific post type (book).
So, open up your functions.php or any other PHP file and add following code:
add_action( 'add_meta_boxes_books', 'lamosty_add_book_meta_data' );
We are hooked into the action. Now, we need to define the function which adds the meta data for us. I called it lamosty_add_book_meta_data()
. Here is its code:
function lamosty_add_book_meta_data( WP_Post $book ) { // Add the meta data you want the custom post type to have $book_meta_data = [ 'author', 'publisher', 'publication_date' ]; foreach ( $book_meta_data as $meta ) { add_post_meta( $book->ID, $meta, '', true ); } }
The add_meta_boxes_books action passes one argument — the actual post. We add a few meta keys to an array an loop through it, calling the add_post_meta
function. Notice the third parameter. It is set to true
. It means that the meta data should be unique so it won’t be added multiple times when we edit the post (book) again.
Hi Rastislav, thanks ! I also needed this and your article helped a lot !!
LikeLike