web-dev-qa-db-fra.com

Comment définir un type d'article personnalisé?

J'ai configuré un CPT pour qu'il agisse de la même manière que les messages mais utilisait pour poster les détails de l'événement.

Le fait est que certains des postes sont à venir et qu'une date future est fixée à ceux-ci. Le problème est que les utilisateurs normaux ne peuvent pas voir ces publications.

Alors:

  • Comment puis-je modifier archive-events.php pour répertorier également les publications futures? Afficher les premiers messages les plus anciens et les plus anciens en dernier tout en maintenant la pagination.
  • Comment puis-je faire en sorte que lorsqu'un utilisateur clique sur une publication future, il ne reçoive pas une page 404 non trouvée, car la publication n'est pas encore techniquement publiée?
8
Brady

J'ai pu résoudre ce problème 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;
}
?>

Pour permettre aux publications d'être visibles par tous les utilisateurs, même si elles sont définies ultérieurement, procédez 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 l'affichage plus tard et appliquons notre propre action pour le forcer à être publié malgré sa date future avec:

wp_publish_post($post);

Il ne reste plus maintenant qu’à afficher les publications futures 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;
}
4
Brady

Brady, je ne saurais trop vous remercier de m'avoir conduit à cette solution. Mon client avait déjà défini toutes les dates d'événements sans champ personnalisé et je n'étais pas sur le point de revenir en arrière et de tout changer. Votre code a initialement généré une erreur en essayant de poster, 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 ça aide quelqu'un d'autre!

2
Zade

Sans modifier le statut de la publication, vous pouvez également afficher les publications futures simples et 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' ) );

    }

}
0
Joe