Вопрос или проблема
Я надеюсь, что кто-то сможет мне помочь.
Для контекста, я просто пытаюсь основывать этот URL поста на “родительском посте”, который является полем отношений внутри этого типа поста человека. Этот тип поста содержит разные поля, чем те, что находятся в типе поста отношений. Это должно быть изолировано в бэкенде.
Я предполагаю, что причина, по которой я сталкиваюсь с проблемами, заключается в том, что переписывание происходит задолго до того, как переменная изменяется в другом файле… но я не знаю, как или что сделать, чтобы объединить код в один внутри function.php.
У меня есть этот кусок кода в моем function.php:
function initiative($args, $post_type)
{
if ($post_type == "initiative") {
global $initiative_url;
$initiative_url="buhh/biffy";
$args['rewrite'] = array(
// это правильно переписывает в url /initiative/ на /buhh/biffy, поскольку это объявлено в переменной $initiative_url в этом файле, но я хочу, чтобы это ссылалось на значение, заданное в шаблоне single-initiative.php
'slug' => $initiative_url
);
}
return $args;
}
add_filter('register_post_type_args', 'initiative', 20, 2);
Внутри шаблона single-initiative.php у меня есть этот код (сильно обрезан, чтобы не был нужен в этом контексте):
<?php
if (have_posts()):
while (have_posts()):
the_post();
$post_slug = get_post_field('post_name', get_post());
$page_title = get_the_title();
$all_fields = get_fields();
$page_id = get_the_ID();
?>
<main>
<?php
if (isset($all_fields['parent_post']) && !empty($all_fields['parent_post'])) {
foreach ($all_fields['parent_post'] as $parent_post_details) {
$parent_post = get_fields($parent_post_details->ID);
$parent_post_id = $parent_post_details->ID;
global $parent_post_permalink;
$parent_post_permalink = get_permalink($parent_post_id);
echo "<pre>";
$initiative_url = preg_replace('/^https?:\/\/[^\/]+\.com\//', '', rtrim($parent_post_permalink, "https://wordpress.stackexchange.com/"));
echo $initiative_url;
echo "</pre>";
}
}
?>
</main>
<?php
endwhile;
endif;
?>
Внутри этого поста переменная дает следующий результат: staff/nick. Я пробовал с глобальным и без него перед $initiative_url в single-initiative.php, и это не похоже, чтобы делало разницу.
Мне нужно, чтобы значение, хранящееся в этой переменной, передавалось в файл functions.php и правильно присваивалось для переписывания.
Если я удалю $initiative_url=”buhh/biffy” из function.php, категория поста возвращается в URL, поэтому у меня это есть там для уверенности, что этот код работает. Я просто не уверен, как передать правильное значение, которое я хочу, в эту переменную для использования.
Ответ или решение
Для решения вашей задачи, которая связана с изменением URL записей на основе связанного родительского поста в настройках вашей темы WordPress, необходимо внимательно рассмотреть две части кода: одна из них содержится в файле functions.php, а другая — в single-initiative.php. В этой ситуации ваша цель — обеспечить, чтобы URL, сгенерированный в шаблоне single-initiative.php, можно было передать в функцию rewrite в functions.php. Для этого мы рассмотрим несколько подходов к реализации этого функционала.
Теория
Основная задача заключается в изменении конечного URL для постов типа "initiative", чтобы вместо стандартного URL использовался кастомный URL, полученный из связанного родительского поста. Это достигается с помощью использования фильтров и функций в WordPress.
В WordPress функция register_post_type
позволяет произвольным образом изменять слуги для пользовательских типов записей путем перезаписи или переписывания значений (rewrite). Здесь, использование глобальных переменных может не всегда иметь желаемый эффект из-за порядка выполнения кода и возможных конфликтов инкапсуляции переменных.
Пример
Рассмотрим идеальный пример решения, предполагающий изменение структуры кода для передачи переменных между файлами элементов WordPress:
-
Шаг 1: Извлечение необходимого URL в файле single-initiative.php.
-
Шаг 2: Передача этого значения в functions.php для использования в качестве slugs.
-
Шаг 3: Применение полученного значения в фильтрации slugs через
register_post_type_args
.
Применение
Для достижения этого цели, следуйте следующим шагам:
-
Создание функции для генерации нужного URL
В файле
single-initiative.php
, продолжите использовать текущую логику, но добавьте функцию, которая будет возвращать нужный URL. Это позволит легко интегрировать вашу логику в дальнейшем.function get_initiative_slug() { $initiative_url = ''; if (have_posts()): while (have_posts()): the_post(); $all_fields = get_fields(); if (isset($all_fields['parent_post']) && !empty($all_fields['parent_post'])) { foreach ($all_fields['parent_post'] as $parent_post_details) { $parent_post_permalink = get_permalink($parent_post_details->ID); $initiative_url = preg_replace('/^https?:\/\/[^\/]+\.com\//', '', rtrim($parent_post_permalink, "https://wordpress.stackexchange.com/")); } } endwhile; endif; return $initiative_url; }
-
Использование action hook
Чтобы передать сгенерированный URL из вашего шаблона в файл
functions.php
, вы можете использоватьactions
иfilters
.В
functions.php
, создайте новый action, который будет присваивать значение slug перед его регистрацией:add_action('init', 'adjust_initiative_slug'); function adjust_initiative_slug() { if (is_admin()) { return; } $post_id = get_the_ID(); if ($post_id && get_post_type($post_id) == 'initiative') { add_filter('register_post_type_args', function ($args, $post_type) { if ($post_type == 'initiative') { $initiative_slug = apply_filters('initiative_slug_override', ''); // Исп. Apply_filters для динамического замешения if (!empty($initiative_slug)) { $args['rewrite'] = array('slug' => $initiative_slug); } } return $args; }, 20, 2); } }
-
Передача значений с помощью filters
В конце шаблона
single-initiative.php
, перед регистрацией постов, примените фильтр:add_filter('initiative_slug_override', 'get_initiative_slug');
Этот процесс интеграции позволит динамически изменять slug для постов типа "initiative" на основе поля relationship родительского поста. Теперь это будет более устойчивое и поддерживаемое решение, следуя лучшим практикам разработки в WordPress.
Благодаря использованию actions и фильтров, мы создаем механизм обратного вызова, который укрепляет структуру кода и изолирует логику там, где это имеет место. Такой подход обеспечивает, что учитываются любые изменения в значениях URL, автоматически обновляя заблаговременно. Это не только улучшает структуру кода, но и гарантирует гибкость для будущих изменений.