Como definir um tipo de postagem personalizado para ter postagens futuras visíveis

9

Configurei um CPT para agir da mesma maneira que as postagens, mas costumava postar detalhes do evento.

O fato é que algumas das postagens estão no futuro e têm uma data futura definida. O problema é que usuários normais não podem ver essas postagens.

Assim:

  • Como altero o archive-events.php para listar postagens futuras também? Mostrando postagens futuras distantes, a primeira e a mais antiga, por último, mantendo a paginação.
  • Como faço para que, quando um usuário clicar em uma postagem futura, não receba uma página 404 não encontrada, pois a publicação ainda não foi publicada tecnicamente?
Scott
fonte
4
Seria possível usar campos personalizados para a data em vez de usar as funções padrão do wordpress, como você diz, essencialmente, as postagens com datas futuras não são realmente publicadas na exibição do WP.
Vince Pettit
Embora dizendo que iria parecer que é uma coisa nível de acesso do usuário para que você poderia acrescentar algo para o arquivo functions.php para conceder a todos os usuários a capacidade de visualizar posts futuros
Vince Pettit

Respostas:

5

Eu fui capaz de resolver isso sozinho. Todo o meu código para registrar o 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;
}
?>

Portanto, para permitir que as postagens sejam visíveis para todos os usuários, mesmo que sejam definidas no futuro, você deve fazer o seguinte:

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

Removemos a ação que trata da postagem posteriormente e aplicamos nossa própria ação para forçá-la a ser publicada, apesar de ter uma data futura com:

wp_publish_post($post);

Agora tudo o que precisamos fazer é mostrar as postagens futuras na página do arquivo 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
fonte
2
Adicione um domínio de texto às suas __()chamadas ou não use a função.
Fuxia
3
-1 para abordagem. :) Conforme a discussão no bate-papo, seria mais confiável rastrear a data do evento separadamente no campo personalizado, em vez de dobrar a mecânica interna para usar a data da postagem.
Rarst
11
+1 para abordagem alternativa :) Eu concordo totalmente com o @Rarst, mas também acho essa abordagem interessante e ficarei feliz em tê-la bem documentada aqui no WPSE.
Michal Mau
2

Brady, não posso agradecer o suficiente por me levar a esta solução. Meu cliente já havia definido todas as datas do evento sem um campo personalizado, e eu não ia voltar e mudar tudo. Seu código inicialmente gerou um erro ao tentar postar, mas funcionou com as seguintes pequenas modificações (feitas para corresponder ao formato usado no 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 );
}

Passei um tempo tentando descobrir isso. Espero que isso ajude mais alguém!

Zade
fonte
0

Sem alterar o status da postagem, você pode exibir futuras postagens únicas e arquivar com pre_get_posts também:

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
fonte