Вопрос или проблема
function get_date_posts($params, $content){
$default_params = array(
'post_type' => 'post',
'order' => 'asc',
'orderby' => 'meta_value',
'posts_per_page'=> 5,
'meta_key' => 'fl_date_picker'
);
if (isset($params['type']) && !empty($params['type']) && post_type_exists($params['type']))
$params['post_type'] = $params['type'];
if (isset($params['taxonomy']) && !empty($params['taxonomy']) && taxonomy_exists($params['taxonomy'])
&& isset($params['slug']) && !empty($params['slug']))
$params[$params['taxonomy']] = $params['slug'];
foreach(array('type', 'slug', 'taxonomy') as $key)
if (isset($params[$key]))
unset($params[$key]);
$params = wp_parse_args($params, $default_params);
$params['meta_query'] = array( array(
'key' => $params['meta_key'],
'value' => date("Ymd"),
'compare' => '>=',
'type'=> 'date'
)
);
$transient_hash="get_date_posts_".substr(md5(serialize($params)),0,10);
if (false === ($html = get_transient($transient_hash))){
add_filter('query', 'q');
global $request_sql;
// init
$html="";
$rp = new WP_Query($params);
// $html .= '<h2>START</h2>';
// $html .= '<pre>'.var_export($params, 1).'</pre>';
// $html .= $request_sql.'<hr>';
if ($rp->have_posts()){
$html .= '<ul>';
while ( $rp->have_posts() ) {
$rp->the_post();
$html .= "<li>";
if (($thumb_id = get_post_thumbnail_id())){
$thumb = wp_get_attachment_image_src($thumb_id, 'panel-small', false);
$flag = get_field('fl_country');
$html .= "<a href="https://wordpress.stackexchange.com/questions/135844/.get_permalink()."><div id=\"calimgf\" style=\"background:url({$thumb['0']}) no-repeat left top;\">";
$html .= "<span id=\"loullos\" style=\"float:right;\" class="". $flag ."" >" ."</span>";
}
$html .= "<span class=\"calendate\" >".get_field('fl_event_date')."</span>";
$html .= "<span class=\"calenhead\" >".get_field('fl_event_title')."</span>";
// debug
// $html .= "<small>".get_post_meta(get_the_id(), $params['meta_key'], 1)."</small>";
$html .= "</div></a></li>";
}
$html .= '</ul>';
}
if (!empty($html))
set_transient($transient_hash, $html, 60);
}
return $html;
}
Функция выше сортирует записи по дате, используя пользовательское поле 'fl_date_picker'
Мне нужно изменить эту функцию так, чтобы пользователь указывал количество записей для отображения в шорткоде. Для этого я пробовал использовать:
extract( shortcode_atts( array(
'post_type' => 'post',
'order' => 'asc',
'orderby' => 'meta_value',
'posts_per_page'=> 5,
'meta_key' => 'fl_date_picker'
), $atts ) );
Однако fl_date_picker
больше не работает, если я это сделаю, и порядок записей не сохраняется.
Вы неправильно используете shortcode_atts()
.
- Вы должны передать шорткоду массив значений по умолчанию в первом
аргументе, что вы и сделали. - Затем вам нужно передать аргументы, предоставленные пользователем, во втором
аргументе, что вы не сделали. Ваш обратный вызов шорткода использует
$params
, однако по какой-то причине вы передаете$atts
, который не
определен в вашей функции.
Кроме того, вы используете extract()
, что создаст переменные из предоставленного массива. Однако ваш код не написан для использования этих полученных переменных. Он по-прежнему использует $params
. extract()
— на мой взгляд, запутанный способ написания кода. Оставайтесь с $params
.
Доказательство концепции:
function my_sc_cb($params="") {
$params = shortcode_atts(
array(
'post_type' => 'post',
'order' => 'asc',
'orderby' => 'meta_value',
'posts_per_page'=> 5,
'meta_key' => 'fl_date_picker'
),
$params
);
var_dump($params); // отладка
}
add_shortcode('msccb','my_sc_cb');
do_shortcode('[msccb post_type="page"]');
Ответ или решение
Чтобы модифицировать функцию get_date_posts
так, чтобы пользователь мог указывать количество постов, отображаемых при использовании шорткода, важно правильно использовать функцию shortcode_atts()
. Также следует оставить согласованность в именах переменных и избавиться от использования функции extract()
, которая может привести к путанице.
Вот как должна выглядеть обновленная версия функции:
function get_date_posts($params, $content) {
// Определяем массив параметров по умолчанию
$default_params = array(
'post_type' => 'post',
'order' => 'asc',
'orderby' => 'meta_value',
'posts_per_page'=> 5,
'meta_key' => 'fl_date_picker',
);
// Объединяем параметры по умолчанию с пользовательскими
$params = shortcode_atts($default_params, $params);
// Проверяем, существует ли указанный тип поста, и если да, изменяем тип поста
if (isset($params['post_type']) && !empty($params['post_type']) && post_type_exists($params['post_type'])) {
$params['post_type'] = $params['post_type'];
}
// Проверяем таксономию и слаг, если они указаны
if (isset($params['taxonomy']) && !empty($params['taxonomy']) && taxonomy_exists($params['taxonomy'])
&& isset($params['slug']) && !empty($params['slug'])) {
$params[$params['taxonomy']] = $params['slug'];
}
// Удаляем ключи, которые не нужны дальше
foreach(array('type', 'slug', 'taxonomy') as $key) {
if (isset($params[$key])) {
unset($params[$key]);
}
}
// Конструируем массив для meta_query
$params['meta_query'] = array(array(
'key' => $params['meta_key'],
'value' => date("Ymd"),
'compare' => '>=',
'type' => 'DATE',
));
// Генерируем хеш для кэша
$transient_hash = "get_date_posts_" . substr(md5(serialize($params)), 0, 10);
// Проверяем, есть ли уже кэш
if (false === ($html = get_transient($transient_hash))) {
global $request_sql;
// Инициализация
$html = "";
$rp = new WP_Query($params);
if ($rp->have_posts()) {
$html .= '<ul>';
while ($rp->have_posts()) {
$rp->the_post();
$html .= '<li>';
if ($thumb_id = get_post_thumbnail_id()) {
$thumb = wp_get_attachment_image_src($thumb_id, 'panel-small', false);
$flag = get_field('fl_country');
$html .= '<a href="' . get_permalink() . '"><div id="calimgf" style="background:url(' . $thumb[0] . ') no-repeat left top;">';
$html .= '<span id="loullos" style="float:right;" class="' . $flag . '"></span>';
}
$html .= '<span class="calendate">' . get_field('fl_event_date') . '</span>';
$html .= '<span class="calenhead">' . get_field('fl_event_title') . '</span>';
$html .= '</div></a></li>';
}
$html .= '</ul>';
}
// Кешируем результат
if (!empty($html)) {
set_transient($transient_hash, $html, 60);
}
}
return $html;
}
Основные Изменения и Объяснения:
-
Использование
shortcode_atts()
: Теперь мы передаем пользовательские параметры в функциюshortcode_atts()
как второй аргумент, чтобы объединить их с параметрами по умолчанию. -
Удаление
extract()
: Мы не используемextract()
, чтобы избежать путаницы в именах переменных. Все обращения к параметрам теперь происходят через$params
. -
Обработка постов: Логика для построения HTML-кода для вывода постов остается прежней, но теперь она использует обновленный массив
$params
. -
Кэширование: Логика кэширования сохраняет результат работы запроса для повышения производительности в будущем.
Заключение:
Обновленная функция get_date_posts
теперь позволяет пользователю указывать до 5 постов (или любое другое количество) через шорткод, сохраняя при этом все остальные параметры, включая сортировку по метаполям. Используя правильные подходы и функции, мы гарантируем, что код будет понятным и легко поддерживаемым.