Obtener lista de años en los que se han publicado posts

21 may 2014, 21:04:26
Vistas: 19.4K
Votos: 7

Quiero crear una lista de posts de un Custom Post Type y añadir algunos filtros en los que el usuario pueda hacer clic para filtrar la lista.

Añadí filtros para todas las categorías usando la función get_terms(). Ahora quiero añadir filtros por año, así que necesito una forma de recuperar una lista de todos los años en los que se ha publicado al menos un post...

Necesito algo como:

$years = get_all_years_with_posts();
// devuelve array( 2011, 2013, 2014 )

Sé que puedo obtener todos los posts, comprobar su año y construir la lista manualmente, pero ¿no hay algún otro enfoque?

0
Todas las respuestas a la pregunta 5
6
16

Tu pregunta es bastante antigua, pero quería agregar una solución real a tu consulta. Aquí hay una función que devolverá un array de años en los que has publicado posts. Puedes colocar esta función en functions.php o en un plugin o donde prefieras.

function get_posts_years_array() {
    global $wpdb;
    $result = array();
    $years = $wpdb->get_results(
        $wpdb->prepare(
            "SELECT YEAR(post_date) FROM {$wpdb->posts} WHERE post_status = 'publish' GROUP BY YEAR(post_date) DESC"
        ),
        ARRAY_N
    );
    if ( is_array( $years ) && count( $years ) > 0 ) {
        foreach ( $years as $year ) {
            $result[] = $year[0];
        }
    }
    return $result;
}

Necesitarás modificarla ligeramente para tipos de posts personalizados... solo agrega AND wp_posts.post_type = 'mi_cpt' en alguna parte de la consulta.

17 jul 2017 15:49:21
Comentarios

Necesité ajustarlo ligeramente. Creo que prepare() requiere que proporciones al menos un argumento de formato %s (ver https://wordpress.stackexchange.com/a/270970/11914. Pero funcionó y lo voté positivamente.

yuvilio yuvilio
5 abr 2018 20:33:14

¿Qué hace que esta sea la solución real?

idleberg idleberg
26 abr 2019 11:14:56

@idleberg Porque en el momento en que publiqué mi respuesta, la otra persona que respondió malinterpretó la pregunta. Dieron un ejemplo de cómo obtener todas las publicaciones ordenadas por año, pero el OP quería obtener una lista de años que tuvieran publicaciones.

Gavin Gavin
10 may 2019 09:48:34

Esto funciona, sin embargo, recupera todas las publicaciones sin tener en cuenta el tipo — asegúrate de aplicar el filtro de tipo de publicación apropiado (WHERE post_type = 'posts') de lo contrario también devolverá publicaciones de páginas.

Vincent Edward Gedaria Binua Vincent Edward Gedaria Binua
28 feb 2021 08:42:50

Recibo un aviso 'El argumento query de wpdb::prepare() debe tener un marcador de posición' con este código cuando el modo de depuración está activado. Por favor edita esta respuesta para incluir marcadores de posición.

user45288 user45288
7 abr 2021 22:17:04

@user45288 ¿Por qué no simplemente eliminar el prepare si no hay parámetros?

Rup Rup
8 abr 2021 02:23:31
Mostrar los 1 comentarios restantes
1

Puedes usar esta función para obtener todos los años de los posts en un array, el cual podrías usar para iterar.

$terms_year = array(
    'post_type'         => array('TU_CPT'),
);

$years = array();
$query_year = new WP_Query( $terms_year );

if ( $query_year->have_posts() ) :
    while ( $query_year->have_posts() ) : $query_year->the_post();
        $year = get_the_date('Y');
        if(!in_array($year, $years)){
            $years[] = $year;
        }
    endwhile;
    wp_reset_postdata();
endif;

// Muestra los años donde quieras

echo '<pre>';
print_r($years);
echo '</pre>';
27 ago 2018 12:51:53
Comentarios

Esta solución funciona bien cuando se corrige el error tipográfico (reemplazar $query_jaar con query_year).

idleberg idleberg
26 abr 2019 11:14:26
0

Podrías usar una función de WP y un shortcode de esta manera:

add_shortcode( 'archives', '_get_archived_posts' );
function _get_archived_posts( $atts ) {

 $a = shortcode_atts( array(
    'type'            => 'yearly',
    'limit'           => '',
    'format'          => '', 
    'before'          => '',
    'after'           => '',
    'show_post_count' => false,
    'echo'            => 0,
    'order'           => 'DESC'
), $atts, 'filter_archives_sc' );

    return wp_get_archives($a);
}

Fuente

21 may 2014 21:20:13
0
// Obtener todos los años de publicación de posts;
function get_posts_years_array($post_type = 'post') {

    global $wpdb;
    $result = array();

    // Preparar consulta SQL para obtener años de posts publicados
    $query_prepare = $wpdb->prepare("SELECT YEAR(post_date) FROM ($wpdb->posts) WHERE post_status = 'publish' AND post_type = %s GROUP BY YEAR(post_date) DESC", $post_type);

    // Ejecutar consulta
    $years = $wpdb->get_results($query_prepare);

    // Procesar resultados
    if ( is_array( $years ) && count( $years ) > 0 ) {
        foreach ( $years as $year ) {
            $result[] = json_decode(json_encode($year), true);
        }
    }

    return $result;
}
16 sept 2019 16:06:44
0

Tomé la solución de @Gavin y la mejoré para agregar soporte para cualquier tipo de publicación y cualquier estado de publicación:

/**
 * Obtiene un array de años disponibles para cualquier tipo de publicación con cualquier estado de publicación
 * @see https://wordpress.stackexchange.com/a/273627/18713
 */
private function get_years_with_posts(
    string $post_type = 'post',
    array $post_stati = ['publish']
): array {
    /** @var wpdb $wpdb */
    global $wpdb;

    /** Convierte el array $post_stati al equivalente MySql IN */
    $post_status_in = "('" . implode("', '", array_map('esc_sql', $post_stati)) . "')";

    /** Prepara la consulta con el tipo de publicación seleccionado */
    $query = $wpdb->prepare(
        "SELECT YEAR(post_date)
        FROM {$wpdb->posts}
        WHERE post_status IN $post_status_in
        AND post_type = %s
        GROUP BY YEAR(post_date) DESC",
        $post_type
    );

    $years = $wpdb->get_results($query, ARRAY_N);

    return array_column($years, 0);
}

Ejemplo de uso: Recuperar todas las publicaciones publicadas y programadas del tipo event:

$avaliable_years = get_years_with_posts('event', ['publish', 'future']);
20 feb 2024 12:07:18