Вопрос или проблема
Я надеюсь, что кто-то сможет мне помочь.
Для контекста, я просто пытаюсь сделать URL этого поста на основе “родительского поста”, который является полем отношений внутри этого типа постов человека. Этот тип поста содержит другие поля, отличные от тех, что находятся в типе поста с отношениями. Это должно быть изолировано внутри бэкенда.
Редактировать: По сути, я просто хочу получить постоянную ссылку на объявленное настраиваемое поле “родительского поста”, обрезать/изменить возвращённый URL, сохранить его в переменной и использовать эту переменную в качестве перезаписи для данного типа поста. Я могу сделать это в шаблоне типа поста без проблем… но как переместить это и сделать запрос из function.php?
Я подозреваю, что причиной, по которой я сталкиваюсь с проблемами, является то, что перезапись происходит задолго до того, как переменная изменяется в другом файле… но я не знаю, как или что сделать, чтобы объединить код в один в function.php.
Редактировать: Я провел небольшое исследование и нашел решения для аналогичных проблем, ссылаясь на поля постов, но я не уверен, как сделать это в 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>";
global $initiative_url;
$initiative_url = preg_replace('/^https?:\/\/[^\/]+\.com\//', '', rtrim($all_fields['parent_post'][0]->guid, "https://wordpress.stackexchange.com/"));
echo $initiative_url;
echo "</pre>";
}
}
?>
</main>
<?php
endwhile;
endif;
?>
Внутри этого поста, переменная выводит следующее: staff/nick. Я пробовал с добавлением и без добавления global перед $initiative_url в single-initiative.php, и, похоже, это не имеет значения.
Мне нужно, чтобы значение, сохраненное в этой переменной, передавалось в файл functions.php и правильно назначалось для перезаписи. Если я удаляю $initiative_url=”buhh/biffy” из function.php, категория поста возвращается в URL, поэтому я просто храню это там для уверенности, что этот код работает. Я просто не уверен, как передать нужное мне значение в эту переменную для использования.
Ответ или решение
Вопрос о передаче значения переменной из шаблона в файл functions.php
сталкивается с несколькими архитектурными и функциональными препятствиями, характерными для работы с темами WordPress, особенно когда дело доходит до настройки ссылок (URL) на посты. Рассмотрим ваши возможности и шаги для достижения желаемого результата.
Теория
Когда вы работаете с WordPress, важно понимать, что различные части системы загружаются в определенном порядке. Переписывания шаблонов и URL-адресов происходят рано в цикле выполнения WordPress, еще до вызова отдельных функций шаблона или доступности глобальных переменных, установленных в этих шаблонах. Это и может быть причиной ваших затруднений.
Переписывание URL (Rewrite)
Переписывание адресов зависит от конфигурации, установленной в functions.php
, и выполняется на этапе инициализации. Поэтому, когда вы хотите использовать данные, определенные в отдельном шаблоне (например, single-initiative.php
), необходимо правильно передавать и захватывать данные между этими двумя контекстами.
Пример
С учетом вашего кода и его функциональности, вот пример, который иллюстрирует, как можно попытаться связать данные между файлами.
В single-initiative.php
В этом файле, вы пытаетесь извлечь и подготовить данные из настраиваемого поля parent_post
. Затем вы устанавливаете переменную $initiative_url
, которая принимает очищенный URL родительского поста. Но, главное здесь — это правильно сформулировать подход к передаче данных.
<?php
if (have_posts()):
while (have_posts()):
the_post();
$all_fields = get_fields();
if (isset($all_fields['parent_post']) && !empty($all_fields['parent_post'])) {
$parent_post_id = $all_fields['parent_post'][0]->ID;
$parent_post_permalink = get_permalink($parent_post_id);
// Здесь вы готовите URL для переписывания
$initiative_url = preg_replace('/^https?:\/\/[^\/]+\.com\//', '', rtrim($parent_post_permalink, "https://yourwebsite.com/"));
// Пользовательская функция может быть вызвана здесь
update_initiative_url($initiative_url);
}
endwhile;
endif;
?>
В functions.php
Создайте пользовательскую функцию, которая запоминала бы новое значение для $initiative_url
. Например, вы можете использовать транзиенты или параметры сессии для сохранения данных между запросами:
function update_initiative_url($url) {
// Используйте транзиент для временного хранения данных
set_transient('dynamic_initiative_url', $url, 12 * HOUR_IN_SECONDS);
}
function initiative($args, $post_type) {
if ($post_type == "initiative") {
// Извлекаем значение $initiative_url из ранее установленных данных
$initiative_url = get_transient('dynamic_initiative_url');
if (!empty($initiative_url)) {
$args['rewrite'] = array(
'slug' => $initiative_url
);
} else {
// Значение по умолчанию в случае, если URL не был установлен
$args['rewrite'] = array(
'slug' => 'buhh/biffy'
);
}
}
return $args;
}
add_filter('register_post_type_args', 'initiative', 20, 2);
Применение
-
Запись и извлечение данных: Мы перенесли часть логики обработки данных в отдельную функцию
update_initiative_url
, которая сохраняет и извлекает данные с помощью транзиентов. Это временное решение, подходящее для смены URL, которые нежелательно хранить постоянно. -
Переписывание: URL-адрес переписывается только в случае наличия сохраненного значительного значения. Если оно отсутствует — используется значение по умолчанию. Это позволяет поддерживать устойчивость системы.
-
Важность синхронизации: Важно учесть, что транзиенты не переживут возврат к исходному виду (например, при ослаблении кэширования или смене параметров). Возможно, понадобится дополнительно рассмотреть более прочные средства хранения, если нужные URL должны оставаться неизменными в течение долгого времени.
С помощью этого подхода вы получаете способ динамически регулировать отображение URL на основе данных из шаблона, одновременно управляя ими через основной файл функций темы. Это решение улучшает гибкость и управляемость URL, обеспечивая, что изменения, внесенные на уровне поста, будут корректно влиять на код в других частях WordPress.