web-dev-qa-db-fra.com

Comment trier CPT par méta valeur personnalisée (date) et renvoyer les messages mois par mois

Pour référence future:
J'utilise l'excellent Meta Box Plugin pour accélérer la création de méta-boîtes pour mes types d'articles personnalisés.

Mon objectif:
Pour créer une section d’événements hautement personnalisable ressemblant beaucoup à un calendrier traditionnel tel que créé par get_calendar, mais pour un type de publication personnalisé spécifique.

Le problème:
- En utilisant uniquement Wordpresses construit dans paramètres de temps , je peux renvoyer mes messages dans un ordre ASC similaire à un calendrier traditionnel, mais je ne peux afficher que des messages jusqu'au jour actuel puisqu'il n'y a aucun moyen d'interroger et de renvoyer les publications programmées - il s'agit évidemment d'un problème, car je dois afficher TOUS les publications d'événement pour le mois en cours, et ainsi de suite ...
- De plus, je dois également pouvoir passer en mode page pour les mois "précédents" et "à venir" similaires à get_calendar.

Ma solution jusqu'ici:
- En raison des restrictions imposées par les paramètres temporels, j’ai choisi de renvoyer mes publications via le paramètre WP_Query de meta_key et de les affecter à la zone "date de début" de mes événements, puis de commander - meta_value_num...

Cela semble reproduire la même fonctionnalité pour la plupart, mais maintenant, je suis confronté à un problème sérieux de:

"Comment puis-je traiter cette méta-valeur de la même manière que wordpresse les paramètres de temps natifs afin que je puisse stocker ces données de manière appropriée pour chaque mois et avoir la possibilité de parcourir les mois de manière similaire à l'archive get_calendar?"

J'espère que mon explication est suffisamment définitive pour aider quiconque lit ceci à comprendre tout cela. Si non, s'il vous plaît faites le moi savoir et je serai heureux d'essayer de clarifier davantage quoi que ce soit ... et merci pour l'aide!


Ci-dessous, mon modèle actuel "Calendrier/Événements", ainsi qu'une capture d'écran de son apparence probable au début du processus.

<?php
/*
Template Name: Calendar
*/
?>

<?php get_header(); ?>

<!-- featured_images.php -->
<?php include ('featured_images.php'); ?>

    <div id="full_col">

        <h2 class="feed_title_full"><?php wp_title('', true); ?></h2>
        <div id="calendar_nav">
            <h4 id="current_month"><?php the_time( 'F Y' ); ?></h4>
        </div>

        <ul id="calendar">

            <?php $current_year = date('Y'); // Get current YEAR ?> 
            <?php $current_month = date('m'); // Get current MONTH ?>
            <?php $calandar_posts = new WP_Query(
                array(
                    'post_type' => 'calendar', 
                    'year' => $current_year,
                    'monthnum' => $current_month, // Show ALL posts for current Month 
                    'meta_key' => 'epr_startdate',
                    'orderby' => 'meta_value_num',
                    'order' => 'ASC', 
                    'posts_per_page' => -1, 
                    'paged' => get_query_var('paged') ? get_query_var('paged') : 1,
                )); 
            ?>
            <?php if($calandar_posts->have_posts()) : while($calandar_posts->have_posts()) : $calandar_posts->the_post(); ?>

                <li class="calendar_entry">
                    <a href="<?php the_permalink(); ?>" class="calendar_link" title="<?php the_title_attribute(); ?>"></a>
                    <div class="entry_date">
                        <?php echo get_post_meta($post->ID, 'epr_startdate', TRUE); ?>
                    </div>
                    <div class="shadow_overlay"></div>
                    <?php the_post_thumbnail('calendar-teaser', array('class' => 'calendar-teaser-img', 'alt' => 'View Event')); ?>
                </li>

            <?php endwhile; else: ?>
                <h2>No Events for the month of <?php the_time( 'F' ); ?></h2>
            <?php endif; ?>
            <?php wp_reset_query(); ?>

        </ul>

    </div>

<?php get_footer(); ?>

enter image description here

2
Mr.Brown

Ce n'est pas un code copier/coller complet, mais j'espère que c'est assez compréhensible pour que vous puissiez commencer.

