How to filter to output of the get_permalink() function

The question:

I know how to filter the output of the function the_permalink – it is like this:

add_filter('the_permalink', 'my_the_permalink');
function my_the_permalink($url) {
    return 'http://mysite/my-link/';

And it works when I use it like: <?PHP the_permalink($id); ?>, but I wanted to change the link returned by get_permalink($id) function. And this filter doesn’t affect the returned permalink in that case.

I was trying to catch it with:

add_filter('post_link', 'my_get_permalink', 10, 3);
function my_get_permalink($url, $post, $leavename=false) {
    return 'http://mysite/my-link/';

But this filter isn’t fired for the get_permalink(). So how can I alter the links returned by the get_permalink()?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

Note that post_link filter is only for the post post type.

For other post types these filters are available:

The get_permalink()function is actually a wrapper for:

  • get_post_permalink()
  • get_attachement_link()
  • get_page_link()

in those cases.

Here’s a way (untested) to create a custom wpse_link filter for all the above cases of get_permalink():

foreach( [ 'post', 'page', 'attachment', 'post_type' ] as $type )
    add_filter( $type . '_link', function ( $url, $post_id, ? bool $sample = null ) use ( $type )
        return apply_filters( 'wpse_link', $url, $post_id, $sample, $type );
    }, 9999, 3 );

where we can now filter all cases with:

add_filter( 'wpse_link', function(  $url, $post_id, $sample, $type )
    return $url;
}, 10, 4 );

Method 2

I successfully use this statement.

add_filter('post_type_link', function ($post_link, $post, $leavename, $sample) {
  if ($post->post_type == 'mycustomposttype') {
    $post_link = '' . $some_uri;
  return $post_link;
}, 999, 4);

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment