Skip to content
WJunction - Webmaster Forum

Hook when Post created

Status
Not open for further replies.
Hi everyone,

I have added these codes in functions.php

Code:
function assign_post_to_category($post_id, $post, $update) {
    // Run only when a new post is created, not when updated
    if (get_post_type($post_id) !== 'post') {
        return;
    }

    $post_title = get_the_title($post_id); // Get post title

    // Split the title by the dot (.)
    $title_parts = explode('.', $post_title);

    // Get the first part
    $first_word = trim($title_parts[0]);

    $category_name = trim($title_parts[0]); // Change this to your desired category name

    // Check if the category exists
    $category_id = get_term_by('name', $category_name, 'category');
    
    // If category doesn't exist, create it
    if (!$category_id) {
        $category_id = wp_insert_term($category_name, 'category');
        if (is_wp_error($category_id)) {
            return; // If there's an error, stop execution
        }
        $cat = get_term_by( 'name', $category_name, 'category' );
        $category_id = $cat->term_id;
    } else {
        $category_id = $category_id->term_id;
    }

    $extra_categories = [$category_id];
    
    // Get current categories
    $existing_categories = wp_get_post_categories($post_id);
    
    // Assign the post to the category
   // Merge and set categories
    wp_set_post_categories($post_id, array_unique(array_merge($existing_categories, $extra_categories)));
}

add_action('publish_post', 'assign_post_to_category');

What I want to achieve is that I want to assign post to new/existing category.

But it seems, code can create new category but not assign post to it.

Can you please review and share what I'm doing wrong?

Thank you
 

3 comments

The problem isn't with creating the category (which actually works), but rather with the moment the assignment takes place.
You are using the `publish_post` hook. When you save a post from the block editor (Gutenberg), the save process goes through the REST API, and the sequence is as follows:

WordPress calls `wp_insert_post()`; this triggers `publish_post`, and your code correctly sets the categories;
immediately afterwards, the REST controller calls `handle_terms()`, which overwrites the post's taxonomies based on what the editor sent (usually just "Uncategorized").

So, your `wp_set_post_categories()` executes, but it gets overwritten a moment later. That is why the category is created but the post ends up unassigned. (Your code would work with the Classic Editor, which confirms this diagnosis.)
The solution is to hook into `wp_after_insert_post`, which was introduced specifically for this purpose: it runs after the post, terms, and meta data have been permanently saved, in both the classic and REST workflows.
Here is the complete, ready-to-use file:
Code:
function assign_post_to_category( $post_id, $post, $update, $post_before ) {
    // Skip autosaves and revisions
    if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) ) {
        return;
    }

    // Only for published posts
    if ( $post->post_type !== 'post' || $post->post_status !== 'publish' ) {
        return;
    }

    // Uncomment if you want it to run only on newly created posts
    /*
    if ( $update ) {
        return;
    }
    */

    $post_title = $post->post_title;

    if ( empty( $post_title ) ) {
        return;
    }

    // Get the part before the first dot
    $title_parts   = explode( '.', $post_title );
    $category_name = trim( $title_parts[0] );

    if ( $category_name === '' ) {
        return;
    }

    // Check if the category already exists
    $term = get_term_by( 'name', $category_name, 'category' );

    if ( ! $term ) {
        // Create the category if it doesn't exist
        $new_term = wp_insert_term( $category_name, 'category' );

        if ( is_wp_error( $new_term ) ) {
            return;
        }

        $category_id = (int) $new_term['term_id'];
    } else {
        $category_id = (int) $term->term_id;
    }

    // Merge with existing categories and assign
    $existing   = wp_get_post_categories( $post_id );
    $categories = array_unique( array_merge( $existing, array( $category_id ) ) );

    wp_set_post_categories( $post_id, $categories );
}

add_action( 'wp_after_insert_post', 'assign_post_to_category', 10, 4 );
 
Status
Not open for further replies.

About the author

A
Active Member · Joined
122
Messages
49
Reactions
28
Points

Advertise on WJunction

Reach 1000's of webmasters, hosts & affiliates. Banner & sponsored-thread slots available.

Contact us
Back
Top Bottom