Изменить функцию Shortcode_atts

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

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().

  1. Вы должны передать шорткоду массив значений по умолчанию в первом
    аргументе, что вы и сделали.
  2. Затем вам нужно передать аргументы, предоставленные пользователем, во втором
    аргументе, что вы не сделали. Ваш обратный вызов шорткода использует
    $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;
}

Основные Изменения и Объяснения:

  1. Использование shortcode_atts(): Теперь мы передаем пользовательские параметры в функцию shortcode_atts() как второй аргумент, чтобы объединить их с параметрами по умолчанию.

  2. Удаление extract(): Мы не используем extract(), чтобы избежать путаницы в именах переменных. Все обращения к параметрам теперь происходят через $params.

  3. Обработка постов: Логика для построения HTML-кода для вывода постов остается прежней, но теперь она использует обновленный массив $params.

  4. Кэширование: Логика кэширования сохраняет результат работы запроса для повышения производительности в будущем.

Заключение:

Обновленная функция get_date_posts теперь позволяет пользователю указывать до 5 постов (или любое другое количество) через шорткод, сохраняя при этом все остальные параметры, включая сортировку по метаполям. Используя правильные подходы и функции, мы гарантируем, что код будет понятным и легко поддерживаемым.

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

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