I want to have a link to create a new post that sets the category also.

I have tried wp-admin/post-new.php?post_category=12 and wp-admin/post-new.php?cat=12, but neither worked. I also tried using the name rather than the id of the category; which also had no affect.

How do I create a link to a new post with a default category?

4 Answers 4


Dave James Miller over at GitHub nailed this one for me. None of the work is from me, I'm just posting his code wrapped into a plguin since it works perfectly as advertised:

 * Plugin Name: Set default category from url parameter
 * Plugin URI:  https://gist.github.com/davejamesmiller/1966543
 * Description: enables you to setup new post links with the post_title, category and tags in the url: <code><a href="<?= esc_attr(admin_url('post-new.php?post_title=Default+title&category=category1&tags=tag1,tag2')) ?>">New post</a></code>
 * Version:     0.0.1
 * Author:      davejamesmiller
 * Author URI:  https://gist.github.com/davejamesmiller

// I used this code to automatically set the default post title, category and
// tags for a new WordPress post based on which link was clicked. It could also
// be tweaked to hard-code the values instead of using request parameters.

add_filter('wp_get_object_terms', function($terms, $object_ids, $taxonomies, $args)
    if (!$terms && basename($_SERVER['PHP_SELF']) == 'post-new.php') {

        // Category - note: only 1 category is supported currently
        if ($taxonomies == "'category'" && isset($_REQUEST['category'])) {
            $id = get_cat_id($_REQUEST['category']);
            if ($id) {
                return array($id);

        // Tags
        if ($taxonomies == "'post_tag'" && isset($_REQUEST['tags'])) {
            $tags = $_REQUEST['tags'];
            $tags = is_array($tags) ? $tags : explode( ',', trim($tags, " \n\t\r\0\x0B,") );
            $term_ids = array();
            foreach ($tags as $term) {
                if ( !$term_info = term_exists($term, 'post_tag') ) {
                    // Skip if a non-existent term ID is passed.
                    if ( is_int($term) )
                    $term_info = wp_insert_term($term, 'post_tag');
                $term_ids[] = $term_info['term_id'];
            return $term_ids;
    return $terms;
}, 10, 4);
  • Using the above method works great, however it would appear that advanced custom fields (another popular plug-in) rules that rely on post category, don't load correctly (i.e the custom fields for that category do not load). Has anyone figured a workaround for this?
    – Aphire
    Commented Nov 5, 2015 at 17:37

Hook into wp_insert_post, test the post status for auto-draft, and the URL for a GET parameter.

But first we need a helper function to get and sanitize the GET parameter:

 * Set default category.
 * @wp-hook pre_option_default_category
 * @return  string Category slug
function t5_get_default_cat_by_url()
    if ( ! isset( $_GET['post_cat'] ) )
        return FALSE;

    return array_map( 'sanitize_title', explode( ',', $_GET['post_cat'] ) );

Now the auto-draft handler:

add_action( 'wp_insert_post', 't5_draft_category', 10, 2 );

 * Add category by URL parameter to auto-drafts.
 * @wp-hook wp_insert_post
 * @param   int $post_ID
 * @param   object $post
 * @return  WP_Error|array An error object or term ID array.
function t5_draft_category( $post_ID, $post )
    if ( ! $cat = t5_get_default_cat_by_url()
        or 'auto-draft' !== $post->post_status )

    // return value will be used in unit tests only.
    return wp_set_object_terms( $post_ID, $cat, 'category' );

This works only if get_default_post_to_edit() was called with the second parameter $create_in_db set to TRUE. To catch the other case you have to filter the option default_category:

add_filter( 'pre_option_default_category', 't5_get_default_cat_by_url' );

Now you can use the parameter post_cat to pass a comma separated list of category slugs:

enter image description here

See also:

  • I tried this solution by pasting the code into my functions.php file and it didn't work. Am I missing something? Do I need to do more like call the function to make it do the job?
    – Jamie
    Commented Jan 16, 2015 at 0:40
  • @Jamie Didn't work is too vague. :)
    – fuxia
    Commented Jan 16, 2015 at 0:42
  • I thought by adding the code into functions.php that when I tick a category, it would add that parameter to the end of the string like in the photo above. I am trying to add a metabox to only a specific category. Then I will use $_GET to test if I am in the correct category to load the metabox. When I tried the code and tried to replicate what is in your photo above, nothing happened. All I got was wp-admin/post-new.php. I am trying to get wp-admin/post-new.php?post_cat=audio
    – Jamie
    Commented Jan 16, 2015 at 0:50
  • @Jamie This code works the other way around: You build the link manually (for example to send it to someone per email), and the code will set the proper category. It doesn’t create any link.
    – fuxia
    Commented Jan 16, 2015 at 0:53

I think you can go about the default option default_category and filter option_default_category this, if the url have a param for the category, like this example source. Use it as plugin, test it. Was write from scratch and not tested.

The url param is post_cat and you can set the category, like this url: /wp-admin/post-new.php?post_cat=categoryname

 * Plugin Name: .my Test
 * Plugin URI:  http://bueltge.de/
 * Description: 
 * Version:     0.0.1
 * Author:      Frank B&uuml;ltge
 * Author URI:  http://bueltge.de/
class Set_Default_Cat_From_Url_Param {

    protected static $classobj = NULL;

    public static function init() {

        NULL === self::$classobj and self::$classobj = new self();

        return self::$classobj;

    function __construct() {

        if ( isset( $_GET['post_cat'] ) )
            add_filter( 'option_default_category', array( $this, 'get_category' ) );

    function get_category( $category ) {

        if ( isset( $_GET['post_cat'] ) )
            $category = get_cat_ID( esc_attr( $_GET['post_cat'] ) );

        return $category;

add_action( 'load-post-new.php', array( 'Set_Default_Cat_From_Url_Param', 'init' ) );

I realize this has already been answered, but I wanted to add my own take. I've added it to a gist here https://gist.github.com/malcalevak/ba05b4fbed0c6e33ac8c18c1451bd857

To save you the hassle, though, here's the code:

function set_category () {

    global $post;
  //Check for a category parameter in our URL, and sanitize it as a string
    $category_slug = filter_input(INPUT_GET, 'category', FILTER_SANITIZE_STRING, array("options" => array("default" => 0)));

  //If we've got a category by that name, set the post terms for it
    if ( $category = get_category_by_slug($category_slug) ) {
        wp_set_post_terms( $post->ID, array($category->term_id), 'category' );


//hook it into our post-new.php specific action hook
add_action( 'admin_head-post-new.php', 'set_category', 10, 1 );

Similar to all the others, you'd trigger it via /wp-admin/post-new.php?category=categoryname

FYI, if you're using Advanced Custom Fields, like @Aphire, this WILL work.

  • this works if it is a simple post. If there is a post_type parameter, it does not work. How can i fix this to recognize wp-admin/post-new.php?post_type=wpdmpro?category=mycategory
    – yurividal
    Commented Jan 2, 2019 at 21:33
  • @yurividal unfortunately, I don't have an environment set up at the moment, any my memory is hazy, but a quick look at the WordPress Download Manager code looks like the issue might be that it's using a custom Taxonomy that "looks" like the built-in Category Taxonomy, but isn't.
    – Malcalevak
    Commented Jan 2, 2019 at 23:15
  • @yurividal didn't mean to end the comment. You'll likely need to adjust the get_category_by_slug function with one to get_term_by and then adjust wp_set_post_terms to set the custom wpdmcategory Taxonomy.
    – Malcalevak
    Commented Jan 2, 2019 at 23:23
  • Wow, that sounds a little complicated and I don't think I have enough php skills for that. Anyways, thank you for your help, I'll try to dig deeper into that.
    – yurividal
    Commented Jan 3, 2019 at 10:15
  • @yurividal I don't think it would be that complicated, but I could definitely see it as daunting to the less well initiated with PHP and/or WordPress. If I can find time to spare, I'll try to throw something together, my only concern is that I can't currently test it, which would make diagnosing issues a bit... complicated.
    – Malcalevak
    Commented Jan 3, 2019 at 21:21

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.