Includere Tipi di Post Personalizzati nel Widget "Post Recenti"

30 set 2010, 17:36:06
Visualizzazioni: 22.8K
Voti: 7

Riesco facilmente a includere i miei tipi di post personalizzati nel loop principale apportando piccole modifiche con query_posts(), ma non sono sicuro di come fare per includere i tipi di post personalizzati nel widget "Post Recenti" nella sidebar (o in qualsiasi altro widget, del resto).

Come posso espandere l'ambito del widget "Post Recenti" per includere più del solo tipo di post nativo?

1
Commenti

Non usare mai query_posts()

Brad Dalton Brad Dalton
25 lug 2014 01:17:31
Tutte le risposte alla domanda 7
7

Dovrai modificare il codice del widget Articoli Recenti o creare la tua versione basata su quella predefinita. Il codice si trova nel file wp-includes/default-widgets.php intorno alla riga 513. Ma poiché non dovresti mai apportare modifiche al core, la mia raccomandazione è di copiare il codice per creare il tuo widget I Miei Articoli Recenti Personalizzati e utilizzarlo sul tuo sito. Basta inserire la nuova classe del widget nel file functions.php del tuo tema o utilizzarlo in un plugin.

L'unica modifica reale che devi fare riguarda il nome della classe del widget e le funzioni e le opzioni incapsulate (in modo che non ci siano conflitti di nomi con il widget originale Articoli Recenti). Successivamente, dovrai modificare la chiamata a WP_Query nel costruttore widget() in modo che includa il tuo tipo di post personalizzato.

Per questo esempio, ho impostato post_type uguale a array('post', 'page', 'custom-post-type') ... dovrai modificarlo in base al tuo caso d'uso specifico.

Ecco il codice completo del widget per riferimento:

/**
  * Classe del widget My_Custom_Recent_Posts
  *
  */
class WP_Widget_My_Custom_Recent_Posts extends WP_Widget {

