Как фильтровать вывод функции get_permalink()

17 мая 2017 г., 11:05:52
Просмотры: 14.9K
Голосов: 7

Я знаю, как фильтровать вывод функции the_permalink - это делается так:

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

И это работает, когда я использую: <?PHP the_permalink($id); ?>, но я хотел изменить ссылку, возвращаемую функцией get_permalink($id). И этот фильтр не влияет на возвращаемый пермалинк в этом случае.

Я пытался поймать это с помощью:

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

Но этот фильтр не срабатывает для get_permalink(). Так как же я могу изменить ссылки, возвращаемые функцией get_permalink()?

2
Комментарии

Я знаю, что могу определить функцию типа get_my_permalink() и использовать её вместо get_permalink(), но интересно, можно ли сделать это на более высоком уровне.

Picard Picard
17 мая 2017 г. 11:16:33

^ Это решение отлично работает, но вызывает предупреждение PHP: PHP Warning: Missing argument 3 for {closure} ()

Stefan Georgiev Andonov Stefan Georgiev Andonov
29 мая 2019 г. 15:07:43
Все ответы на вопрос 2
10
12

Обратите внимание, что фильтр post_link работает только для типа записей post.

Для других типов записей доступны следующие фильтры:

Функция get_permalink() на самом деле является обёрткой для:

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

в соответствующих случаях.

Вот способ (не тестировался) создать пользовательский фильтр wpse_link для всех вышеперечисленных случаев использования 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 );
}

Теперь мы можем фильтровать все случаи с помощью:

add_filter( 'wpse_link', function(  $url, $post_id, $sample, $type )
{
    return $url;
}, 10, 4 );
17 мая 2017 г. 11:17:54
Комментарии

Я тестирую это на обычной записи add_filter('post_type_link',... не влияет на get_permalink() в моём случае. Думаю, я просто напишу свою функцию типа get_my_permalink(), которая будет оборачивать get_permalink(), чтобы быстро и просто решить эту "проблему".

Picard Picard
17 мая 2017 г. 11:26:53

Странно, то же самое происходит на чистой установке? И вы уверены (извините за вопрос), что $id в get_permalink( $id ) относится к типу записи post? @Picard

birgire birgire
17 мая 2017 г. 11:46:03

Мне следовало быть точнее - это тип page, и page_link с ним работает нормально. Я ожидал какого-то фильтра для всех типов записей, например add_filter('get_permalink', ..., но раз его нет, ваш ответ подходит, спасибо.

Picard Picard
17 мая 2017 г. 11:50:47

ок, я обновил ответ с непроверенным обходным решением @Picard

birgire birgire
17 мая 2017 г. 12:11:49

Спасибо, просто добавьте { при открытии foreach, в остальном работает отлично - позволяет переопределять ссылки как для get_permalink(), так и для the_permalink для постов типа page - позже протестирую для других типов записей.

Picard Picard
17 мая 2017 г. 13:08:34

Полный список фильтров ссылок: https://codex.wordpress.org/Plugin_API/Filter_Reference#Link_Filters

Juniper Jones Juniper Jones
13 окт. 2018 г. 21:04:01

Моя медиатека перестала работать с этим. Выдаёт ошибку "слишком мало аргументов". Чтобы исправить, на строке 3 добавьте значение по умолчанию для sample: $sample = null.

Davey Davey
12 нояб. 2021 г. 18:31:55

Спасибо за подсказку, не стесняйтесь обновлять ответ по мере необходимости. @Davey

birgire birgire
12 нояб. 2021 г. 19:07:06

Я внес правку - думаю, это будет широко совместимо с версиями PHP и WP, но протестировано только на моём экземпляре.

Davey Davey
15 нояб. 2021 г. 12:03:59

отлично, спасибо @Davey

birgire birgire
15 нояб. 2021 г. 13:57:25
Показать остальные 5 комментариев
0

Я успешно использую этот код.

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);
20 нояб. 2019 г. 12:15:31