How Can I Organize the Uploads Folder by Slug (or ID, or FileType, or Author)?

admin2025-01-08  7

I want to store all attachments (media) in folders named with each post title.

Example: /wp-content/uploads/my-post-about-stuff/

The folder should contain all media attached to that post.

Is that possible?

I want to store all attachments (media) in folders named with each post title.

Example: /wp-content/uploads/my-post-about-stuff/

The folder should contain all media attached to that post.

Is that possible?

Share Improve this question edited Jun 1, 2012 at 0:08 brasofilo 22.1k8 gold badges69 silver badges264 bronze badges asked Aug 14, 2011 at 18:27 user3047user3047 5461 gold badge6 silver badges16 bronze badges 1
  • Does anyone know about some plugin for doing this? – user3047 Commented Aug 16, 2011 at 23:11
Add a comment  | 

4 Answers 4

Reset to default 12

Disclaimer

  • Tracking the way to do the same using the post_id
  • Having already answered one question about separating PDF's from the rest
  • Found disperse questions about this matter
  • Decided to adopt this Q as the venue to publish this.

Follow the instructions in the comments, and this code can be adapted to organize the uploads folder by post_name (aka: slug), post_author, post_id or media type.

add_filter('wp_handle_upload_prefilter', 'wpse_25894_handle_upload_prefilter');
add_filter('wp_handle_upload', 'wpse_25894_handle_upload');

function wpse_25894_handle_upload_prefilter( $file )
{
    add_filter('upload_dir', 'wpse_25894_custom_upload_dir');
    return $file;
}

function wpse_25894_handle_upload( $fileinfo )
{
    remove_filter('upload_dir', 'wpse_25894_custom_upload_dir');
    return $fileinfo;
}

function wpse_25894_custom_upload_dir($path)
{   
    /*
     * Determines if uploading from inside a post/page/cpt - if not, default Upload folder is used
     */
    $use_default_dir = ( isset($_REQUEST['post_id'] ) && $_REQUEST['post_id'] == 0 ) ? true : false; 
    if( !empty( $path['error'] ) || $use_default_dir )
        return $path; //error or uploading not from a post/page/cpt 
    
    /*
     * Save uploads in ID based folders 
     *
     */
    
    /*
     $customdir = '/' . $_REQUEST['post_id'];
    */


    /*
     * Save uploads in SLUG based folders 
     *
     */
    
     $the_post = get_post($_REQUEST['post_id']);
     $customdir = '/' . $the_post->post_name;


    /*
     * Save uploads in AUTHOR based folders 
     *
     * ATTENTION, CAUTION REQUIRED: 
     * This one may have security implications as you will be exposing the user names in the media paths
     * Here, the *display_name* is being used, but normally it is the same as *user_login*
     *
     * The right thing to do would be making the first/last name mandatories
     * And use:
     * $customdir = '/' . $the_author->first_name . $the_author->last_name;
     *
     */
    
    /* 
      $the_post = get_post($_REQUEST['post_id']);
      $the_author = get_user_by('id', $the_post->post_author);
      $customdir = '/' . $the_author->data->display_name;
    */
    
    
    /*
     * Save uploads in FILETYPE based folders 
     * when using this method, you may want to change the check for $use_default_dir
     *
     */
    
    /*
     $extension = substr( strrchr( $_POST['name'], '.' ), 1 );
     switch( $extension )
     {
        case 'jpg':
        case 'png':
        case 'gif':
            $customdir = '/images';
            break;
            
        case 'mp4':
        case 'm4v':
            $customdir = '/videos';
            break;
        
        case 'txt':
        case 'doc':
        case 'pdf':
            $customdir = '/documents';
            break;
     
        default:
            $customdir = '/others';
            break;
     }
    */
    
    $path['path']    = str_replace($path['subdir'], '', $path['path']); //remove default subdir (year/month)
    $path['url']     = str_replace($path['subdir'], '', $path['url']);      
    $path['subdir']  = $customdir;
    $path['path']   .= $customdir; 
    $path['url']    .= $customdir;  

    return $path;
}

The plugin Custom Upload Dir has this capability:

[with] Custom Upload Dir [...] you can construct paths from variables like post title, category, post author, post date and many more.

::Screenshots::



The first answer is quite good. I've noticed a PHP empty index notice when uploading WP plugins. To fix this replace:

$the_post = get_post($_REQUEST['post_id']);
$customdir = '/' . $the_post->post_name;

With

//check if post id is defined
      if( isset($_REQUEST['post_id']) ) {
        $the_post = get_post($_REQUEST['post_id']);
        $customdir = '/' . $the_post->post_name;
      }
    
    else {
        $customdir = '';
    }

For our internal webpage, we used the code from here and made it use the top level parent if the upload is from a page. Since it is internal, we didn't care about the username being visible. This allowed us to break up the uploads by something close to departments.

function wpse_25894_custom_upload_dir( $path ) {   
    /*
     * Determine if uploading from inside a page - if not, use the username
     */
    if ( ( strpos( $_SERVER['HTTP_REFERER'], 'wp-admin/upload' ) !== false ) || 
        ( strpos( $_SERVER['HTTP_REFERER'], 'wp-admin/media-new' ) !== false ) ) 
    {  
        $current_user = wp_get_current_user();    
        $customdir = '/' . $current_user->user_login;   
    } else {
        $post = get_post( $_REQUEST['post_id'] );    
        /* 
         * If there is a parent page, then get the hierarchy array, 
         * reverse it and use the first one to get the top level parent
         */
        if ( $post->post_parent ) {
            $parent = array_reverse( get_post_ancestors( $post->ID ) );
            $first_parent = get_page( $parent[0] );
            $customdir  = '/' . $first_parent->post_name;
        }
        /* 
         * Check if it is not a page (post or attachment page)
         * If it is, then use the username
         */
        elseif (strcmp ( 'page', $page->type ) == false ) {
            $current_user = wp_get_current_user();    
            $customdir = '/' . $current_user->user_login;
        }
        /*
         * Otherwise it is a top level parent page and just use the page name
         */
        else {
            $the_post = get_post( $_REQUEST['post_id'] );
            $customdir = '/' . $the_post->post_name;
        }
    }
    // Format the variables into a useable path
    $path['path']    = str_replace( $path['subdir'], '', $path['path'] ); // Remove default subdir (year/month)
    $path['url']     = str_replace( $path['subdir'], '', $path['url'] );      
    $path['subdir']  = $customdir;
    $path['path']   .= $customdir; 
    $path['url']    .= $customdir;  
    return $path;
}
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1736268328a1266.html

最新回复(0)