Получить текущий URL (постоянную ссылку) без /page/{pagenum}/
Как получить текущий URL (будь то главная страница, архив, архив типа записи, архив категории и т.д.), но всегда без части /page/{pagenum}/
, если она присутствует? То есть, если реальный URL:
example.com/category/uncategorized/
ИЛИ
example.com/category/uncategorized/page/2/
то возвращаемое значение всегда будет
example.com/category/uncategorized/

Вы можете получить текущий URL с помощью home_url( $wp->request )
.
Попробуйте пример ниже:
global $wp;
// получаем текущий URL с query string.
$current_url = home_url( $wp->request );
// находим позицию, где начинается текст '/page.. '.
$pos = strpos($current_url , '/page');
// удаляем строку начиная с определенной позиции
$finalurl = substr($current_url,0,$pos);
echo $finalurl;

Самый простой способ - использовать get_pagenum_link()
, который возвращает текущий URL без каких-либо параметров /page/*
.
Бонус
Вы также можете просто использовать его для динамического создания ссылок "Назад" и "Вперед", используя переменную запроса 'paged'
:
// Получаем текущий номер страницы.
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$first_page = '<a href="' . get_pagenum_link() . '" class="page-first">«</a>';
$prev_page = '<a href="' . get_pagenum_link($paged - 1) . '" class="page-prev">‹</a>';
$next_page = '<a href="' . get_pagenum_link($paged + 1) . '" class="page-next">›</a>';
// Имея объект `WP_Query`, вы также можете создать ссылку на последнюю страницу:
$max = $the_query->max_num_pages;
$last_page = '<a href="' . get_pagenum_link($max) . '" class="page-last">»</a>';

Ответ от Говинда Кумара сработал, однако он возвращал URL только если в адресе присутствовала часть /page/{номер_страницы}/, и ничего не возвращал, если её не было. Мне нужно было универсальное решение, которое всегда возвращало бы базовый URL без пагинации, поэтому я немного модифицировал код Говинда и обернул его в функцию:
function get_nopaging_url() {
global $wp;
$current_url = home_url( $wp->request );
$position = strpos( $current_url , '/page' );
$nopaging_url = ( $position ) ? substr( $current_url, 0, $position ) : $current_url;
return trailingslashit( $nopaging_url );
}
echo get_nopaging_url();
Теперь функция всегда возвращает корректный URL.
(Это полезно, если вам нужно реализовать какие-либо фильтры записей, которые добавляют параметр для фильтрации, например, по метаполю. Таким образом, даже если пользователь установит параметр фильтра на странице X, новые отфильтрованные результаты всегда будут начинаться с базового URL, а не со страницы X, что позволит избежать ошибки 404, если отфильтрованных записей окажется меньше.)

Очень хорошо. Очень близко. Но '/page' недостаточно строго. Например, http://page-me.com вернет значение, которое будет некорректным.

@ChiefAlchemist хорошее замечание, я даже не подумал о том, что подстрока /page
может быть частью доменного имени (если не используется www, конечно). Это, на мой взгляд, скорее крайний случай. Тем не менее, я бы предложил вам внести свой вклад, добавив код, который также покроет этот случай.

Vorotbov - Сделаю. Пожалуйста, смотрите ниже. Кстати, есть множество слов с подстрокой 'page'. Не думаю, что можно считать это редким случаем. Лучше сделать проверку максимально строгой. Меньше проблем в долгосрочной перспективе.

Верно, но хотя я в целом согласен с вами, вопрос касался конкретной проблемы, и она была решена максимально эффективно для данного случая. Если в моем домене нет этой подстроки, то мне просто не нужно использовать регулярные выражения, которые работают медленнее простого substr (и который отлично подходит для моего случая). Это не публичный плагин или тема, поэтому мне не нужно учитывать все возможные крайние случаи. Тем не менее, ваше дополнение ценно и, надеюсь, поможет другим разработчикам в будущем. Спасибо!

Мои требования были очень похожи на требования Игоря Воротнова, за исключением того, что у меня было больше одного параметра. Поэтому, взяв за основу его ответ, я модифицировал код, используя регулярное выражение:
function get_nopaging_url() {
$current_url = $_SERVER[REQUEST_URI];
$pattern = '/page\\/[0-9]+\\//i';
$nopaging_url = preg_replace($pattern, '', $current_url);
return $nopaging_url;
}

Если вы хотите удалить все возможные варианты пагинации, используйте этот сниппет:
// удаляем пагинацию из URL
$pattern = '/page(\/)*([0-9\/])*/i';
$url = preg_replace($pattern, '', $GLOBALS['wp']->request);
Он обработает:
/page
/page/
/page/1
/page/1/
...
и является регистронезависимым, работает для любой страницы пагинации и удалит любые комбинации с числами/числами/числами... (тесты здесь: https://regex101.com/r/9fQaLC/1)
Если вам нужен полный URL с указанием протокола http(s), просто добавьте:
$url = home_url($url);
В этой строке вы также можете добавить любые пользовательские GET-параметры, например:
$url = home_url($url . '?typ=test');

Лично я всегда стараюсь избегать регулярных выражений, если что-то можно сделать без них (и при этом решение остаётся достаточно простым). Также add_query_arg() следует использовать для добавления GET-параметров вместо конкатенации строк. Но сам ответ правильный и работает, спасибо.

/**
* Получает SEO-оптимизированный URL текущей страницы
* Удаляет пагинацию (/page/X) из URL для улучшения SEO
*/
function getCurrentUrlSeo() {
global $wp;
$current_url = home_url($wp->request); // Получаем текущий URL
$pos = mb_strpos($current_url, '/page'); // Ищем позицию пагинации в URL
$finalurl = $pos ? substr($current_url, 0, $pos) : $current_url; // Если найдена пагинация - обрезаем её
return $finalurl.'/'; // Возвращаем URL с завершающим слэшем
}

Спасибо - на первый взгляд это то же самое, что и ответ Игоря. Не могли бы вы отредактировать ответ, чтобы объяснить, что вы изменили и почему это лучше?

Хотя на этот вопрос уже был дан ответ здесь (не принятый), этот фрагмент кода должен сработать: home_url(add_query_arg(NULL, NULL));
.

trait TraitURLStrip {
/**
* Удаляет пагинацию и строку запроса. Возвращает URL, удобный для фильтрации результатов
*
* @param bool $str_url
* @param string $str_page
*
* @return bool|string
*/
protected function urlStrip( $str_url = false , $str_page = 'page' ){
if ( is_string( $str_url) ) {
$arr_parse_url = wp_parse_url( $str_url );
$str_path_no_page = '';
if ( isset( $arr_parse_url['path'] ) ) {
// если есть пагинация, удаляем её
$str_path_no_page = preg_replace( "/\/{$str_page}\/[0-9]*\/$/", "/", $arr_parse_url['path'] );
}
$str_scheme_host = "{$arr_parse_url['scheme']}://{$arr_parse_url['host']}";
return $str_scheme_host . $str_path_no_page;
}
return false;
}
}

Могу я спросить, почему вы возвращаете false, если $str_url не является строкой? Если вы случайно (чего, конечно, быть не должно) передадите что-то другое, вы уничтожаете данные. Полагаю, лучше было бы вернуть неизмененный $str_url. Также у вас есть проверка на строку, но нет проверки, что это действительно URL, который можно разобрать (иначе следующий код сломается - wp_parse_url может вернуть false, null, int, string или array). Кроме того, я не уверен, что использование этого в качестве трейта имеет смысл - не все везде используют классы (это же WordPress, верно?).
