Шорткод и get_template_part

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

Я разрабатываю собственный плагин для WordPress. Я создаю шорткод для своего плагина и тип поста с пользовательской таксономией и пользовательским постом типа.

Когда я пытаюсь использовать функцию get_template_part() в своем шорткоде, результатом является вызов шаблона single.php из темы. Как мне ограничить, где get_template_part может искать файлы?

Это мой шорткод:

function shortcode_display_products ( $atts ){

 global $wpdb;
 $query = '';

 $atts = shortcode_atts( array(
   'categories' => ''
 ), $atts, 'shortcode_display_products');


if( !empty($atts['categories']) && !is_null($atts['categories']) ){
$query = new WP_Query( array(
  'post_type'     =>  'products',
  'post_status'   => 'public',
  'tax_query' => array(
    array(
      'taxonomy'=> 'groups',
      'field'   => 'slug',
      'terms'   => '"'.$atts['categories'].'"'
    )
  ),
  'showposts'     =>  -1,
  'orderby'       =>  'date',
  'order'         =>  'DESC'
));
}
else{
$query = new WP_Query( array(
  'post_type'   =>  'products',
  'post_status' => 'public',
  'showposts'   =>  -1,
  'orderby'     =>  'date',
  'order'       =>  'DESC'
));
}
ob_start();

if( $query->have_posts() ){

  $c = 0;

  while ( $query -> have_posts() ){

      $query -> the_post();
      get_template_part('single','products');

    $c++;
 }
}
else{
 return esc_html__('Не найдено ни одного зарегистрированного продукта',P_TEXTDOMAIN);
}

wp_reset_postdata();

return ob_get_clean();

}

add_shortcode('display_products','shortcode_display_products');

Это мой single-products:

if ( !is_single() ){

 include '/form/products-form.php';
 $idnumber = ( is_single() )? '': '-'.$c;
?>

<div class="card">
  <div class="card-header" id="heading<?= $idnumber?>">
    <h5 class="mb-0">
      <button class="btn btn-link" data-toggle="collapse" data-target="#collapse<?= $idnumber?>" aria-expanded="true" aria-controls="collapse<?= $idnumber?>">
        <?= $post->title ?>
      </button>
    </h5>
  </div>
  <div id="collapse<?= $idnumber?>" class="collapse show" aria-labelledby="heading<?= $idnumber?>" data-parent="#accordion">
    <div class="card-body">
      <?= $post->content ?>
      <?php create_product_form() ?>
    </div>
  </div>
</div>

<?php }
else{ _e('ничего другого',P_TEXTDOMAIN);}

}

Функция get_template_part() загружает файл только из директории темы (или дочерней темы).
Нет фильтра или хука действия, который изменял бы это поведение.

Вам нужно будет написать свой собственный вариант get_template_part(), чтобы загружать файлы из директории плагина (замените вызов locate_template() из оригинальной функции). Или напишите явно:

$query->the_post();
include plugin_dir_path( __FILE__ ) . 'single-products.php';

Ответ или решение

Вопрос: Как ограничить путь для функции get_template_part() в шорткоде WordPress?

При разработке плагина для WordPress, использование шорткодов предоставляет гибкие возможности для отображения контента. Однако, когда вы пытаетесь использовать функцию get_template_part(), она по умолчанию загружает файлы только из директории вашей темы или дочерней темы. Это может быть проблемой, если вы хотите подключить файлы шаблонов из папки плагина.

Решение

  1. Создание собственной функции: Чтобы расширить функциональные возможности get_template_part(), вы можете создать свою версию этой функции, которая будет загружать файлы шаблонов непосредственно из вашего плагина. Ниже приведен пример, как можно реализовать такую функцию:
function get_plugin_template_part($slug, $name = null) {
    $template = '';

    // Формируем путь к файлу шаблона
    if ($name) {
        $template = plugin_dir_path(__FILE__) . "templates/{$slug}-{$name}.php";
    }

    // Проверяем наличие файла
    if (!$template || !file_exists($template)) {
        return;
    }

    include $template;
}
  1. Использование новой функции: Теперь в вашем шорткоде, вместо вызова get_template_part(), вы можете использовать get_plugin_template_part():
while ($query->have_posts()) {
    $query->the_post();
    get_plugin_template_part('single', 'products'); // Загрузка файла из папки плагина
}

Альтернативный подход

Если вы предпочитаете не создавать новую функцию, можно загружать файлы напрямую с использованием include:

while ($query->have_posts()) {
    $query->the_post();
    include plugin_dir_path(__FILE__) . 'templates/single-products.php'; // Укажите правильный путь к файлу
}

Контроль зависимостей и путей

Также обратите внимание на правильность указания имени файла и его расположение. Полный путь к файлу может быть определен с использованием функции plugin_dir_path(), чтобы избежать ошибок с доступностью файла.

Заключение

Существует несколько способов ограничить, откуда get_template_part() загружает шаблоны. Создание собственных функций или прямой вызов файлов через include — это надежные методы, которые позволяют вам сохранять контроль над структурой вашего плагина и безопасно подключать необходимые шаблоны. Используя подобные подходы, вы не только улучшите качество своего кода, но и создадите больше возможностей для расширения функционала вашего плагина.

Если у вас возникли дополнительные вопросы или потребуются уточнения по данной теме, не стесняйтесь их задавать — разработка плагинов для WordPress может быть сложной задачей, но с правильными инструментами и знаниями это возможно.

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

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