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 '17 at 8:16
  • ^ That solution works great, it just makes a PHP warning: PHP Warning: Missing argument 3 for {closure} () – Stefan Georgiev Andonov May 29 '19 at 12:07

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, $sample ) 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 );
| improve this answer | |
  • 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 '17 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 '17 at 8:46
  • I should've been more specific - it is page type, and page_link works with it fine. I expected some filter for all post types like add_filter('get_permalink', ..., but since there isn't your answer is fine, thanks. – Picard May 17 '17 at 8:50
  • 1
    ok, i updated the answer with an untested workaround @Picard – birgire May 17 '17 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 '17 at 10:08

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);
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.