La première étape consiste à enregistrer votre type de publication et à ajouter une règle de réécriture pour gérer les années/mois. Cela vous donnera des événements uniques à event/post-name/, votre archive de type de publication à calendar et gérera les demandes entrantes de calendar/yyyy/mm/. Assurez-vous de visiter votre page Paramètres> Permaliens après son ajout pour vider les règles de réécriture.

function wpa88173_calendar_post_type() {

    // just the important bits shown here
    $args = array(
        'rewrite' => array( 'slug' => 'event' )
        'has_archive' => 'calendar',
    );

    register_post_type( 'calendar', $args );

    add_rewrite_rule(
        '^calendar/([0-9]{4})/([0-9]{2})/?',
        'index.php?post_type=calendar&calendar_year=$matches[1]&calendar_month=$matches[2]',
        'top'
    );

}
add_action( 'init', 'wpa88173_calendar_post_type' );

La prochaine étape consiste à ajouter les vars de requête calendar_year et calendar_month afin que WordPress les ajoute au tableau de vars de requête lorsque les demandes entrantes sont analysées.

function wpa88173_calendar_query_vars( $query_vars ) {
    $query_vars[] = 'calendar_year';
    $query_vars[] = 'calendar_month';
    return $query_vars;
}
add_filter('query_vars', 'wpa88173_calendar_query_vars' );

L'étape suivante consiste à ajouter une action à pre_get_posts, qui vérifie s'il s'agit de l'archive de type publication de calendrier, récupère l'année/le mois ou la définit sur l'année/le mois en cours, puis modifie la requête avec les paramètres meta_query pour charger l'année/le mois demandé. . Voir WP_Query pour plus d’informations sur les méta-requêtes. Cela suppose un format de date de yyyymmdd.

function wpa88173_calendar_query( $query ) {
    // is it a post type archive?
    if( ! $query->is_post_type_archive( 'calendar' ) )
        return;

    // is it the main query and not an admin page?      
    if( $query->is_main_query()
        && ! is_admin() ) {

        // check if year/month was set via the URI, or set it to current year/month
        ( ! empty( $query->query_vars['calendar_year'] ) ) ? $query_year = $query->query_vars['calendar_year'] : $query_year = date('Y');
        ( ! empty( $query->query_vars['calendar_month'] ) ) ? $query_month = $query->query_vars['calendar_month'] : $query_month = date('m');

        // meta_query parameters for events between start and end dates
        $date_start = $query_year . $query_month . '01';
        $date_end = $query_year . $query_month . '31';
        $meta_query = array(
            array(
                'key' => 'event_date',
                'value' => array( $date_start, $date_end ),
                'compare' => 'BETWEEN',
                'type' => 'NUMERIC'
            )
        );

        // modify the query
        $query->set( 'meta_key', 'event_date' );
        $query->set( 'orderby', 'meta_value_num' );
        $query->set( 'order', 'ASC' );
        $query->set( 'meta_query', $meta_query );

    }

}
add_action( 'pre_get_posts', 'wpa88173_calendar_query' );

La dernière étape consiste à créer le calendrier dans votre modèle et à créer les liens suivants/précédents vers la page par mois. Vous pouvez obtenir l'année/le mois demandé dans le modèle via get_query_var .

EDIT- Voici un exemple de création de liens avec plain ol 'math

( '' == get_query_var( 'calendar_month' ) ) ? $this_month = date( 'n' ) : $this_month = ltrim( get_query_var( 'calendar_month' ), '0' );
( '' == get_query_var( 'calendar_year' ) ) ? $this_year = date( 'Y' ) : $this_year = get_query_var( 'calendar_year' );

if( 1 == $this_month ):
    $next_month = 2;
    $prev_month = 12;
    $next_year = $this_year;
    $prev_year = $this_year - 1;
elseif( 12 == $this_month ):
    $next_month = 1;
    $prev_month = 11;
    $next_year = $this_year + 1;
    $prev_year = $this_year;
else:
    $next_month = $this_month + 1;
    $prev_month = $this_month - 1;
    $next_year = $this_year;
    $prev_year = $this_year;
endif;

$next_month = str_pad( $next_month , 2, '0', STR_PAD_LEFT );
$prev_month = str_pad( $prev_month , 2, '0', STR_PAD_LEFT );

echo 'next month: /calendar/' . $next_year . '/' . $next_month . '/';
echo 'previous month: /calendar/' . $prev_year . '/' . $prev_month . '/';
5
Milo