web-dev-qa-db-de.com

So legen Sie einen benutzerdefinierten Beitragstyp fest, damit zukünftige Beiträge angezeigt werden

Ich habe ein CPT so eingerichtet, dass es die gleichen Aktionen ausführt wie Beiträge, aber zum Posten von Ereignisdetails verwendet wird.

Die Sache ist, dass einige der Posts in der Zukunft sind und ein zukünftiges Datum auf ihnen festgelegt ist. Problem ist, dass normale Benutzer diese Beiträge nicht sehen können.

So:

  • Wie ändere ich die Datei archive-events.php, um auch zukünftige Beiträge aufzulisten? Erste und älteste Posts der fernen Zukunft werden zuletzt angezeigt, während die Paginierung beibehalten wird.
  • Wie kann ich dafür sorgen, dass ein Benutzer, der auf einen zukünftigen Beitrag klickt, keine 404-Seite findet, da der Beitrag noch nicht technisch veröffentlicht ist?
8
Brady

Ich konnte das selbst lösen. Mein gesamter Code für die Registrierung des 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;
}
?>

Damit Posts auch dann für alle Benutzer sichtbar sind, wenn sie in Zukunft festgelegt werden, müssen Sie folgende Schritte ausführen:

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

Wir entfernen die Aktion, die sich mit dem späteren Posten befasst, und wenden unsere eigene Aktion an, um die Veröffentlichung zu erzwingen, obwohl sie ein zukünftiges Datum hat mit:

wp_publish_post($post);

Dann müssen wir nur noch zukünftige Beiträge auf der Archivseite anzeigen, indem wir posts_where filtern:

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, ich kann Ihnen nicht genug danken, dass Sie mich zu dieser Lösung geführt haben. Mein Kunde hatte bereits alle Veranstaltungstermine ohne ein benutzerdefiniertes Feld festgelegt, und ich wollte nicht zurückgehen und alles ändern. Ihr Code hat beim Posten zunächst einen Fehler ausgegeben, der jedoch mit den folgenden geringfügigen Änderungen (die an das in wp-includes/post.php verwendete Format angepasst wurden) funktioniert:

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

und

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

Ich habe eine Weile damit verbracht, das herauszufinden. Hoffe es hilft jemand anderem!

2
Zade

Ohne Änderung des Beitragsstatus können Sie zukünftige Beiträge einzeln anzeigen und auch mit pre_get_posts archivieren:

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