Question

I am creating a gallery site using FooGallery and having the individual images open in the attachment page. I tried a bunch of codes from here to rewrite the attachment urls from ?attachment_id=8184 to /photos/frienly url but they are not working properly.

This code below works but it is not stable. If it works for one image, few hours later it starts redirecting to the homepage.

Any help on fixing this permanently?

add_filter( 'attachment_link', 'wp_attachment_link', 20, 2 );
function wp_attachment_link( $link, $attachment_id ){
$attachment = get_post( $attachment_id );
$attachment_title = $attachment->post_title ;
$attachment_title = str_replace( ' ' , '-' , $attachment_title );
$site_url = get_site_url( $attachment_id );
$link =  $site_url . '/photos/'  .$attachment_title;
return $link;
}
// Rewrite attachment page link
add_action( 'init', function() {
add_rewrite_rule( 'photos/([A-Za-z0-9-]+)?$', 'index.php?attachment_id=$matches[2]', 'top' );
Was it helpful?

Solution

There are three issues in your code:

  1. In your custom wp_attachment_link() function, you should use the post slug ($attachment->post_name) instead of simply replacing the (whitespaces) with - (dash) in the post title — and note that the resulting slug could be different than the actual slug, e.g. the title could be My Image with the actual slug being my-image-2, and yet your str_replace()-ing would result in my-image.

  2. In your rewrite rule, there's no $matches[2], only $matches[1] which matches the <slug> as in example.com/photos/<slug>.

  3. Also in that rule, the query is not valid: You should use the attachment parameter and not attachment_id, so the correct one is attachment=$matches[1].

So that should help you fix your own code, or you can try my code:

add_filter( 'attachment_link', 'wp_attachment_link', 20, 2 );
function wp_attachment_link( $link, $attachment_id ) {
    if ( ! $slug = get_post_field( 'post_name', $attachment_id ) ) {
        return $link; // you should just do this if the slug is empty..
    }

    return home_url( user_trailingslashit( "/photos/$slug", 'single' ) );
}

// Rewrite attachment page link.
add_action( 'init', function() {
    add_rewrite_rule( // wrapped for brevity
        '^photos/([\w\-]+)/?$',
        'index.php?attachment=$matches[1]',
        'top'
    );
} );

And don't forget to flush the rewrite rules; just visit the permalink settings admin page (wp-admin → Settings → Permalinks). Also, you should use a unique function name and not wp_attachment_link, e.g. use my_prefix_attachment_link. :)

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top