Вопрос или проблема
Я пытаюсь создать шорткод, который отображает результаты пользовательского запроса (вызывая элементы меню) для сайта бизнеса по доставке еды. Я пытался настроить атрибуты категории так, чтобы на главной странице я мог использовать [himenu cat=”special-offers”], что является слагом использованной категории для отображения специальных предложений. Это работает отлично, проблем нет, однако я испытываю трудности с реализацией следующего (как вы увидите из моего кода ниже)
1- на странице ‘полное меню’ я хотел бы использовать тот же шорткод, который отображает все элементы меню, просто оставив атрибут cat пустым
2 – на странице полного меню, перечислить все элементы меню под соответствующим заголовком категории, например:
БУРГЕРЫ
пункт 1
пункт 2
пункт 3
пункт 4
КЕБАБЫ
пункт 1
пункт 2
пункт 3
и т.д.
Я настроил категории для пользовательского типа постов, поэтому думаю, что мне нужно найти категории и пройти через них перед выполнением запроса? Буду признателен за любой совет, я потратил целое утро на это безуспешно.
Спасибо
//ШОРТКОД МЕНЮ
add_shortcode( 'himenu', 'cat_post' );
function cat_post($atts){
// атрибуты для шорткода
if (isset($atts['cat'])) {$cat = $atts['cat'];} else {return;}
if (isset($atts['posts_per_page'])) {$posts_per_page = $atts['posts_per_page'];} else {$posts_per_page = -1;}
// получаем посты категории
$category = get_category_by_slug($cat);
if (!is_object($category)) {return;}
$args = array(
'cat' => $category->term_id,
'post_type' => menu_item,
'posts_per_page' => $posts_per_page,
'order' => 'ASC',
'orderby' => 'title'
);
$query = new WP_Query($args);
while ($query->have_posts()) : $query->the_post(); ?>
<div class="indi-menu-item">
<div class="menu-item-column">
<h5> <?php
if($cat === 'special-offers'){
echo 'Специальные предложения';
} else {
the_category();
}
?></h5>
<div class="menu-item-meta">
<h4> <?php the_title(); ?></h4>
<p><?php the_field('description')?></p>
</div>
</div>
<div class="menu-item-column">
<h2>£<?php the_field('price'); ?></h2>
</div>
</div>
<?php endwhile;
wp_reset_postdata(); // сбросить запрос
}
wp_reset_query();// сбросить глобальную переменную, связанную с циклом постов
?>
Я нашел ответ на этот запрос. Используя упрощенную версию моего исходного кода, я могу передать категорию, чтобы показать только эту категорию или, если она пустая, показать все категории. Затем условие foreach проходит через все доступные категории и исчерпывает посты в каждой во время запроса.
Надеюсь, это поможет кому-то в какой-то момент 🙂
//ШОРТКОД МЕНЮ
add_shortcode('himenu', 'create_menu_shortcode');
function create_menu_shortcode ($atts){
$atts = shortcode_atts(
array(
'category' => ''
), $atts, 'himenu' );
$category = $atts["category"];
?> <?php
var_dump ($atts);
var_dump ($category);
$args_cat = [
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => 0,
];
$menu_categories = get_categories($args_cat);
//print_r($categories);
if (!empty($menu_categories)):
foreach ($menu_categories as $menu_category):
$args = [
'post_type' => 'menu_item',
'posts_per_page' => -1,
'order' => 'ASC',
'orderby' => 'title',
'category_name' => $category,
'cat' => $menu_category->term_id
];
$query = new WP_Query($args);
while ($query->have_posts()) : $query->the_post(); ?>
<div class="indi-menu-item">
<div class="menu-item-column">
<h5> <?php the_category(); ?></h5>
<div class="menu-item-meta">
<h4> <?php the_title(); ?></h4>
<p><?php the_field('description')?></p>
</div>
</div>
<div class="menu-item-column">
<h2>£<?php the_field('price'); ?></h2>
</div>
</div>
<?php endwhile;
wp_reset_postdata();
endforeach;
endif;?>
</div>
<?php } ?>
<?php wp_reset_query();// сбросить глобальную переменную, связанную с циклом постов
?>
Ответ или решение
Для решения задачи по созданию шорткода, который будет выводить меню на сайте бизнеса по тейкэю, необходимо учитывать несколько аспектов: выбор категорий, настройка запроса WP для получения необходимых постов и правильное формирование вывода.
Определение задачи
Вы хотите создать шорткод, который будет:
- Выводить элементы меню по заданной категории, если она имеется (например, специальные предложения).
- Выводить все элементы меню, если атрибут категории не указан.
- Группировать элементы меню по категориям при их выводе на странице полного меню.
Реализация шорткода
Ниже приведён оптимизированный код для вашего шорткода, который удовлетворяет всем указанным требованиям:
add_shortcode('himenu', 'create_menu_shortcode');
function create_menu_shortcode($atts) {
// Определим атрибуты шорткода
$atts = shortcode_atts(array(
'category' => '' // Атрибут для категории
), $atts, 'himenu');
// Получаем значение категории
$category = $atts['category'];
// Получаем все категории меню
$args_cat = array(
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => 0,
);
$menu_categories = get_categories($args_cat);
// Проверяем, есть ли доступные категории
if (!empty($menu_categories)) {
foreach ($menu_categories as $menu_category) {
// Подготовка аргументов для WP_Query
$args = array(
'post_type' => 'menu_item',
'posts_per_page' => -1,
'order' => 'ASC',
'orderby' => 'title',
// Проверяем, задана ли категория
'category_name' => !empty($category) ? $category : $menu_category->slug,
);
// Выполняем запрос
$query = new WP_Query($args);
// Если найдены записи, выводим их
if ($query->have_posts()) {
echo '<h3>' . esc_html($menu_category->name) . '</h3>'; // Заголовок для категории
while ($query->have_posts()) : $query->the_post();
?>
<div class="indi-menu-item">
<div class="menu-item-column">
<h5><?php the_category(', '); ?></h5>
<div class="menu-item-meta">
<h4><?php the_title(); ?></h4>
<p><?php the_field('description'); ?></p>
</div>
</div>
<div class="menu-item-column">
<h2>£<?php the_field('price'); ?></h2>
</div>
</div>
<?php
endwhile;
wp_reset_postdata(); // Сбрасываем данные запроса
}
}
}
wp_reset_query(); // Сбрасываем глобальную переменную, связанную с циклом постов
}
Пояснения к коду:
-
Шорткод
himenu
: Он принимает один атрибут –category
. Если этот атрибут не указан, будет выводиться содержимое всех категорий меню. -
Получение категорий: Мы используем функцию
get_categories()
для получения всех категорий, которые были заранее созданы для пользовательского типа постов (menu_item). -
Цикл по категориям: Для каждой категории выполняется запрос WP для получения постов с определённой категорией. Если атрибут
category
не передан, для запроса используются посты из всех категорий. -
Форматирование вывода: Для каждого поста выводится название категории, заголовок элемента меню, его описание и цена. Это все оборачивается в соответствующие HTML-контейнеры.
-
Безопасность: Везде, где это необходимо, применяется функция
esc_html()
, что защищает от XSS-атаки.
Заключение
Следуя этому подходу, вы сможете динамически выводить меню, основываясь на заданной категории, на любой странице вашего сайта. Также это обеспечит групповое представление элементов меню под каждой категорией на странице «Полное меню». Такой подход гарантирует, что ваш код будет читабельным, модульным и безопасным.