Incluir Custom Post Types en el Widget "Publicaciones Recientes"

30 sept 2010, 17:36:06
Vistas: 22.8K
Votos: 7

Puedo incluir fácilmente mis custom post types en el loop principal haciendo pequeños ajustes con query_posts(), pero no estoy seguro de cómo incluir custom post types en el widget "Publicaciones Recientes" de la barra lateral (o en cualquiera de los otros widgets).

¿Cómo debería proceder para expandir el alcance de "Publicaciones Recientes" para incluir más que solo el tipo de publicación nativo?

1
Comentarios

Nunca uses query_posts()

Brad Dalton Brad Dalton
25 jul 2014 01:17:31
Todas las respuestas a la pregunta 7
7

Tendrás que editar el código del widget Entradas recientes o crear tu propia versión basada en el predeterminado. El código está en el archivo wp-includes/default-widgets.php alrededor de la línea 513. Pero como nunca deberías modificar el núcleo, mi recomendación sería copiar el código para crear tu propio widget Mis Entradas Recientes Personalizadas y usarlo en tu sitio. Simplemente coloca la nueva clase del widget en el archivo functions.php de tu tema o utilízalo en un plugin.

La única modificación real que necesitas hacer son al nombre de la clase del widget y a las funciones y opciones encapsuladas (para que no haya conflictos de nombres con el widget original Entradas Recientes). Después de eso, necesitarás editar la llamada a WP_Query en el constructor widget() para que incluya tu tipo de entrada personalizado.

