Mostrar publicaciones por mes

3

Quiero lograr algo como esto, no sé si es posible y cuál sería la mejor manera de hacerlo:

Laformaenqueconsultolaspublicacionesesasí:

<divclass="post">
    <?php global $wp_query;
    query_posts( array('post_type' => array( 'lecturas-post' ),'showposts' => 15, 'paged'=>$paged, 'order' => 'DESC' ));?>
    <?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
        <div><?php the_title() ?></a>
    <?php endwhile; // end of the loop. ?>
</div>

¿Alguien me puede dar una sugerencia sobre la mejor manera de hacerlo?

    
pregunta wpuser 27.01.2015 - 10:52

3 respuestas

9

Como se dijo en un comentario, puedes hacer esto en una consulta. El principio aquí es mostrar solo el encabezado de la fecha si el mes de la fecha de publicación de la publicación anterior no coincide con el de la publicación anterior

ALGUNAS NOTAS

Antes de empezar, algunas notas:

  • Nunca usa query_posts , excepto si realmente necesitas romper todo en una página. No solo vuelve a ejecutar la consulta principal y también la rompe, desordena la paginación y sus globales, y también confunde con sus funciones de objeto consultadas. Si realmente tiene que ejecutar una consulta personalizada, use WP_Query o get_posts

  • showposts se eliminó hace años en favor de posts_per_page

  • No es necesario utilizar el $wp_query global. query_posts confunde eso de todos modos

EL PLAN

Las publicaciones se publican en orden cronológico, con la publicación más reciente primero y la publicación más antigua al final, por lo que ya están en el orden correcto. Es solo una cuestión de mostrar la fecha en el lugar apropiado.

Para hacer esto, todo lo que necesita hacer es obtener el mes y año actuales de la fecha de publicación de la publicación actual, y luego compararlos con el mes de la fecha de publicación posterior de la publicación anterior y luego mostrar la fecha si los meses no lo hacen. coincide o no lo muestra si coinciden

Como explicación, usaré el bucle principal con la consulta principal.

Para lograr esto, necesitas:

  • Obtenga el mes a partir de la fecha de publicación de la publicación actual. Para lograr esto, use get_the_date( 'F' )

  • Obtenga la publicación anterior en el bucle con $wp_query->posts['this will be current post -1 ']->post .

  • Obtenga y compare los meses entre las dos publicaciones

  • Muestra o no muestra la fecha según la comparación

EL CÓDIGO

Este código va dentro de su bucle, justo después de su declaración while() .

$current_month = get_the_date('F');

if( $wp_query->current_post === 0 ) { 

   the_date( 'F Y' );

}else{ 

    $f = $wp_query->current_post - 1;       
    $old_date =   mysql2date( 'F', $wp_query->posts[$f]->post_date ); 

    if($current_month != $old_date) {

        the_date( 'F Y' );;

    }

}

CONSULTA PERSONALIZADA

Si necesita ejecutar una consulta personalizada, intente esto

$q = new WP_Query( array('post_type' => array( 'lecturas-post' ),'posts_per_page' => 15, 'paged'=>$paged, 'order' => 'DESC' ));

if( $q->have_posts() ) {
    while( $q->have_posts() ) {

        $q->the_post();

        $current_month = get_the_date('F');

        if( $q->current_post === 0 ) { 

           the_date( 'F Y' );

        }else{ 

            $f = $q->current_post - 1;       
            $old_date =   mysql2date( 'F', $q->posts[$f]->post_date ); 

            if($current_month != $old_date) {

                the_date( 'F Y' );;

            }

        }

        the_title();

    }

}
    
respondido por el Pieter Goosen 27.01.2015 - 15:44
4

Respuesta actualizada

Después de pensar en el comentario de @PieterGoosen a continuación, he agregado un método para lograr tu objetivo mediante una única consulta.

Realicé una prueba comparativa de los métodos y la consulta simple es más rápida, con el método de consulta múltiple siendo un 15% más lento . No es un gran margen, pero todo ayuda, y para ser honesto, el método probablemente se puede refinar aún más.

He dejado el método de consulta múltiple en la respuesta para la prosperidad, pero recomiendo que se use el método de consulta única.

Método de consulta única

$time_start = microtime(true);

/** Set up a date interval object for 6 monts ago (you can change as required) */
$interval = new DateInterval('P6M');
$interval->invert = 1;

/** Grab the date as it was 6 months ago */
$date = new DateTime(date('Y-m-d'));
$date->add($interval);

/** Query the database for all posts newer than the the given date interval */
$args = array(
    'nopaging'          => true,
    'posts_per_page'    => -1,
    'post_type'         => 'post',
    'post_status'       => 'publish',
    'order_by'          => 'date',
    'date_query'        => array(
        'after' => $date->format('Y-m-d')
    )
);
$month_query = new WP_Query($args);

