Adding File Extensions to Attachment Page Permalinks

Introduction

When uploading a file (stackexchange.jpg) to the media library in a WordPress site, there are two relevant links.

  1. Direct link to file
    http://example.com/wp-content/uploads/stackexchange.jpg

  2. Attachment page
    http://example.com/stackexchange/

My question deals with the second one: attachment page.

What I Want to Do

I would like to add the file extension in the attachment page permalink. For example, instead of

http://example.com/stackexchange/

I would like

http://example.com/stackexchange-jpg/

Why This Would be Useful

This would be very useful for a couple of reasons. For one, it won’t be hogging permalinks in case I want to use it for a post or a page, etc. For another, I can then upload another file called stackexchange.png. Then, I would have:
http://example.com/stackexchange-jpg/
and
http://example.com/stackexchange-png/

And again, I can still use http://example.com/stackexchange/ for an actual page.

I do realize that I can go through and edit every single file’s slug manually, which in turn would indeed change the attachment page permalink, but I think it almost goes without saying that I wouldn’t need to actually make a thread if I was looking to do that.

Question

Is there a function I can write to make it so that whenever a file is uploaded, it reflects the changes I’m looking for? Is this even possible? If so, how do I do it? If you know how to edit the default permalink, but you don’t know how to add the file extension part, I can most likely still work with that information.

I’m thinking this is probably not possible without tampering with core files (which would be a deal breaker), but hopefully it is.

Thanks for reading and for any help.

2 Answers
2

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 );

Leave a Comment