sampson
  • 0
Учитель

Включение пользовательских типов сообщений в виджет «Последние сообщения»

  • 0

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

Как мне расширить область действия «Последние сообщения», чтобы включить больше, чем просто собственный тип сообщений?

Share
  1. Никогда не используйте query_posts()

    • 0
  2. Вам придется отредактировать код виджета « Последние сообщения » или создать собственную версию на основе значения по умолчанию. Код находится в wp-includes/default-widgets.php файле около строки 513. Но, поскольку вам никогда не следует вносить изменения в ядро, я бы порекомендовал скопировать код, чтобы создать свой собственный виджет «Мои пользовательские последние сообщения » и использовать его на своем сайте. Просто поместите новый класс виджета в functions.php файл вашей темы или используйте его в плагине.

    Единственная реальная модификация, которую вам нужно внести, — это имя класса виджета и инкапсулированные функции и параметры (чтобы не возникало конфликтов имен с исходным виджетом « Последние сообщения ». После этого вам нужно будет отредактировать вызов WP_Query в widget() конструктор, чтобы он включал ваш пользовательский тип записи.

    Для этого примера я установил post_type равным array('post, 'page', 'custom-post-type') … вам нужно будет изменить его, чтобы он соответствовал вашему конкретному варианту использования.

    Вот полный код виджета для справки:

    /**
      * My_Custom_Recent_Posts widget class
      *
      */
    class WP_Widget_My_Custom_Recent_Posts extends WP_Widget {
    
        function __construct() {
            $widget_ops = array('classname' => 'widget_my_custom_recent_entries', 'description' => __( "The most recent posts on your site") );
            $this->WP_Widget('my-custom-recent-posts', __('My Custom Recent Posts'), $widget_ops);
            $this->alt_option_name = 'widget_my_custom_recent_entries';
    
            add_action( 'save_post', array(&$this, 'flush_widget_cache') );
            add_action( 'deleted_post', array(&$this, 'flush_widget_cache') );
            add_action( 'switch_theme', array(&$this, 'flush_widget_cache') );
        }
    
        function widget($args, $instance) {
            $cache = wp_cache_get('widget_my_custom_recent_posts', 'widget');
    
            if ( !is_array($cache) )
                $cache = array();
    
            if ( isset($cache[$args['widget_id']]) ) {
                echo $cache[$args['widget_id']];
                return;
            }
    
            ob_start();
            extract($args);
    
            $title = apply_filters('widget_title', empty($instance['title']) ? __('My Custom Recent Posts') : $instance['title'], $instance, $this->id_base);
            if ( !$number = (int) $instance['number'] )
                $number = 10;
            else if ( $number < 1 )
                $number = 1;
            else if ( $number > 15 )
                $number = 15;
    
            $r = new WP_Query(array('showposts' => $number, 'nopaging' => 0, 'post_status' => 'publish', 'ignore_sticky_posts' => true, 'post_type' => array('post', 'page', 'custom-post-type')));
            if ($r->have_posts()) :
    ?>
            <?php echo $before_widget; ?>
            <?php if ( $title ) echo $before_title . $title . $after_title; ?>
            <ul>
            <?php  while ($r->have_posts()) : $r->the_post(); ?>
            <li><a href="<?php the_permalink() ?>" title="<?php echo esc_attr(get_the_title() ? get_the_title() : get_the_ID()); ?>"><?php if ( get_the_title() ) the_title(); else the_ID(); ?></a></li>
            <?php endwhile; ?>
            </ul>
            <?php echo $after_widget; ?>
    <?php
            // Reset the global $the_post as this query will have stomped on it
            wp_reset_postdata();
    
            endif;
    
            $cache[$args['widget_id']] = ob_get_flush();
            wp_cache_set('widget_my_custom_recent_posts', $cache, 'widget');
        }
    
        function update( $new_instance, $old_instance ) {
            $instance = $old_instance;
            $instance['title'] = strip_tags($new_instance['title']);
            $instance['number'] = (int) $new_instance['number'];
            $this->flush_widget_cache();
    
            $alloptions = wp_cache_get( 'alloptions', 'options' );
            if ( isset($alloptions['widget_my_custom_recent_entries']) )
                delete_option('widget_my_custom_recent_entries');
    
            return $instance;
        }
    
        function flush_widget_cache() {
            wp_cache_delete('widget_my_custom_recent_posts', 'widget');
        }
    
        function form( $instance ) {
            $title = isset($instance['title']) ? esc_attr($instance['title']) : '';
            if ( !isset($instance['number']) || !$number = (int) $instance['number'] )
                $number = 5;
    ?>
            <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" /></p>
    
            <p><label for="<?php echo $this->get_field_id('number'); ?>"><?php _e('Number of posts to show:'); ?></label>
            <input id="<?php echo $this->get_field_id('number'); ?>" name="<?php echo $this->get_field_name('number'); ?>" type="text" value="<?php echo $number; ?>" size="3" /></p>
    <?php
        }
    }
    
    • 0
  3. Начиная с версии 3.6 вы можете использовать следующий код для изменения используемого запроса:

    add_filter('widget_posts_args', 'widget_posts_args_add_custom_type'); 
    function widget_posts_args_add_custom_type($params) {
       $params['post_type'] = array('post','custom_type');
       return $params;
    }
    

    Просто добавьте нужные типы в массив для post_type, и они должны появиться.

    Обновление: Согласно http://core.trac.wordpress.org/ticket/16159, это доступно с версии 3.4.

    • 0
  4. Я только что наткнулся на отличный плагин, в котором уже проделана тяжелая работа, и у него отличная документация и авторская поддержка. Я действительно был впечатлен.

    Он позволяет переопределять WP_Query (позволяя вам фильтровать пользовательские типы сообщений и все, что вы хотите) и некоторые четкие инструкции о том, как его использовать.

    Документация http://www.pjgalbraith.com/2011/08/recent-posts-plus/

    URL плагина WordPress http://wordpress.org/extend/plugins/recent-posts-plus/

    Сделал мою работу намного короче!

    • 0
  5. Вы можете скопировать код виджета (см. /wp-includes/default-widgets.php) и изменить строку запроса.

    • 0
  6. Я также создал для этого плагин виджета, который более настраиваемый, чем виджет «Последние сообщения». Если интересно, вы можете скачать его здесь http://new2wp.com/pro/latest-custom-post-type-posts-sidebar-widget/

    • 0
  7. Этот код создает новый виджет последних сообщений, который включает ваши CPT.

    При расширении собственного виджета последних сообщений необходимо выполнить 2 шага:

    я. Создайте новый класс для вашего пользовательского виджета последних сообщений, который вы можете сделать, скопировав и переименовав код виджета последних сообщений из defaults-widgets.php в папке wp-includes.

    II. Затем вам также нужно будет зарегистрировать новый виджет, и вы можете отменить регистрацию собственного виджета последних сообщений или использовать оба.

    Весь код можно просто скопировать в файл функций с помощью дочерней темы или создать другой файл и включить его в файл функций дочерней темы.

    <?php
    
    class WPSites_Recent_Posts extends WP_Widget {
    
        public function __construct() {
            $widget_ops = array('classname' => 'wpsites_recent_posts', 'description' => __( "Latest CPT's & Posts.") );
            parent::__construct('wpsites-recent-posts', __('WP Sites Recent Posts'), $widget_ops);
            $this->alt_option_name = 'wpsites_recent_posts';
    
            add_action( 'save_post', array($this, 'flush_widget_cache') );
            add_action( 'deleted_post', array($this, 'flush_widget_cache') );
            add_action( 'switch_theme', array($this, 'flush_widget_cache') );
        }
    
        public function widget($args, $instance) {
            $cache = array();
            if ( ! $this->is_preview() ) {
                $cache = wp_cache_get( 'wpsites_widget_recent_posts', 'widget' );
            }
    
            if ( ! is_array( $cache ) ) {
                $cache = array();
            }
    
            if ( ! isset( $args['widget_id'] ) ) {
                $args['widget_id'] = $this->id;
            }
    
            if ( isset( $cache[ $args['widget_id'] ] ) ) {
                echo $cache[ $args['widget_id'] ];
                return;
            }
    
            ob_start();
    
            $title = ( ! empty( $instance['title'] ) ) ? $instance['title'] : __( 'Recent Posts' );
    
            /** This filter is documented in wp-includes/default-widgets.php */
            $title = apply_filters( 'widget_title', $title, $instance, $this->id_base );
    
            $number = ( ! empty( $instance['number'] ) ) ? absint( $instance['number'] ) : 5;
            if ( ! $number )
                $number = 5;
            $show_date = isset( $instance['show_date'] ) ? $instance['show_date'] : false;
    
    
            $r = new WP_Query( apply_filters( 'widget_posts_args', array(
                'posts_per_page'      => $number,
                'no_found_rows'       => true,
                'post_status'         => 'publish',
                'post_type'           => array('post', 'portfolio',
                'ignore_sticky_posts' => true
            ) ) ) );
    
            if ($r->have_posts()) :
    ?>
            <?php echo $args['before_widget']; ?>
            <?php if ( $title ) {
                echo $args['before_title'] . $title . $args['after_title'];
            } ?>
            <ul>
            <?php while ( $r->have_posts() ) : $r->the_post(); ?>
                <li>
                    <a href="<?php the_permalink(); ?>"><?php get_the_title() ? the_title() : the_ID(); ?></a>
                <?php if ( $show_date ) : ?>
                    <span class="post-date"><?php echo get_the_date(); ?></span>
                <?php endif; ?>
                </li>
            <?php endwhile; ?>
            </ul>
            <?php echo $args['after_widget']; ?>
    <?php
    
            wp_reset_postdata();
    
            endif;
    
            if ( ! $this->is_preview() ) {
                $cache[ $args['widget_id'] ] = ob_get_flush();
                wp_cache_set( 'wpsites_widget_recent_posts', $cache, 'widget' );
            } else {
                ob_end_flush();
            }
        }
    
        public function update( $new_instance, $old_instance ) {
            $instance = $old_instance;
            $instance['title'] = strip_tags($new_instance['title']);
            $instance['number'] = (int) $new_instance['number'];
            $instance['show_date'] = isset( $new_instance['show_date'] ) ? (bool) $new_instance['show_date'] : false;
            $this->flush_widget_cache();
    
            $alloptions = wp_cache_get( 'alloptions', 'options' );
            if ( isset($alloptions['wpsites_recent_posts']) )
                delete_option('wpsites_recent_posts');
    
            return $instance;
        }
    
        public function flush_widget_cache() {
            wp_cache_delete('wpsites_widget_recent_posts', 'widget');
        }
    
        public function form( $instance ) {
            $title     = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
            $number    = isset( $instance['number'] ) ? absint( $instance['number'] ) : 5;
            $show_date = isset( $instance['show_date'] ) ? (bool) $instance['show_date'] : false;
    ?>
            <p><label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo $title; ?>" /></p>
    
            <p><label for="<?php echo $this->get_field_id( 'number' ); ?>"><?php _e( 'Number of posts to show:' ); ?></label>
            <input id="<?php echo $this->get_field_id( 'number' ); ?>" name="<?php echo $this->get_field_name( 'number' ); ?>" type="text" value="<?php echo $number; ?>" size="3" /></p>
    
            <p><input class="checkbox" type="checkbox" <?php checked( $show_date ); ?> id="<?php echo $this->get_field_id( 'show_date' ); ?>" name="<?php echo $this->get_field_name( 'show_date' ); ?>" />
            <label for="<?php echo $this->get_field_id( 'show_date' ); ?>"><?php _e( 'Display post date?' ); ?></label></p>
    <?php
        }
    }
    

    Зарегистрируйте новый пользовательский виджет последних сообщений

    function wpsites_widgets_init() {
        if ( !is_blog_installed() )
            return;
    
        register_widget('WPSites_Recent_Posts');
        do_action( 'widgets_init' );
    }
    
    add_action( 'init', 'wpsites_widgets_init', 2 );
    

    Код включает модифицированный WP_Query, который включает в себя массив для типов сообщений, включая CPT портфолио, который вы можете переименовать, чтобы он соответствовал вашему пользовательскому типу сообщений.

    Вот строка кода, которую нужно изменить:

    'post_type'           => array('post', 'portfolio',
    
    • 0
  8. На дворе 2020 год, и я пришел сюда, чтобы найти решение проблемы «10 самых последних пользовательских сообщений типа XYZ». Я нашел плагин , который делает это и многое другое.

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

    Вы выбираете нужный виджет (в моем случае «самый последний»), и сначала вы получаете выбор, в котором вы указываете настраиваемый тип сообщения, на который должен ориентироваться виджет. Выбор по умолчанию — старый добрый «пост», поэтому этот плагин является заменой ванильных виджетов WP, связанных с постами.

    • 0

Оставить ответ

You must login to add an answer.