Come impostare un tipo di post personalizzato per avere post futuri visualizzabili


9

Ho impostato un CPT per agire allo stesso modo dei post ma utilizzato per pubblicare i dettagli dell'evento.

La cosa è che alcuni dei post sono in futuro e tali hanno una data futura impostata su di essi. Il problema è che gli utenti normali non possono vedere questi post.

Così:

  • Come posso modificare archive-events.php per elencare anche i post futuri? Mostra i post più lontani per primi e quelli più vecchi per ultimi mantenendo l'impaginazione.
  • Come faccio a fare in modo che quando un utente fa clic su un post futuro non ottenga una pagina 404 non trovata poiché il post non è ancora tecnicamente pubblicato?

4
Sarebbe possibile usare campi personalizzati per la data piuttosto che usare le funzioni wordpress predefinite come dici tu essenzialmente i post con date future non sono effettivamente pubblicati nella vista di WP.
Vince Pettit,

Anche se dire che sembrerebbe una cosa a livello di accesso utente, quindi potresti eventualmente aggiungere qualcosa al file Functions.php per garantire a tutti gli utenti la possibilità di visualizzare post futuri
Vince Pettit

Risposte:


5

Sono stato in grado di risolverlo da solo. Il mio intero codice per la registrazione del 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;
}
?>

Quindi, per consentire ai post di essere visibili a tutti gli utenti anche se sono impostati in futuro, è necessario effettuare le seguenti operazioni:

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

Rimuoviamo l'azione che si occupa della pubblicazione in un secondo momento e applichiamo la nostra azione per costringerla a essere pubblicata nonostante abbia una data futura con:

wp_publish_post($post);

Quindi tutto ciò che dobbiamo fare ora è mostrare i post futuri nella pagina di archivio filtrando 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
Aggiungi un dominio di testo alle tue __()chiamate o non utilizzare la funzione.
fuxia

3
-1 per l'approccio. :) Come da discussione in chat, sarebbe più affidabile tenere traccia della data dell'evento separatamente nel campo personalizzato oltre a piegare la meccanica interna per utilizzare la data del post.
Rarst

1
+1 per un approccio alternativo :) Sono totalmente d'accordo con @Rarst ma trovo anche questo approccio interessante e sarò felice di averlo ben documentato qui su WPSE.
Michal Mau,

2

Brady, non posso ringraziarti abbastanza per avermi portato a questa soluzione. Il mio cliente aveva già impostato tutte le date dell'evento senza un campo personalizzato e non avevo intenzione di tornare indietro e cambiare tutto. Il tuo codice inizialmente ha generato un errore durante il tentativo di pubblicare, ma ha funzionato con le seguenti lievi modifiche (fatte per abbinare il formato usato in 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);

e

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

Ho trascorso un po 'a cercare di capirlo. Spero che aiuti qualcun altro!


0

Senza modificare lo stato dei post, puoi visualizzare singoli post futuri e archiviarli anche con 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' ) );

    }

}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.