So legen Sie einen benutzerdefinierten Beitragstyp fest, um zukünftige Beiträge sichtbar zu machen

9

Ich habe ein CPT so eingerichtet, dass es sich wie Posts verhält, aber zum Posten von Ereignisdetails verwendet.

Es ist so, dass einige der Posts in der Zukunft liegen und auf denen ein zukünftiges Datum festgelegt ist. Problem ist, dass normale Benutzer diese Beiträge nicht sehen können.

Damit:

  • Wie ändere ich archive-events.php, um auch zukünftige Beiträge aufzulisten? Anzeigen der ersten und ältesten Beiträge zukünftiger zukünftiger Beiträge unter Beibehaltung der Paginierung.
  • Wie mache ich es so, dass ein Benutzer, wenn er auf einen zukünftigen Beitrag klickt, keine 404-Seite erhält, die nicht gefunden wurde, da der Beitrag noch nicht technisch veröffentlicht ist?
Scott
quelle
4
Wäre es möglich, benutzerdefinierte Felder für das Datum zu verwenden, anstatt die Standard-WordPress-Funktionen zu verwenden, wie Sie sagen, werden Beiträge mit zukünftigen Daten im Wesentlichen nicht in der Ansicht von WP veröffentlicht.
Vince Pettit
Obwohl es so aussieht, als wäre es eine Sache auf Benutzerzugriffsebene, könnten Sie möglicherweise etwas zur Datei functions.php hinzufügen, um allen Benutzern die Möglichkeit zu geben, zukünftige Beiträge anzuzeigen
Vince Pettit

Antworten:

5

Ich konnte das selbst lösen. Mein gesamter Code zur 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 Beiträge für alle Benutzer sichtbar sind, auch wenn sie in Zukunft festgelegt werden, müssen Sie Folgendes tun:

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 der späteren Veröffentlichung 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 filtern 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;
}
Scott
quelle
2
Fügen Sie Ihren __()Anrufen eine Textdomäne hinzu oder verwenden Sie keine Funktion.
Fuxia
3
-1 für Annäherung. :) Gemäß der Diskussion im Chat wäre es zuverlässiger, das Ereignisdatum separat im benutzerdefinierten Feld zu verfolgen, indem interne Mechaniken gebogen werden, um das Datum des Beitrags zu verwenden.
Rarst
1
+1 für alternativen Ansatz :) Ich stimme @Rarst voll und ganz zu, aber ich finde diesen Ansatz auch interessant und bin froh, dass er hier auf WPSE gut dokumentiert ist.
Michal Mau
2

Brady, ich kann dir nicht genug danken, dass du mich zu dieser Lösung geführt hast. Mein Kunde hatte bereits alle Veranstaltungstermine ohne ein benutzerdefiniertes Feld festgelegt, und ich wollte nicht zurückgehen und alles ändern. Ihr Code hat beim Versuch, etwas zu posten, anfangs einen Fehler ausgegeben, der jedoch mit den folgenden geringfügigen Änderungen funktioniert hat (entsprechend dem in wp-include / post.php verwendeten Format):

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 versucht, das herauszufinden. Hoffe es hilft jemand anderem!

Zade
quelle
0

Ohne den Beitragsstatus zu ändern, 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' ) );

    }

}
Joe
quelle