проверить, является ли текущая страница дочерней страницей указанной страницы верхнего уровня

Вопрос или проблема

Я пишу код, который встроит чат-бота на определенные страницы моего сайта. У меня есть функция/шорткод, который принимает 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-проверок, таксономий и метаполей. Таким образом, возможно построить эффективную систему, которая будет устойчивой к изменениям структуры сайта и которая сможет гибко управлять видимостью иерархических и неиерархических элементов.

Оцените материал
Добавить комментарий

Капча загружается...