- Вопрос или проблема
- ИЗМЕНЕНИЕ 5 АПРЕЛЯ 2016
- ОРИГИНАЛЬНЫЙ ОТВЕТ
- Ответ или решение
- Способ 1: Использование глобальной переменной $post
- Способ 2: Функция get_queried_object()
- Способ 3: Использование get_post_field()
- Способ 4: Получение слога из ссылки
- Способ 5: Создание собственной функции
- Способ 6: SQL-запрос
- Заключение
Вопрос или проблема
Я пытаюсь получить ярлык текущей страницы WordPress вне цикла. Название страницы возвращается с помощью wp_title ()
, но как мне получить ярлык?
<li>
<a href="https://wordpress.stackexchange.com/slug-of-current-page/">
<?php wp_title('', true); ?>
</a>
</li>
Используйте глобальную переменную $post
:
<?php
global $post;
$post_slug = $post->post_name;
?>
Согласно другим ответам, ярлык хранится в свойстве post_name
. Хотя его можно получить напрямую, я предпочитаю (недостаточно используемую) функцию get_post_field()
для доступа к свойствам поста, для которых нет соответствующего API.
Она требует, чтобы пост был указан явно и не по умолчанию обращалась к текущему, поэтому для текущего поста это будет:
$slug = get_post_field( 'post_name', get_post() );
ИЗМЕНЕНИЕ 5 АПРЕЛЯ 2016
После поисков для большей надежности, я в конечном итоге сделал этот ответ на следующий пост, который привел к этому изменению: (Обязательно ознакомьтесь с ним)
Самый надежный способ, который я смог придумать на сегодняшний день, такой:
// Получить запрашиваемый объект и очистить его
$current_page = sanitize_post( $GLOBALS['wp_the_query']->get_queried_object() );
// Получить ярлык страницы
$slug = $current_page->post_name;
ОРИГИНАЛЬНЫЙ ОТВЕТ
Другой более безопасной альтернативой этой проблеме является использование get_queried_object()
, который содержит текущий запрашиваемый объект, чтобы получить ярлык страницы, который хранится в свойстве post_name
. Это можно использовать в любом месте вашего шаблона.
$post
можно использовать, но он может быть ненадежным, так как любой пользовательский запрос или пользовательский код могут изменить значение $post
, поэтому его следует избегать вне цикла.
Использование get_queried_object()
для получения текущего объекта страницы гораздо надежнее и менее вероятно будет изменено, если вы не используете злостный query_posts
, который нарушает основной объект запроса, но тогда это уже зависит от вас.
Вы можете использовать вышеизложенное следующим образом
if ( is_page() )
$slug = get_queried_object()->post_name;
Простой способ получить ярлык — это:
<?php echo basename(get_permalink()); ?>
Судя по приведенному примеру кода, похоже, что вам действительно нужна ссылка. В этом случае вы можете использовать get_permalink(), который можно использовать вне цикла. Это должно выполнить вашу задачу более надежно, чем использование ярлыка поста.
Возможно, это старая проблема, но я создал функции get_the_slug() и the_slug() на основе ваших ответов.
if ( !function_exists("get_the_slug") ) {
/**
* Возвращает ярлык страницы или поста.
*
* @param int|WP_Post|null $id (Опционально) Идентификатор поста или объект поста. По умолчанию используется глобальный $post.
* @return string
*/
function get_the_slug( $id = null ){
$post = get_post($id);
если( !empty($post) ) return $post->post_name;
return ''; // Нет глобальной переменной $post или соответствующего ID.
}
/**
* Отображает ярлык страницы или поста
*
* Использует get_the_slug() и применяет фильтр 'the_slug'.
*
* @param int|WP_Post|null $id (Опционально) Идентификатор поста или объект поста. По умолчанию используется глобальный $post.
*/
function the_slug( $id=null ){
echo apply_filters( 'the_slug', get_the_slug($id) );
}
}
Вы можете просто извлечь ярлык из запроса.
global $wp;
// Поскольку ярлыки сами по себе не могут содержать косые черты,
// давайте воидем на косые черты и получим только последнюю часть.
$request_args = explode("https://wordpress.stackexchange.com/", $wp->request);
$current_slug = end($request_args);
// Учитывая URL https://example.com/foo/bar/foo-bar
if ($current_slug === 'foo-bar') {
// условие будет соответствовать.
}
Это работает для всех постов, страниц, пользовательских маршрутов.
Это функция, которую следует использовать, когда необходимо получить ярлык вне цикла.
get_post_field( 'post_name');
Ответ найден здесь: Как получить ярлык текущей страницы в WordPress?
Если вы хотите более глубокий ответ, вы можете использовать следующий SQL-запрос, чтобы получить все посты, которые могут быть как постами, так и страницами, или пользовательскими таксономиями в любое время, даже если еще не сработали никакие хуки.
Сырой SQL:
SELECT `id`, `post_type` AS `type`, `post_author` AS `author`, `post_name` AS
`slug`, `post_status` AS `status`
FROM wp_posts
WHERE `post_type` NOT IN ('attachment', 'nav_menu_item', 'revision')
AND `post_status` NOT IN ('draft', 'trash')
ORDER BY `id`;
Это работает даже на самой первой строке вашего файла функций, даже до хуков mu_plugins_loaded
или init
.
@замечание
Это предполагает, что у вас стандартный префикс базы данных wp_posts
. Если вам нужно учитывать переменные префиксы, вы можете получить правильную таблицу постов через PHP довольно просто, сделав следующее:
<?php
global $wpdb;
$table = $wpdb->posts;
$query = "SELECT `id`, `post_type` AS `type`, `post_author` AS `author`, `post_name` AS
`slug`, `post_status` AS `status`
FROM " . $table . "
WHERE `post_type` NOT IN ('attachment', 'nav_menu_item', 'revision')
AND `post_status` NOT IN ('draft', 'trash')
ORDER BY `id`;"
Затем выполните это с помощью $wpdb
, mysqli
или экземпляра PDO
. Поскольку в этом запросе нет пользовательского ввода, его безопасно выполнять без подготовленного заявления, если вы не вводите в него никакие переменные.
Я бы рекомендовал сохранить это как частичное статическое значение класса, чтобы к нему можно было получить доступ без повторного выполнения запроса больше одного раза на страницу для достижения наилучшей производительности, что-то вроде этого:
class Post_Cache
{
private static $post_cache;
public function __construct()
{
//Таким образом пропускается операция, если она уже установлена.
$this->initCache();
}
public function get($id, $type = null)
{
если ( !(is_int( $id ) && array_key_exists( $id, self::$post_cache ) ) )
return false;
}
if ( !is_null( $type ) )
{
//возвращает конкретное значение столбца для идентификатора
return self::$post_cache[$id][$type];
}
//возвращает всю строку
return self::$post_cache[$id];
}
private function initCache()
{
if ( is_null(self::$post_cache) )
{
$query = "...";
$result = some_query_method($query); //Выполните вашу логику запроса здесь.
self::$post_cache = $result;
{
}
}
Использование
$cache = new \Post_Cache();
//Получить ярлык страницы
$slug = $cache->get( get_the_ID(), 'slug');
if ($cache->get( get_the_ID() ))
{
//пост существует
} else {
//нет, 404 'em
}
if ( $cache->get( get_the_ID(), 'status') === 'publish' )
{
//он публичный
} else {
//либо проверьте current_user_can('whatever_permission'), либо просто 404 это,
//в зависимости от того, хотите ли вы, чтобы это было видно текущему пользователю или нет.
}
if ( $cache->get( get_the_ID(), 'type') === 'post' )
{
//Это пост
}
if ( $cache->get( get_the_ID(), 'type') === 'page' )
{
//Это страница
}
Вы уловили суть. Если вам нужны дополнительные детали, вы можете получить их как обычно с помощью new \WP_Post( get_the_ID() );
Это позволит вам проверять посты в любое время, даже если цикл WordPress не достиг той точки, где он находит ваш запрос приемлемым. Это несколько более оптимизированная версия того же запроса, который выполняет сам WordPress. Эта версия фильтрует весь мусор, который вы не хотите получать, и просто дает вам аккуратно организованный список с соответствующим идентификатором автора, типом поста, ярлыком и видимостью. Если вам нужны дополнительные детали, вы можете получить их как обычно с помощью new \WP_Post($id);
, или использовать любые другие встроенные функции WordPress с любыми соответствующими строками таблиц, даже вне цикла.
Я использую аналогичную настройку в нескольких своих пользовательских темах и плагинах, и это работает довольно хорошо. Он также безопасен и не оставляет внутренние данные, висящие в глобальной области, где их можно переопределить, как это делает большинство вещей в WordPress.
Если вы в цикле, другие ответы помогут вам. Если нет (например, вы подключаетесь к init
или plugins_loaded
), вы можете прибегнуть к примитиву PHP, такому как parse_url()
.
Вот функция, которая работает в обоих случаях:
function get_the_slug() {
global $post;
$slug = $post->post_name ?? '';
if ( ! $slug ) {
$slug = basename( parse_url( $_SERVER['REQUEST_URI'] ?? '', PHP_URL_PATH ) );
}
return $slug;
}
Обратите внимание, что этот подход работает только с постами/страницами на корневом уровне из-за того, как работает basename()
.
Просто далее по ответу @Matthew Boynes, если вы интересуетесь получением родительского ярлыка (если он есть), то я нашел эту функцию полезной:
function mytheme_get_slugs() {
if ( $link = get_permalink() ) {
$link = str_replace( home_url( "https://wordpress.stackexchange.com/" ), '', $link );
if ( ( $len = strlen( $link ) ) > 0 && $link[$len - 1] == "https://wordpress.stackexchange.com/" ) {
$link = substr( $link, 0, -1 );
}
return explode( "https://wordpress.stackexchange.com/", $link );
}
return false;
}
Например, чтобы добавить ярлык(и) в класс body:
function mytheme_body_class( $classes ) {
if ( $slugs = mytheme_get_slugs() ) {
$classes = array_merge( $classes, $slugs );
}
return $classes;
}
add_filter( 'body_class', 'mytheme_body_class' );
Я бы предложил следующее:
$current_page_slug = trim(preg_replace('#^' . preg_quote(get_site_url()) . '#', '', get_permalink()), "https://wordpress.stackexchange.com/");
Динамический вызов страницы в WordPress.
<?php
get_template_part('foldername/'.basename(get_permalink()),'name');
?>
Ответ или решение
Для того чтобы получить слог (slug) текущей страницы в WordPress вне цикла, существует несколько эффективных способов. Важно помнить, что слог – это часть URL, которая представляет собой уникальное название записи или страницы, и хранится в поле post_name
в базе данных. Ниже представлено детальное объяснение различных методов получения слога текущей страницы.
Способ 1: Использование глобальной переменной $post
Наиболее распространённый метод заключается в использовании глобальной переменной $post
. Это можно сделать следующим образом:
global $post;
$post_slug = $post->post_name;
Однако, это может быть ненадежно в тех случаях, когда ваши запросы изменяются нестандартным образом (например, при использовании query_posts
или пользовательских запросов). Поэтому такой метод не рекомендуем использовать вне цикла.
Способ 2: Функция get_queried_object()
Более надежным способом является использование функции get_queried_object()
, которая возвращает текущий объект запроса:
if ( is_page() ) {
$slug = get_queried_object()->post_name;
}
Этот метод обеспечит более стабильные результаты, так как он меньше подвержен изменениям извне.
Способ 3: Использование get_post_field()
Для получения слога можно воспользоваться функцией get_post_field()
, которая позволяет запрашивать конкретные поля записи:
$slug = get_post_field('post_name', get_post());
Этот способ хорош тем, что работает независимо от состояния цикла и возвращает необходимую информацию, основываясь на ID текущей страницы.
Способ 4: Получение слога из ссылки
Также можно извлечь слог напрямую из URL-адреса:
global $wp;
$request_args = explode("/", $wp->request);
$current_slug = end($request_args);
Этот способ может быть полезен, если слог не содержит слешей, а также может использоваться для получения слога страниц или кастомных маршрутов.
Способ 5: Создание собственной функции
Если вам нужно что-то более универсальное, вы можете создать свою функцию для получения слога:
function get_the_slug() {
global $post;
$slug = $post->post_name ?? '';
if (!$slug) {
$slug = basename(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
}
return $slug;
}
Эта функция сначала пытается получить слог через $post
, а если это не удаётся, она извлекает слог из текущего URL.
Способ 6: SQL-запрос
Для более опытных разработчиков существует возможность выполнения прямого SQL-запроса в базу данных для получения информации о записях:
global $wpdb;
$query = "SELECT post_name FROM {$wpdb->posts} WHERE ID = ?";
$slug = $wpdb->get_var($wpdb->prepare($query, get_the_ID()));
Это может быть полезно, если вам нужно обрабатывать данные вне контекста стандартных функций WordPress или в специфических ситуациях.
Заключение
Каждый из перечисленных методов имеет свои преимущества и недостатки в зависимости от контекста использования. Выбор метода будет зависеть от ваших конкретных требований и условий. Эффективное использование этих методов позволит вам получать слоги страниц в WordPress корректно и надежно.