1

Im looking for a solution in admin panel when admin click on a specific link to add new post automatically select one or more categories based on GET value.

for example if admin click on fallowing link wp-admin/post-new.php?cat=news in the add new post page automatically check the news category in category selection section.

4

If you start to edit a new post, already a post with the status auto-draft is created. Actually, what you see is this post. So you can hook into the transition filter new_to_auto-draft and add a category to this post:

add_action( 'new_to_auto-draft', function(  $post ) {
    // Bail out, if not in admin editor.
    if ( ! strpos( $_SERVER['REQUEST_URI'], 'wp-admin/post-new.php' ) ) {
        return;
    }

    // Bail out, it no category set in $_GET.
    if ( empty( $_GET['cat'] ) ) {
        return;
    }

    $cat = wp_unslash( $_GET['cat'] );

    // Bail out, if category does not exist.
    if ( false === ( $cat = get_category_by_slug( $cat ) ) ) {
        return;
    }

    wp_set_post_categories( $post->ID, array( $cat->term_id ) );

} );

Explanation

As I've said, a post is created in the moment, you open the editor. wp_insert_post() is calling wp_transition_post_status( $new_status, $old_status, $post ) where the $new_status is auto-draft and the old "status" is new. wp_transition_post_status() basically fires three action hooks:

I am using {$old_status}_to_{$new_status} (new_to_auto-draft) because it is the most precise for what you are trying to accomplish.

In the function, where we get the post object as parameter ($post), we bail out if we are not in the correct location or the $_GET['cat'] is not found. With wp_unslash() we remove '\' and stuff from $_GET['cat']. Another possibility would be to use sanitize_key(), maybe it is even more appropriate.

We now load the category object with get_category_by_slug() since we will need the ID of the category to attach the post to the category in wp_set_post_categories(). If the category was not found get_category_by_slug() will return false and we bail out. Another idea would be to create a category with this slug, if the category was not found.

For Custom Post Types and Custom Taxonomies

In response to

This does not seem to work on a custom post type/taxonomy

The above example works explicitly on the post type post and the taxonomy category. If you want to use it with a custom post type and a custom taxononmy, you will need to use get_term_by() instead of get_category_by_slug() and you will need to use wp_set_object_terms() instead of wp_set_post_categories().

The example below registers a post type, a taxonomy and shows the process:

add_action( 'new_to_auto-draft', function(  $post ) {
    // Bail out, if not in admin editor.
    if ( ! strpos( $_SERVER['REQUEST_URI'], 'wp-admin/post-new.php' ) ) {
        return;
    }

    // Bail out, it no category set in $_GET.
    if ( empty( $_GET['post_type'] ) || 'post_slug' !== wp_unslash( $_GET['post_type'] ) ) {
        return;
    }

    // Bail out, it no category set in $_GET.
    if ( empty( $_GET['cat'] ) ) {
        return;
    }

    $cat = wp_unslash( $_GET['cat'] );

    // Bail out, if category does not exist.
    if ( false === ( $cat = get_term_by( 'slug', $cat, 'tax' ) ) ) {
        return;
    }

    wp_set_object_terms( $post->ID, array( $cat->term_id ), 'tax' );

} );
add_action ( 'init', function() {
    $args['label'] = 'Test';
    $args['public'] = TRUE;
    register_post_type( 'post_slug', $args );

    $args['label'] = 'Taxonomy';
    register_taxonomy( 'tax', 'post_slug', $args );
});
  • This does not seem to work on a custom post type/taxonomy (despite replacing wp_set_post_categories with wp_set_object_terms)...any ideas? – Stephen Dec 1 '16 at 15:28
  • 1
    Hi @Stephen, I expanded the answer above. – websupporter Dec 4 '16 at 8:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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