Comment définir un type de publication personnalisé pour avoir des publications futures visibles


9

J'ai configuré un CPT pour agir de la même manière que les publications, mais utilisé pour publier les détails de l'événement.

Le fait est que certains des postes sont dans le futur et que ceux-ci ont une date future fixée sur eux. Le problème est que les utilisateurs normaux ne peuvent pas voir ces messages.

Donc:

  • Comment puis-je modifier archive-events.php pour lister les futurs messages aussi? Afficher les futurs messages lointains en premier et les plus anciens en dernier tout en conservant la pagination.
  • Comment puis-je faire en sorte que lorsqu'un utilisateur clique sur un futur message, il n'obtienne pas de page 404 introuvable car le message n'est pas encore techniquement publié?

4
Serait-il possible d'utiliser des champs personnalisés pour la date plutôt que d'utiliser les fonctions wordpress par défaut, comme vous dites que les messages avec des dates futures ne sont pas réellement publiés dans la vue de WP.
Vince Pettit

Bien que disant qu'il semblerait que ce soit une chose de niveau d'accès utilisateur, vous pouvez éventuellement ajouter quelque chose au fichier functions.php pour permettre à tous les utilisateurs de voir les futurs messages
Vince Pettit

Réponses:


5

J'ai pu résoudre cela moi-même. Mon code complet pour l'enregistrement du CPT:

<?php
add_action( 'init', 'events_post_type_register' );
function events_post_type_register() {

    $post_type = "events";

    $labels = array(
        'name' => _x('Events', 'post type general name', 'project_X'),
        'singular_name' => _x('Event', 'post type singular name', 'project_X'),
        'add_new' => _x('Add New', 'event', 'project_X'),
        'add_new_item' => __('Add New Event', 'project_X'),
        'edit_item' => __('Edit Event', 'project_X'),
        'new_item' => __('New Event', 'project_X'),
        'all_items' => __('All Events', 'project_X'),
        'view_item' => __('View Event', 'project_X'),
        'search_items' => __('Search Events', 'project_X'),
        'not_found' =>  __('No events found', 'project_X'),
        'not_found_in_trash' => __('No events found in trash', 'project_X'),
        'parent_item_colon' => '',
        'menu_name' => 'Events'
    );

    $args = array(
        'labels' => $labels,
        'public' => true,
        'hierarchical' => false,
        'has_archive' => true,
        'rewrite' => array(
            'with_front' => false,
            'slug' => "news/{$post_type}"
        ),
        'supports' => array( 'title', 'editor', 'thumbnail' )
    );
    register_post_type($post_type, $args);

    remove_action("future_{$post_type}", '_future_post_hook');
    add_action("future_{$post_type}", 'sc_ps_publish_future_events_now', 2, 10);
}

function sc_ps_publish_future_events_now($depreciated, $post) {
    wp_publish_post($post);
}

add_filter('posts_where', 'sc_ps_show_future_events_where', 2, 10);
function sc_ps_show_future_events_where($where, $that) {
    global $wpdb;
    if("events" == $that->query_vars['post_type'] && is_archive())
        $where = str_replace( "{$wpdb->posts}.post_status = 'publish'", "{$wpdb->posts}.post_status = 'publish' OR $wpdb->posts.post_status = 'future'", $where);
    return $where;
}
?>

Ainsi, pour permettre aux publications d'être visibles pour tous les utilisateurs, même si elles sont définies à l'avenir, vous devez procéder comme suit:

remove_action("future_{$post_type}", '_future_post_hook');
add_action("future_{$post_type}", 'sc_ps_publish_future_events_now', 2, 10);

Nous supprimons l'action qui concerne la publication ultérieure et appliquons notre propre action pour la forcer à être publiée malgré sa date future avec:

wp_publish_post($post);

Il ne nous reste plus qu'à afficher les futurs articles sur la page d'archive en filtrant posts_where:

function sc_ps_show_future_events_where($where, $that) {
    global $wpdb;
    if("events" == $that->query_vars['post_type'] && is_archive())
        $where = str_replace( "{$wpdb->posts}.post_status = 'publish'", "{$wpdb->posts}.post_status = 'publish' OR $wpdb->posts.post_status = 'future'", $where);
    return $where;
}

2
Ajoutez un domaine de texte à vos __()appels ou n'utilisez pas de fonction.
fuxia

3
-1 pour l'approche. :) Selon la discussion dans le chat, il serait plus fiable de suivre la date de l'événement séparément dans un champ personnalisé au-dessus de la mécanique interne de flexion pour utiliser la date du message.
Rarst

1
+1 pour une approche alternative :) Je suis totalement d'accord avec @Rarst mais je trouve également cette approche intéressante et je serai heureux de l'avoir bien documentée ici sur WPSE.
Michal Mau

2

Brady, je ne vous remercierai jamais assez de m'avoir conduit vers cette solution. Mon client avait déjà défini toutes les dates de l'événement sans champ personnalisé, et je n'allais pas revenir en arrière et tout changer. Votre code a initialement généré une erreur lors de la publication, mais il a fonctionné avec les légères modifications suivantes (faites pour correspondre au format utilisé dans wp-includes / post.php):

remove_action( 'future_' . $post_type, '_future_post_hook', 5, 2 );
add_action( 'future_' . $post_type, 'my_future_post_hook', 5, 2);

et

function my_future_post_hook( $deprecated = '', $post ) {
    wp_publish_post( $post->ID );
}

J'ai passé un certain temps à essayer de comprendre cela. J'espère que cela aide quelqu'un d'autre!


0

Sans changer le statut de la publication, vous pouvez également afficher les publications futures uniques et les archiver avec pre_get_posts:

add_action( 'pre_get_posts', 'joesz_include_future_posts' );
function joesz_include_future_posts( $query ) {

    if ( $query->is_main_query() && 
           ( $query->query_vars['post_type'] == 'your-post-type' || // for single
         is_post_type_archive( 'your-post-type' ) ) ) {         // for archive

        $query->set( 'post_status', array( 'future', 'publish' ) );

    }

}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.