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()?

  • I know I can define a function like get_my_permalink() and use it instead of get_permalink() but I am wondering if I can do this on some higher level.
    – Picard
    May 17, 2017 at 8:16
  • ^ That solution works great, it just makes a PHP warning: PHP Warning: Missing argument 3 for {closure} () May 29, 2019 at 12:07

2 Answers 2


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 );
  • I'm testing it on a regular post add_filter('post_type_link',... doesn't affect get_permalink() for me neither. I think I will just write my own function like get_my_permalink() to wrapping the get_permalink() to solve this "problem" fast and easy.
    – Picard
    May 17, 2017 at 8:26
  • Strange, does the same happen on a vanilla install? and you're sure (sorry for asking this) the $id in get_permalink( $id ) is for the post post type? @Picard
    – birgire
    May 17, 2017 at 8:46
  • 1
    ok, i updated the answer with an untested workaround @Picard
    – birgire
    May 17, 2017 at 9:11
  • 1
    Thanks, just add { when foreach opens, besides that works great - allows to override links for both get_permalink() and the_permalink for page type posts - I will do tests for other post types later.
    – Picard
    May 17, 2017 at 10:08
  • 1
    I made an edit - I think it will be widely compatible with php and WP vesrions but it's only tested on my one instance.
    – Davey
    Nov 15, 2021 at 10:03

I successfully use this statement.

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

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.