WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a lot of uploaded image files and image sizes. So it would be better to organize media files into folders based on post type. I have just read this tutorial, but as I can see it works with plugins. How to change this to use in a theme? Thanks.

function custom_upload_directory( $args ) {
    $id = $_REQUEST['post_id'];
    $parent = get_post( $id )->post_parent;
    // Check the post-type of the current post
    if( "post-type" == get_post_type( $id ) || "post-type" == get_post_type( $parent ) ) {
        $args['path'] = plugin_dir_path(__FILE__) . "uploads";
        $args['url']  = plugin_dir_url(__FILE__) . "uploads";
        $args['basedir'] = plugin_dir_path(__FILE__) . "uploads";
        $args['baseurl'] = plugin_dir_url(__FILE__) . "uploads";
    return $args;
add_filter( 'upload_dir', 'custom_upload_directory' );
share|improve this question
This article may be useful for understanding how to place things in theme or plugin. – brasofilo Dec 21 '12 at 17:38
up vote 5 down vote accepted

If i understand your question right you want a function within your theme that adds directories for the current post_type? like: uploads/post_type_name. if so here is a function for that:

function wpse_16722_type_upload_dir( $args ) {

    // Get the current post_id
    $id = ( isset( $_REQUEST['post_id'] ) ? $_REQUEST['post_id'] : '' );

    if( $id ) {    
       // Set the new path depends on current post_type
       $newdir = '/' . get_post_type( $id );

       $args['path']    = str_replace( $args['subdir'], '', $args['path'] ); //remove default subdir
       $args['url']     = str_replace( $args['subdir'], '', $args['url'] );      
       $args['subdir']  = $newdir;
       $args['path']   .= $newdir; 
       $args['url']    .= $newdir; 
    return $args;
add_filter( 'upload_dir', 'wpse_16722_type_upload_dir' );
share|improve this answer
Thank you, it works for me. I made a little modification because $_REQUEST['post_id'] cause Undefined index: post_id error. I use this: if(!isset($_REQUEST['post_id'])) return $args; $id = (int)$_REQUEST['post_id']; – user9909 Jan 26 '13 at 14:45

In WP 4.4, you need to return the $args just before finishing the function not inside the condition of $id.

share|improve this answer
No, it was always the way to do it. Your return statement should be outside the condition – Pieter Goosen Mar 9 at 9:34

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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