I know there a some functions already avaible here for this task, but none of them seem to work as needed.

The best way seems to me adding a filter to wp_handle_upload_prefilter like kaiser does in this example. Unfortunately the file only gets the parent-post-title if the post is already saved to the database.

Another approach is to add a function to add_attachment like Ijaas does here. Then the file gets the parent-post-title as name, but no thumbnails are created. And my attempt in using wp_generate_attachment_metadata(); to create the missing image sizes, ended in an endless loop (propably cause I'm using it the wrong way, but now I'm a bit scared by this function).

Would be great if there was a way to pass the title to wp_handle_upload_prefilter even if the post isn't saved yet.

Oh by the way, this is my endless function, maybe somebody can tell me what's wrong with it. DON'T USE THIS FUNCTION !!!

add_action('add_attachment', 'fkp_rename_attacment');
function fkp_rename_attacment($post_ID){

  $post = get_post($post_ID);
  $file = get_attached_file($post_ID);
  $path = pathinfo($file);
  $parent = get_post($post->post_parent);
  $p_author = get_the_author_meta( 'display_name', $parent->post_author );
  $p_author_san = sanitize_title($p_author);

  $newfilename = $parent->post_name . '-' . $p_author_san . '-' . $post_ID;
  $newfile = $path['dirname']."/".$newfilename.".".$path['extension'];

  rename($file, $newfile);    

  $wp_filetype = wp_check_filetype(basename($newfile), null );
  $wp_upload_dir = wp_upload_dir();
  $attachment = array(
    'guid' => $wp_upload_dir['url'] . '/' . basename( $newfile ), 
    'post_mime_type' => $wp_filetype['type'],
    'post_title' => preg_replace('/\.[^.]+$/', '', basename($newfile)),
    'post_content' => '',
    'post_status' => 'inherit'
  $attach_id = wp_insert_attachment( $attachment, $newfile, $parent->ID );
  require_once(ABSPATH . 'wp-admin/includes/image.php');
  $attach_data = wp_generate_attachment_metadata( $attach_id, $newfile );
  wp_update_attachment_metadata( $attach_id, $attach_data );


  • Would it fix the problem to replace wp_update_attachment_metadata( $attach_id, $attach_data ); with remove_action('add_attachment', 'fkp_rename_attacment'); wp_update_attachment_metadata( $attach_id, $attach_data ); add_action('add_attachment', 'fkp_rename_attacment'); ? Commented Mar 21, 2013 at 13:37
  • Maybe someone could tell me what causes the endless loop in my function. That would help me A LOT. Commented Mar 23, 2013 at 16:01
  • add_attachment gets called on wp_insert_attachment, which you call within your function.
    – Milo
    Commented Mar 23, 2013 at 16:05
  • Oh thank you! But I tried to remove it and add it again at the end, like posted in the comment above and get an endless loop too. However this already helped me a lot. Commented Mar 23, 2013 at 16:08

1 Answer 1


After trying to add a function to publish_post and creating a lot of unnecessary files I tried to blemish kaisers function to fit my needs.

function modify_uploaded_file_names( $image ) {
    // Use part of the post or user object to rename the image
    global $post, $current_user;

    // only do this if we got the post id, 
    // otherwise they're probably in the media section 
    // rather than uploading an image from a post
    if ( isset( $_REQUEST['post_id'] ) ) {
        // get the ID
        $post_id  = absint( $_REQUEST['post_id'] );

        // get the post OBJECT
        $post_obj  = get_post( $post_id );

        // get the post slug
        $post_slug = sanitize_title($post_obj->post_title); 

        // get the author
        $author = sanitize_title( get_the_author_meta( 'display_name', $post_obj->post_author ) );

        switch( $image['type'] ) {
            case 'image/jpeg' :
                $suffix = 'jpg';

            case 'image/png' :
                $suffix = 'png';

            case 'image/gif' :
                $suffix = 'gif';

        // if we found a slug
        if ( $post_slug ) 
            $image['name'] = "{$author}-{$post_slug}-{$random_number}.{$suffix}";
    else {
        $image_name    = str_place( ' ', '-', strtolower( $current_user->data->user_nicename ) );
        $image['name'] = $image_name . '-' . $file['name'];

    return $image;

// Only one arg, so 4th attr not needed - Priority set to later 20
add_filter( 'wp_handle_upload_prefilter', 'my_modify_uploaded_file_names', 20 );

There are only some small changes

  1. replaced $post_obj->post_name with sanitize_title($post_obj->post_title) since post_name only was present in my tests when the post already was saved.
  2. deleted the random-numbers, cause wp_handle_upload uses wp_unique_filename() anyway.
  3. Added the author-name to the file-name, but that's just something I need.

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.