Вопрос или проблема
Я пишу код, который встроит чат-бота на определенные страницы моего сайта. У меня есть функция/шорткод, который принимает 2 параметра, include
и exclude
. Значение каждого из них может быть либо единичным ID поста, либо строкой ID постов, разделенных запятыми (которая позже преобразуется в массивы в функции шорткода). Если оба параметра равны null
(по умолчанию), бот будет встроен на каждую страницу сайта. Если правильные значения переданы в один из них, функция добавит бота только на страницы, чьи ID находятся в массиве include
, и/или НЕ добавит его на страницы с ID из массива exclude
.
if (in_array($id, $exclude) || bene_get_pods_val('disable_chatbot') === true) return;
if ((count($include) === 0 && count($exclude) === 0) || in_array($id, $include)) {
embed_bot();
}
Помимо этого, я хотел бы иметь возможность исключать или включать целые секции страниц (Продукты, Решения, Компания, База знаний и т.д.) на сайте. Я знаю, что могу передать что-то в шорткод, указав ему включать/исключать страницы, которые являются детьми одного или нескольких переданных ID. Там проблем нет.
if( $include_children && $top_level_page_id === wp_get_post_parent_id(get_the_ID()) ) {
return true;
}
Моя проблема заключается в настраиваемых типах постов. Например, у меня есть секция Базы знаний, которая использует обычный пост как страницу верхнего уровня (т.е. страницу, расположенную по адресу www.example.com/knowledge-base/
), но все страницы содержимого в этой секции являются настраиваемыми типами постов. По этой причине, я не могу сделать их дочерними этой страницы верхнего уровня, и поэтому ID каждой их родительской страницы возвращает 0.
Я знаю, что могу проверить $_SERVER['REQUEST_URI']
на наличие определенного слага
function pageIsInSection($top_level_page_id) {
$is = false;
$parent_slug = get_post_field('post_name', $top_level_page_id);
if(false !== strpos($_SERVER['REQUEST_URI'], '/$parent_slug/')) {
$is = true;
}
return $is;
}
но это кажется мне хаком. Есть ли более лучший способ определить, является ли текущая страница Базой знаний (или какой-либо другой секцией с настраиваемыми типами постов)?
Я не дам решения вашей актуальной проблемы, но покажу, как проверить, является ли текущая страница дочерней для определенной страницы верхнего уровня. Если вам нужно проверить, есть ли у текущей страницы определенная родительская страница, вы можете сделать это так:
<?php
$currentPage = get_the_id();
$pageAncestors = get_post_ancestors($currentPage);
$hasParent = in_array($currentPage,$pageAncestors);
здесь get_post_ancestors
вернет все ID родительских страниц для данной страницы в виде массива и, используя in_array
, вы сможете проверить, существует ли ID. Подробнее о get_post_ancestors можно прочитать здесь.
Ответ или решение
Для того чтобы ответить на вопрос о том, как проверить, является ли текущая страница дочерней по отношению к указанной верхнеуровневой странице в WordPress, необходимо учитывать некоторые особенности работы с иерархией страниц и пользовательскими типами записей. Ниже я дам детальный анализ этой задачи.
Теория
В WordPress существует несколько функций, которые помогают определить иерархическую структуру страниц. Одной из таких является get_post_ancestors()
, которая возвращает массив предков (родителей) указанной страницы. Это полезно для проверки, является ли одна страница дочерней по отношению к другой. Однако ситуация усложняется, когда на сайте используются пользовательские типы записей. В этом случае вместо привычной иерархии родитель-дочерний объект используется другая логика, основанная на URL-стуктуре или других параметрах.
Как правильно заметили в проблемном описании, у вас есть разделы сайта, где верхнеуровневая страница и дочерние страницы представлены разными типами записей, что затрудняет использование стандартной функции wp_get_post_parent_id()
для заголовка этого раздела. Это особенно характерно для таких структур, как база знаний, где верхнеуровневой является обычная страница, а дочерние элементы — записи пользовательского типа.
Пример
Рассмотрим пример кода, который пытается решить эту задачу, используя URI-ссылки. Основная идея заключается в проверке, содержится ли в текущем URI определенный шаблон, что позволяет косвенно определить принадлежность страницы к определенному разделу.
function pageIsInSection($top_level_page_id) {
$is = false;
$parent_slug = get_post_field('post_name', $top_level_page_id);
if (false !== strpos($_SERVER['REQUEST_URI'], '/' . $parent_slug . '/')) {
$is = true;
}
return $is;
}
Этот подход работает, поскольку сравнивает части URI, однако имеет некоторую ненадежность из-за возможных изменений в структуре URL или переименований, что делает его менее устойчивым решением в долгосрочной перспективе.
Применение
Чтобы реализовать более устойчивое решение, можно сочетать несколько подходов. Во-первых, можно использовать таксономии и метаполя для указания принадлежности записей к определенным разделам. Создание пользовательской таксономии позволит группировать записи, а использование меток напрямую в коде упростит управление этими категориями.
Также можно воспользоваться интеграцией с кастомным REST API или внутренней логикой, где идентификаторы определенных элементов хранятся в базе данных, а принадлежность проверяется напрямую через PHP функции, взаимодействующие с базой.
Пример кода с использованием метаполей для проверки:
function isPageInCustomSection($custom_field_key, $expected_value) {
$current_page_id = get_the_ID();
$custom_field_value = get_post_meta($current_page_id, $custom_field_key, true);
return $custom_field_value === $expected_value;
}
// Использование
if (isPageInCustomSection('section_type', 'knowledge_base')) {
// Действие, если текущая страница принадлежит к базе знаний
}
Этот подход значительно увеличивает гибкость и надежность, позволяя контролировать видимость и поведение контента посредством гибких и настраиваемых параметров.
Заключение
В контексте CMS, такой как WordPress, где решающую роль играют пользовательские настройки и расширенная функциональность, оптимальным решением является интеграция различных подходов. Это включает в себя использование иерархических функций, URI-проверок, таксономий и метаполей. Таким образом, возможно построить эффективную систему, которая будет устойчивой к изменениям структуры сайта и которая сможет гибко управлять видимостью иерархических и неиерархических элементов.