Para este ejemplo, he configurado post_type igual a array('post, 'page', 'custom-post-type')... necesitarás modificar esto para que se ajuste a tu caso de uso específico.

Aquí está el código completo del widget como referencia:

/**
  * Clase 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' => __( "Las entradas más recientes en tu sitio") );
        $this->WP_Widget('my-custom-recent-posts', __('Mis Entradas Recientes Personalizadas'), $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']) ? __('Mis Entradas Recientes Personalizadas') : $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
        // Restablece la variable global $the_post ya que esta consulta la habrá sobrescrito
        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('Título:'); ?></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('Número de entradas a mostrar:'); ?></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 sept 2010 18:13:10
Comentarios

En lugar de cambiar el nombre del widget, creo que sería mejor usar unregister_widget en el widget predeterminado antes de registrar el nuevo (menos confuso en el administrador).

sorich87 sorich87
30 sept 2010 18:25:33

Sí, podrías usar unregister_widget, pero este método te da acceso a ambos por si quieres usar los dos (es decir, tener un widget de Publicaciones Recientes para mostrar las entradas recientes del blog y un widget de Reseñas de Películas Recientes para mostrar solo las entradas recientes de un tipo de contenido personalizado específico).

EAMann EAMann
30 sept 2010 18:31:55

solo una nota para cualquiera que pruebe el código anterior: No olvides agregar esto: register_widget('WP_Widget_My_Custom_Recent_Posts');

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

Gracias por proporcionar el código para la clase de widget personalizado y por las explicaciones. Ha sido muy útil. Sin embargo, me preguntaba si habría alguna manera de modificarlo para permitir HTML incrustado en el campo del título. Básicamente necesito convertir el título del widget en un enlace clickable, pero por defecto el HTML incrustado es eliminado de los títulos de los widgets. Cualquier ayuda sería muy apreciada.

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

Ian, por favor pregunta eso como una pregunta separada para que podamos tener una discusión completa...

EAMann EAMann
29 abr 2011 16:51:07

No sé nada de PHP pero ¿no se podría simplemente Extend la clase por defecto y actualizar las variables requeridas? ¿En lugar de un copiar y pegar completo?

thornomad thornomad
10 mar 2012 23:02:18

Desafortunadamente, la clase WP_Widget_Recent_Posts no se presta para ser extendida y solo cambiar algunas propiedades - las cosas que necesitas cambiar están en medio de métodos bastante grandes.

Phil Gyford Phil Gyford
16 feb 2017 20:27:34
Mostrar los 2 comentarios restantes
0

A partir de al menos la versión 3.6, puedes usar el siguiente código para modificar la consulta utilizada:

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

Solo añade los tipos que quieras en el array para post_type y deberían aparecer.

Actualización: Según http://core.trac.wordpress.org/ticket/16159, esto ha estado disponible desde la versión 3.4

30 sept 2013 00:30:12
0

Acabo de encontrar un plugin genial donde el trabajo pesado ya está hecho, tiene una documentación excelente y buen soporte del autor. Realmente me ha impresionado.

Permite anulaciones de WP_Query (lo que te permite filtrar por tipos de entrada personalizados y cualquier otra cosa que desees) e incluye instrucciones claras sobre cómo usarlo.

Documentación http://www.pjgalbraith.com/2011/08/recent-posts-plus/

URL del plugin de WordPress http://wordpress.org/extend/plugins/recent-posts-plus/

¡Hizo que mi trabajo fuera mucho más corto!

27 jul 2012 17:32:18
2

Puedes copiar el código del widget (ver /wp-includes/default-widgets.php) y modificar la línea de consulta.

30 sept 2010 18:03:00
Comentarios

Exactamente lo que estaba pensando... pero ya iba a la mitad de escribir mi respuesta cuando publicaste esto...

EAMann EAMann
30 sept 2010 18:13:48

¡El tuyo está muy completo! +1

sorich87 sorich87
30 sept 2010 18:26:19
0

También he creado un widget plugin para esto que es más personalizable que el widget de Publicaciones Recientes. Si estás interesado, puedes descargarlo aquí http://new2wp.com/pro/latest-custom-post-type-posts-sidebar-widget/

30 ene 2011 13:20:28
0

Este código crea un nuevo widget de publicaciones recientes que incluye tus CPT's

Hay 2 pasos involucrados al extender el widget nativo de publicaciones recientes:

i. Crear una nueva clase para tu widget personalizado de publicaciones recientes, lo cual puedes hacer copiando y renombrando el código del widget de publicaciones recientes del archivo defaults-widgets.php en la carpeta wp-includes.

ii. Luego necesitarás registrar el nuevo widget y puedes elegir desregistrar el widget nativo de publicaciones recientes o usar ambos.

Todo el código puede copiarse directamente en tu archivo functions.php usando un tema hijo o crear otro archivo e incluirlo en el archivo functions.php de tu tema hijo.

<?php

class WPSites_Recent_Posts extends WP_Widget {

    public function __construct() {
        $widget_ops = array('classname' => 'wpsites_recent_posts', 'description' => __( "Últimos CPT's & Publicaciones.") );
        parent::__construct('wpsites-recent-posts', __('Publicaciones Recientes de 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'] : __( 'Publicaciones Recientes' );

        /** Este filtro está documentado en 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( 'Título:' ); ?></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( 'Número de publicaciones a mostrar:' ); ?></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( '¿Mostrar fecha de publicación?' ); ?></label></p>
<?php
    }
}

Registrar el nuevo widget personalizado de publicaciones recientes

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

El código incluye una WP_Query modificada que incluye un array para tipos de publicación incluyendo el CPT portfolio que puedes renombrar para que coincida con tu tipo de publicación personalizado.

Esta es la línea de código que necesita ser modificada:

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

Es 2020 y vine aquí buscando una solución para los "10 artículos más recientes del tipo de entrada personalizada XYZ". Encontré el plugin que hace eso y más.

Widgets para Tipos de Entradas Personalizadas extiende las funcionalidades estándar de los widgets para entradas habituales (más recientes, archivos mensuales, categorías utilizadas, comentarios recientes, búsqueda, calendario) a tipos de entradas personalizadas.

Seleccionas el widget que necesitas (en mi caso "más recientes") y primero obtienes un selector donde especificas el tipo de entrada personalizada al que debe dirigirse el widget. La opción predeterminada es el clásico 'post', por lo que este plugin es un sustituto de los widgets estándar de WordPress relacionados con entradas.

24 feb 2020 07:28:09