/** Check to ensure that there are articles for this month... */
if($month_query->have_posts()) :

    $month_titles = array();
    $close_ul = false;


    //echo '<ul style="padding-left: 250px;" id="monthly-posts">';

    /** Set the attributes for displaying the title as an attribute */
    $title_attribute_args = array(
        'before'    => 'Visit article \'',
        'after'     => '\' ',
        'echo'      => false
    );      

    /** Loop through each post for this month... */
    while($month_query->have_posts()) : $month_query->the_post();

        /** Check the month/year of the current post */
        $month_title = date('F Y', strtotime(get_the_date('Y-m-d H:i:s')));

        /** Maybe output a human friendly date, if it's not already been output */
        if(!in_array($month_title, $month_titles)) :

            if($close_ul) echo '</ul>';                                                             // Check if the unordered list of posts should be closed (it shouldn't for the first '$monthe_title')
            echo '<h1 style="padding-left: 250px;" id="monthly-title">' . $month_title . '</h1>';   // Output the '$month_title'
            echo '<ul style="padding-left: 250px;" id="monthly-posts">';                            // Open an unordered lists for the posts that are to come
            $month_titles[] = $month_title;                                                         // Add this '$month_title' to the array of '$month_titles' so that it is not repeated
            $close_ul = true;                                                                       // Indicate that the unordered list should be closed at the next oppurtunity

        endif;

        /** Output each article for this month */
        printf(
            '<li id="monthly-post-%1$s">%2$s <a href="%3$s" title="%4$s">%3$s</a></li>',
            get_the_ID(),                               /** %1$s - The ID of the post */
            get_the_title(),                            /** %2$s - The article title */
            get_permalink(get_the_ID()),                /** %3$s - The article link */
            the_title_attribute($title_attribute_args)  /** %4$s - The title for use as an attribute */
        );

    endwhile;

    if($close_ul) echo '</ul>'; // Close the last unordered list of posts (if there are any shown)

endif;

/** Reset the query so that WP doesn't do funky stuff */
wp_reset_query();

Respuesta original

Prueba esto. Lo he configurado para que solo se seleccionen los últimos 6 meses y solo los últimos 5 mensajes de cada mes, pero puedes modificarlo como desees.

Esencialmente, el código primero verificará qué meses tienen publicaciones y luego publicará las últimas cinco publicaciones de ese mes, junto con un enlace.

Método de consulta múltiple

global $wpdb, $wp_locale;

/** Query the individual months to display (I've chosen the last 6 months) */
$query = $wpdb->prepare('
    SELECT DISTINCT YEAR('%1$s'.'post_date') AS year, MONTH('%1$s'.'post_date') AS month
    FROM '%1$s'
    WHERE '%1$s'.'post_type' = "post"
    ORDER BY '%1$s'.'post_date' DESC
    LIMIT 6',
    $wpdb->posts
);
$months = $wpdb->get_results($query);

/** Count the number of months */
$month_count = count($months);

/** Ensure that there are months to display... */
if($month_count || ($month_count === 1 && $months[0]->month > 0)) :

    /** Loop through each month... */
    foreach($months as $month) :

        if($month->year === 0) :
            continue;
        endif;

        /** Grab the individual month and year, and construct a human friendly date (for the title) */
        $m = zeroise($month->month, 2);
        $y = $month->year;
        $human_date = sprintf(__('%1$s %2$d'), $wp_locale->get_month($m), $y);

        /** Grab any posts for this month (I've chosedn only the last 5 posts) */
        $args = array(
            'nopaging'          => true,
            'posts_per_page'    => 5,
            'post_type'         => 'post',
            'post_status'       => 'publish',
            'order_by'          => 'date',
            'year'              => $y,
            'monthnum'          => $m
        );
        $month_query = new WP_Query($args);

        /** Check to ensure that there are articles for this month... */
        if($month_query->have_posts()) :

            /** Output a human friendly date */
            echo '<h1 id="monthly-title">' . $human_date . '</h1>';
            echo '<ul id="monthly-posts">';

            /** Set the attributes for displaying the title as an attribute */
            $title_attribute_args = array(
                'before'    => 'Visit article \'',
                'after'     => '\' ',
                'echo'      => false
            );      

            /** Loop through each post for this month... */
            while($month_query->have_posts()) : $month_query->the_post();

                /** Output each article for this month */
                printf(
                    '<li id="monthly-post-%1$s">%2$s <a href="%3$s" title="%4$s">%3$s</a></li>',
                    get_the_ID(),                               /** %1$s - The ID of the post */
                    get_the_title(),                            /** %2$s - The article title */
                    get_permalink(get_the_ID()),                /** %3$s - The article link */
                    the_title_attribute($title_attribute_args)  /** %4$s - The title for use as an attribute */
                );

            endwhile;

            echo '</ul>';

        endif;

        /** Reset the query so that WP doesn't do funky stuff */
        wp_reset_query();

    endforeach;

