I'm trying to hook on save_post to automatically assign a category (from a custom field) on post update and creation. Basically if the date event is 10/10/2020 - I want to assign the event to category '2020'.

So far, it's partially working because I actually have to hit the 'update' button twice to make it works. I'm stucked here for now. Being not much proefficient with PHP or WP wizardy, I've tried to document as best as I could.

If can help I also have debug logs here : https://pastebin.com/HQ9B6JqZ?fbclid=IwAR1Ag9_yekNMByN4Dim3BZPJ6ALdIPwQ77hP36W5Ht13QekpkuaofuoLlzY

 * Create or update category for each event creation or udate
 * @param int $post_id The post ID.
 * @param post $post The post object.
 * @param bool $update Whether this is an existing post being updated or not.
function save_event( $post_id, $post, $update ) {
    $id = $post_id;

    // If this isn't a 'book' post, don't do anything.
    $post_type = get_post_type($post_id);
    if ( "event" != $post_type ) return;

    // Check if year has been defined
    $date = get_field('event_date', $post_id, false);
    if (empty($date)) {
        write_log( "Event date is not defined yet" );

    // Extract event's year 
    $date = new DateTime($date);
    $year = $date->format('Y');

    // Get existing category
    $current_cats = get_the_category($post_id);
    if ( ! empty( $current_cats ) ) {
        $current_cat_name = esc_html( $current_cats[0]->name ); 
        write_log( "Current category in use : {$current_cat_name}");

        if ( ! empty($current_cat_name) && $year === $current_cat_name) {
        write_log( "Matching existing category with event date");

    // Does the category exist? Should we create it?
    $category_id = get_cat_ID($year);
    if ( $category_id === 0) {
        $category_id = wp_create_category( $year );
        write_log( "Creating category : ({$year}) with ID of {$category_id}");
    } else {
        write_log( "Found category ({$year}) with ID of {$category_id}");

    // Assign the category
    $event_categories = array($category_id);
    $post_categories = wp_set_post_categories( $id, $event_categories);
    write_log( "A new category ({$year} - {$category_id} )  has been assigned to post {$id}");
    write_log( json_encode($post_categories) );

add_action( 'save_post', 'save_event', 10, 3 );
  • Can you give some more details on what you're trying to accomplish? Commented Apr 9, 2019 at 22:33
  • @MikeNGarett, sure. I basically need my custom post type (events) to be assigned the category of the event date (if the event is 2020, event shoud be assigned to '2020' category) because my front end need it to display. Users could actually do this manually but I'd like to automate (it's likely they will forget to do it) Commented Apr 11, 2019 at 8:24

2 Answers 2


After getting year, you may check if category exists using


if not found then create category using

 wp_create_category( $cat_name, $parent );

after that you may create post using

$my_post = array(
  'post_title'    => wp_strip_all_tags( $_POST['post_title'] ),
  'post_content'  => $_POST['post_content'],
  'post_status'   => 'publish',
  'post_author'   => 1,
  'post_category' => array( 8,39 )

// Insert the post into the database
wp_insert_post( $my_post );

You may also add category to a existing post using


more information:
https://developer.wordpress.org/reference/functions/wp_insert_post/ https://codex.wordpress.org/Function_Reference/wp_create_category https://developer.wordpress.org/reference/functions/category_exists/

  • The question highlights an issue where the update button needs to be clicked twice in order for the change to take effect, so your answer is more likely to be considered if you address this problem. The question also provides working code to check for the existence of categories so although your provided references are useful they don't appear to provide a solution Commented Apr 11, 2019 at 10:32
  • That's correct, the script is actuallly successful but changes are not reflected through the backend (I have to click on 'update' button twice) - see my answer below Commented Apr 11, 2019 at 14:21

So I've tried with set_object_terms() instead of wp_set_post_categories() but it's pretty much the same.

I've tried to dump almost everything I could : - $post_id and $post object are always available - post data are not sometimes available trough $_POST (see below)

I realized I couldn't always get my value by using get_field('event_date') or $_POST['acf']['field_5c766105f364e'] but I've found that get_field('event_date', $post_id) consistently returns the right value.

Now what's really odd is that the save_post() is triggered three times at each 'update' click.. and the logs tell me that the second one is sucessfull. There others tell me the category is already assigned to the right category.

So it actually works except I have no clues why : - hook get triggered three times - backend edit page does not reflect updated category (at the first click)

logs https://pastebin.com/dF2Q15Y0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.