Leave a Reply

4 comments

  1. 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:

    <?php
    /**
     * 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, " ntrx0B,") );
                $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) )
                            continue;
                        $term_info = wp_insert_term($term, 'post_tag');
                    }
                    $term_ids[] = $term_info['term_id'];
                }
                return $term_ids;
            }
        }
        return $terms;
    }, 10, 4);
    
  2. 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;
    
        // 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:

  3. 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

    <?php
    /**
     * 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' ) );
    
  4. 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.