endif;
    
respondido por el David Gard 27.01.2015 - 13:29
1

Esta es una función que utilicé para las necesidades generales, para recuperar datos de tipos de publicaciones postales o personalizadas antes o después de un determinado año / mes o año actual, en el orden que necesite:

// you could change the name in case it collides with some other plugin
function get_posts_by_date($user_options = array()){

  $options = array(
    'year_limit' => '1980'
    ,'month_limit' => '01'
    ,'operator' => '>=' // date comparison operator
    ,'current_year' => true // limit data to current year
    ,'post_type' => 'post'
    ,'year_order' => 'DESC'
    ,'month_order' => 'DESC'
    ,'post_ids_order' => 'DESC'
    ,'raw_output' => false
  );

  extract(array_merge($options, $user_options));

  global $wpdb;

  if($operator == '>=' || $operator == '=='){
    $day = "01";
  } elseif($mode == '<='){
    $day = "31";
  }

  if($current_year){ // will be after [previous year]/12/31
    $year_limit = date('Y', strtotime('-1 year'));
    $month_limit = '12';
    $day = "31";
    $operator == '>=';
  }

  // warning: if your parameters come from user input/forms, 
  // pass them using $wpdb::prepare()
  // https://developer.wordpress.org/reference/classes/wpdb/prepare/
  $results = $wpdb->get_results("
    SELECT tbl.y year, group_concat(month_posts ORDER BY tbl.m " . $month_order . " SEPARATOR '-') months
      FROM (
        SELECT YEAR(p.post_date) y, MONTH(p.post_date) m, concat(MONTH(p.post_date), ':', group_concat(p.id ORDER BY p.post_date " . $post_ids_order . " )) month_posts
        FROM $wpdb->posts p
        WHERE (p.post_status = 'publish' OR p.post_status = 'future')
          AND p.post_type = '" . $post_type . "'
          AND p.post_date " . $operator . " DATE('" . $year_limit . "-" . $month_limit . "-" . $day . " 00:00:00')
        GROUP BY y, m
      ) tbl
    GROUP BY tbl.y
    ORDER BY tbl.y " . $year_order
  );

  if($raw_output) return $results;

  global $wp_locale;

  foreach ($results as $data){
    $months_data = explode('-',$data->months);
    $months = array();
    $data->count = 0; // year count

    foreach ($months_data as $month_data){
      $month_obj = new stdClass;

      $splitted = explode(':',$month_data);
      $raw_month = $splitted[0];
      $month_obj->number = $raw_month;
      $month_obj->name = $wp_locale->get_month($raw_month);
      $month_obj->posts = array();
      $post_ids = explode(',',$splitted[1]);
      $data->count += count($post_ids);

      foreach($post_ids as $post_id){
        $month_obj->posts[] = get_post($post_id);
        $months[$raw_month] = $month_obj;
      }// foreach
    }// foreach

    $data->months = $months;
  }// foreach

  return $results;
}// get_posts_by_date

Ejemplo de uso:

$posts_by_date = get_posts_by_date(array(
  'year_limit' => '2016'
  ,'operator' => '<='
  ,'current_year' => false
  ,'post_type' => 'product'
  ,'month_order' => 'ASC'
  ,'raw_output' => true
));

Si la opción raw_output es verdadera, la salida predeterminada será algo como esto:

array(2) {
  [0]=>
  object(stdClass)#6645 (2) {
    ["year"]=>
    string(4) "2017"
    ["months"]=>
    string(65) "8:386,401-7:406,373,380,377,408,399,362-6:1,391,404-5:367,397,394"
  }
  [1]=>
  object(stdClass)#6644 (2) {
    ["year"]=>
    string(4) "2016"
    ["months"]=>
    string(5) "6:429"
  }
}

La cadena de "meses" contiene valores formateados como:

month:[post ids]-month:[post ids]-ecc

Si la opción raw_output es falsa, obtendrás una lista de publicaciones como esta:

array (array of objects)
  object
    -> year (ex. '2017')
    -> count (total year's posts)
    -> months (array of objects)
        month
          -> number (of month)
          -> name (localized)
          -> posts (array of post objects)

Feliz codificación ... :)

    
respondido por el Stratboy 15.08.2017 - 10:59

Lea otras preguntas en las etiquetas