Возврат переменной из файла шаблона в функцию в function.php или объединение части кода в function.php?

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

Я надеюсь, что кто-то сможет мне помочь.

Для контекста, я просто пытаюсь основывать этот 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. Шаг 1: Извлечение необходимого URL в файле single-initiative.php.

  2. Шаг 2: Передача этого значения в functions.php для использования в качестве slugs.

  3. Шаг 3: Применение полученного значения в фильтрации slugs через register_post_type_args.

Применение

Для достижения этого цели, следуйте следующим шагам:

  1. Создание функции для генерации нужного 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;
    }
  2. Использование 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);
       }
    }
  3. Передача значений с помощью filters

    В конце шаблона single-initiative.php, перед регистрацией постов, примените фильтр:

    add_filter('initiative_slug_override', 'get_initiative_slug');

Этот процесс интеграции позволит динамически изменять slug для постов типа "initiative" на основе поля relationship родительского поста. Теперь это будет более устойчивое и поддерживаемое решение, следуя лучшим практикам разработки в WordPress.

Благодаря использованию actions и фильтров, мы создаем механизм обратного вызова, который укрепляет структуру кода и изолирует логику там, где это имеет место. Такой подход обеспечивает, что учитываются любые изменения в значениях URL, автоматически обновляя заблаговременно. Это не только улучшает структуру кода, но и гарантирует гибкость для будущих изменений.

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

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