    function __construct() {
        $widget_ops = array('classname' => 'widget_my_custom_recent_entries', 'description' => __( "Gli articoli più recenti del tuo sito") );
        $this->WP_Widget('my-custom-recent-posts', __('I Miei Articoli Recenti Personalizzati'), $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']) ? __('I Miei Articoli Recenti Personalizzati') : $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
        // Ripristina il globale $the_post poiché questa query lo avrà sovrascritto
        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('Titolo:'); ?></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('Numero di articoli da mostrare:'); ?></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
    }
}
30 set 2010 18:13:10
Commenti

Invece di rinominare il widget, penso che fare unregister_widget al widget predefinito prima di registrarne uno nuovo sarebbe meglio (meno confuso nell'admin).

sorich87 sorich87
30 set 2010 18:25:33

Sì, potresti usare unregister_widget, ma questo metodo ti dà accesso a entrambi nel caso volessi usarli entrambi (ad esempio avere un widget Post Recenti per mostrare i post recenti del blog e un widget Recensioni Film Recenti per mostrare solo i post recenti di un tipo di post personalizzato specifico).

EAMann EAMann
30 set 2010 18:31:55

solo una nota per chi prova il codice sopra: Non dimenticare di aggiungere questo: register_widget('WP_Widget_My_Custom_Recent_Posts');

Fredrik Holm Fredrik Holm
24 feb 2011 15:28:11

Grazie per aver fornito il codice per la classe del widget personalizzato e per le spiegazioni. Mi è stato molto utile. Tuttavia, mi chiedevo se ci fosse un modo per modificarlo per consentire l'HTML incorporato nel campo del titolo? In sostanza, ho bisogno di trasformare il titolo del widget in un link cliccabile, ma per impostazione predefinita l'HTML incorporato viene rimosso dai titoli dei widget. Qualsiasi aiuto sarebbe molto apprezzato.

Ian Young Ian Young
29 apr 2011 12:57:21

Ian, per favore fai questa domanda come una domanda separata in modo da poter avere una discussione completa...

EAMann EAMann
29 apr 2011 16:51:07

Non so nulla di PHP, ma non sarebbe possibile semplicemente Extend la classe predefinita e aggiornare le variabili richieste? Invece di un copia-incolla completo?

thornomad thornomad
10 mar 2012 23:02:18

Sfortunatamente la classe WP_Widget_Recent_Posts non si presta ad essere estesa con solo alcune proprietà modificate - gli elementi che necessitano di modifica si trovano nel mezzo di metodi piuttosto complessi.

Phil Gyford Phil Gyford
16 feb 2017 20:27:34
Mostra i restanti 2 commenti
0

A partire almeno dalla versione 3.6, puoi utilizzare il seguente codice per modificare la query utilizzata:

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;
}

Basta aggiungere i tipi che desideri nell'array per post_type e dovrebbero apparire.

Aggiornamento: Secondo http://core.trac.wordpress.org/ticket/16159, questa funzionalità è disponibile dalla versione 3.4

30 set 2013 00:30:12
0

Mi sono appena imbattuto in un fantastico plugin dove il lavoro pesante è già fatto, e ha un'ottima documentazione e supporto dall'autore. Sono rimasto davvero colpito.

Permette override di WP_Query (consentendoti di filtrare per custom post types e qualsiasi altra cosa tu voglia) e alcune chiare istruzioni su come usarlo.

Documentazione http://www.pjgalbraith.com/2011/08/recent-posts-plus/

URL del Plugin Wordpress http://wordpress.org/extend/plugins/recent-posts-plus/

Ha reso il mio lavoro solo quel po' più breve!

27 lug 2012 17:32:18
2

Puoi copiare il codice del widget (vedi /wp-includes/default-widgets.php) e modificare la riga della query.

30 set 2010 18:03:00
Commenti

Pensavo esattamente la stessa cosa... ma avevo già scritto metà della mia risposta quando hai postato questo...

EAMann EAMann
30 set 2010 18:13:48

La tua è molto completa! +1

sorich87 sorich87
30 set 2010 18:26:19
0

Ho anche creato un widget plugin per questo che è più personalizzabile del widget Articoli Recenti. Se sei interessato puoi scaricarlo qui http://new2wp.com/pro/latest-custom-post-type-posts-sidebar-widget/

30 gen 2011 13:20:28
0

Questo codice crea un nuovo widget per i post recenti che include i tuoi CPT

Ci sono 2 passaggi coinvolti nell'estensione del widget nativo dei post recenti:

i. Creare una nuova classe per il tuo widget personalizzato dei post recenti, che puoi fare copiando e rinominando il codice del widget dei post recenti dal file defaults-widgets.php nella cartella wp-includes.

ii. Poi dovrai registrare il nuovo widget e potrai scegliere se deregistrare il widget nativo dei post recenti o utilizzarli entrambi.

Tutto il codice può essere semplicemente copiato nel tuo file functions usando un child theme oppure creare un altro file e includerlo nel file functions del tuo child theme.

<?php

class WPSites_Recent_Posts extends WP_Widget {

    public function __construct() {
        $widget_ops = array('classname' => 'wpsites_recent_posts', 'description' => __( "Ultimi CPT e Post.") );
        parent::__construct('wpsites-recent-posts', __('Post Recenti di WP Sites'), $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'] : __( 'Post Recenti' );

        /** Questo filtro è documentato 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( 'Titolo:' ); ?></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( 'Numero di post da mostrare:' ); ?></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( 'Mostrare la data del post?' ); ?></label></p>
<?php
    }
}

Registra il nuovo widget personalizzato per i post recenti

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 );

Il codice include una modifica a WP_Query che include un array per i tipi di post incluso il CPT portfolio che puoi rinominare per adattarlo al tuo custom post type.

Ecco la riga di codice che deve essere modificata:

'post_type'           => array('post', 'portfolio',
26 lug 2014 02:15:27
0

È il 2020 e sono qui per trovare una soluzione ai "10 articoli più recenti del tipo di post personalizzato XYZ". Ho trovato il plugin che fa proprio questo, e molto altro.

Custom Post Type Widgets estende le funzionalità standard dei widget per i post tradizionali (più recenti, archivi mensili, categorie utilizzate, commenti recenti, ricerca, calendario) ai tipi di post personalizzati.

Selezioni il widget di cui hai bisogno (nel mio caso "più recenti") e ti viene presentata prima una selezione in cui specifichi il tipo di post personalizzato a cui il widget deve fare riferimento. La scelta predefinita è il buon vecchio 'post', quindi questo plugin è un sostituto dei widget predefiniti di WP relativi ai post.

24 feb 2020 07:28:09