Cómo configurar un tipo de publicación personalizada para tener publicaciones futuras visibles

9

He configurado un CPT para que actúe de la misma manera que las publicaciones, pero solía publicar detalles del evento.

La cuestión es que algunas de las publicaciones están en el futuro y tienen una fecha futura fijada. El problema es que los usuarios normales no pueden ver estas publicaciones.

Entonces:

  • ¿Cómo modifico archive-events.php para enumerar publicaciones futuras también? Mostrar las publicaciones futuras lejanas y las publicaciones más antiguas duran al mismo tiempo que se mantiene la paginación.
  • ¿Cómo hago para que cuando un usuario haga clic en una publicación futura no obtenga una página 404 que no se encuentra ya que la publicación aún no está técnicamente publicada?
Scott
fuente
44
¿Sería posible usar campos personalizados para la fecha en lugar de usar las funciones predeterminadas de WordPress como dice, esencialmente, las publicaciones con fechas futuras no se publican realmente en la vista de WP?
Vince Pettit
A pesar de decir que parecería que es una cuestión de nivel de acceso de usuario, podría agregar algo al archivo functions.php para otorgar a todos los usuarios la posibilidad de ver publicaciones futuras
Vince Pettit

Respuestas:

5

He podido resolver esto yo mismo. Mi código completo para registrar el 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;
}
?>

Por lo tanto, para permitir que las publicaciones sean visibles para todos los usuarios, incluso si se configuran en el futuro, debe hacer lo siguiente:

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

Eliminamos la acción que se ocupa de publicar más tarde y aplicamos nuestra propia acción para forzar su publicación a pesar de tener una fecha futura con:

wp_publish_post($post);

Entonces, todo lo que tenemos que hacer ahora es mostrar publicaciones futuras en la página de archivo 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;
}
Scott
fuente
2
Agregue un dominio de texto a sus __()llamadas o no use la función.
fuxia
3
-1 para aproximación. :) Según la discusión en el chat, sería más confiable rastrear la fecha del evento por separado en el campo personalizado sobre la flexión de la mecánica interna para hacer uso de la fecha de publicación.
Rarst
1
+1 para un enfoque alternativo :) Estoy totalmente de acuerdo con @Rarst, pero también encuentro este enfoque interesante y estaré feliz de tenerlo bien documentado aquí en WPSE.
Michal Mau
2

Brady, no puedo agradecerte lo suficiente por llevarme a esta solución. Mi cliente ya había establecido todas las fechas del evento sin un campo personalizado, y no estaba dispuesto a regresar y cambiar todo. Inicialmente, su código arrojó un error al intentar publicar, pero funcionó con las siguientes ligeras modificaciones (hechas para que coincida con el formato utilizado en 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);

y

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

Pasé un tiempo tratando de resolver esto. Espero que ayude a alguien más!

Zade
fuente
0

Sin cambiar el estado de la publicación, puede mostrar publicaciones futuras individuales y archivar con pre_get_posts también:

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
fuente