Great question! I’ve been thinking about this myself and your question prompted me to dig into it.
There is a filter wp_insert_attachment_data
than can be used to fix the slug name for uploaded files. It is called for attachments shortly before the attachment is inserted into the database in post.php
.
The following sample will append the mime type to the slug name, for example image-jpg
will be added to a jpeg image title.
/**
* Filter attachment post data before it is added to the database
* - Add mime type to post_name to reduce slug collisions
*
* @param array $data Array of santized attachment post data
* @param array $postarr Array of unsanitized attachment post data
* @return $data, array of post data
*/
function filter_attachment_slug($data, $postarr)
{
/**
* Only work on attachment types
*/
if ( ! array_key_exists( 'post_type', $data ) || 'attachment' != $data['post_type'] )
return $data;
/**
* Add mime type to the post title to build post-name
*/
$post_title = array_key_exists( 'post_title', $data ) ? $data['post_title'] : $postarr['post_title'];
$post_mime_type = array_key_exists( 'post_mime_type', $data ) ? $data['post_mime_type'] : $postarr['post_mime_type'];
$post_mime_type = str_replace( "https://wordpress.stackexchange.com/", '-', $post_mime_type );
$post_name = sanitize_title( $post_title . '-' . $post_mime_type );
/**
* Generate unique slug for post name
*/
$post_ID = array_key_exists( 'ID', $data ) ? $data['ID'] : $postarr['ID'];
$post_status = array_key_exists( 'post_status', $data ) ? $data['post_status'] : $postarr['post_status'];
$post_type = array_key_exists( 'post_type', $data ) ? $data['post_type'] : $postarr['post_type'];
$post_parent = array_key_exists( 'post_parent', $data ) ? $data['post_parent'] : $postarr['post_parent'];
$post_name = wp_unique_post_slug( $post_name, $post_ID, $post_status, $post_type, $post_parent );
$data['post_name'] = $post_name;
return $data;
}
/**
* Adjust slug for uploaded files to include mime type
*/
add_filter( 'wp_insert_attachment_data', 'filter_attachment_slug', 10, 2 );