Можно ли получить ссылку на страницу из её слага?
Возможно ли получить постоянную ссылку страницы, используя только слаг? Я знаю, что можно получить ссылку на страницу по ID, используя get_page_link():
<a href="<?php echo get_page_link(40); ?>">Карта</a>
Мне интересно, есть ли способ сделать то же самое со слагом страницы - например, так:
<a href="<?php echo get_page_link('map'); ?>">Карта</a>
Это то, что вы ищете:
get_permalink( get_page_by_path( 'map' ) )get_permalink( get_page_by_title( 'Карта' ) )home_url( '/map/' )
Ссылки на документацию:
get_page_by_path() возвращает массив со всей информацией о странице. get_permalink() принимает ID страницы в качестве первого аргумента. Я подумал, что нужно явно передать значение ID.
Sampson
@Jonathan: Это не всегда задокументировано, но многие функции WP принимают в качестве аргумента как числовые ID, так и полные объекты записей.
Jan Fabry
Похоже, что get_page_by_path() может быть довольно сложной в использовании при работе с дочерними страницами...
Kaaviar
Я использую 1 для своих дочерних страниц без проблем. Действительно не вижу в этом сложности.
Jeremy
неверный ответ, минусуйте в нирвану пожалуйста. Путь не совпадает со слагом. Пример: страница имеет родительскую страницу с названием abc, сама страница имеет слаг 123. Теперь путь выглядит как abc/123, а слаг - 123. Пожалуйста, удалите этот неправильный ответ. get_page_by_path( '123' ) не сработает.
Toskan
В моем случае пришлось использовать первый вариант, и он сработал, потому что второй (get_page_by_title) возвращал ссылку на другую запись (не страницу) с похожим (но не идентичным) slug. Не знаю, почему так происходило.
Adriana Hernández
Думаю, это можно улучшить:
function get_page_by_slug($page_slug, $output = OBJECT, $post_type = 'page' ) {
global $wpdb;
$page = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_name = %s AND post_type= %s", $page_slug, $post_type ) );
if ( $page )
return get_page($page, $output);
return null;
}
следуя шаблону "оригинальной" функции get_page_by_title в WordPress. (строка 3173)
С уважением
Почему? Это не создает полный объект записи просто для получения ID.
s_ha_dum
Последний комментарий - я думаю, что в этом SQL запросе нужно добавить еще одно условие: function get_page_by_slug($page_slug, $output = OBJECT, $post_type = 'page' ) { global $wpdb; $page = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_name = %s AND post_type= %s AND post_status = 'publish'", $page_slug, $post_type ) ); if ( $page ) return get_page($page, $output); return null; }
User
@webcitron Думаю, это просто следует оригинальному шаблону Wordpress получения поста по 'title', только заменяет на 'slug'. (проверьте ссылку)
Matheus Eduardo
Это хороший ответ. Это обходит возможность того, что какой-то плагин может маскировать вашу страницу или неправильно её фильтровать. Если вы вернёте id из таблицы постов, то сможете создать экземпляр \WP_Post из него, и это будет напрямую работать во всех функциях Wordpress, которые проверяют другие значения. \WP_Post также предоставляет методы для непосредственного поиска большинства связанных данных о посте.
mopsyd
Это метод, опубликованный Томом МакФарлином в своем блоге:
/**
* Возвращает постоянную ссылку для страницы на основе переданного ярлыка (slug).
*
* @param string $slug Ярлык страницы, на которую нужно создать ссылку.
* @param string $post_type Тип записи (необязательный параметр).
* @return string Постоянная ссылка страницы
* @since 1.0
*/
function wpse_4999_get_permalink_by_slug( $slug, $post_type = '' ) {
// Инициализация переменной для хранения ссылки
$permalink = null;
// Формируем аргументы для WP_Query
$args = array(
'name' => $slug,
'max_num_posts' => 1
);
// Если передан необязательный параметр, добавляем его в массив аргументов
if( '' != $post_type ) {
$args = array_merge( $args, array( 'post_type' => $post_type ) );
}
// Выполняем запрос (и сбрасываем его)
$query = new WP_Query( $args );
if( $query->have_posts() ) {
$query->the_post();
$permalink = get_permalink( get_the_ID() );
wp_reset_postdata();
}
return $permalink;
}
Метод работает как с пользовательскими типами записей, так и со встроенными (такими как post и page).
принятый ответ неверен, потому что иерархические страницы работают не так. Проще говоря, ярлык (slug) не всегда соответствует пути страницы или записи. Например, если ваша страница имеет дочернюю, путь будет родительский-ярлык/дочерний-ярлык, и функция get_page_by_path не сможет найти дочерний-ярлык таким образом. Правильное решение выглядит так:
function mycoolprefix_post_by_slug($the_slug, $post_type = "page"){
$args = array(
'name' => $the_slug,
'post_type' => $post_type,
'post_status' => 'publish',
'numberposts' => 1
);
$my_page = get_posts($args)[0];
return $my_page;
}
<a href="<?php echo mycoolprefix_post_by_slug('map'); ?>">Карта</a>
Попробуйте так:
<a href="<?php echo get_page_link( get_page_by_path( 'map' ) ); ?>">Карта</a>
Функция get_page_by_path( 'path' ) возвращает объект страницы/записи, который затем можно использовать в get_page_link(), так как она принимает объект страницы/записи и возвращает постоянную ссылку.
function theme_get_permalink_by_title( $title ) {
// Инициализируем значение постоянной ссылки
$permalink = null;
// Пытаемся получить страницу по переданному заголовку
$page = get_page_by_title( strtolower( $title ) );
// Если страница существует, получаем её постоянную ссылку
if( null != $page ) {
$permalink = get_permalink( $page->ID );
} // end if
return $permalink;
} // end theme_get_permalink_by_title
Используйте эту функцию следующим образом
if( null == theme_get_permalink_by_title( 'Регистрация на сайте' ) ) {
// Постоянная ссылка не существует, обработайте это как считаете нужным
} else {
// Страница существует, выполните необходимые действия
} // end if/else