Como você usa um CPT como a página inicial padrão?

20

Eu tenho um cliente cujo site fará uso pesado de tipos de postagem personalizados para configurar seu site. Mas estou entre uma pedra e um lugar difícil para a página inicial solicitada.

Na realidade, a página inicial será uma pilha de "páginas" específicas no WordPress. Basicamente, haverá páginas para: Introdução , Blog , Sobre nós , Portfólio e Entre em contato . Todos eles serão empilhados um sobre o outro para que você possa rolar de uma página para outra.

Meu primeiro instinto foi usar apenas uma página (chamada Home ) e incorporar um código de acesso que aceite slugs de página e produza a ordem correta (ie [pageOrder]intro, blog, about-us, portfolio, contact-us[/pageOrder]). A página usaria um modelo de página personalizado para organizar, controlar o loop e adicionar navegação ao lado esquerdo da página. Mas tudo isso parece desajeitado.

Minha solução ideal seria criar um tipo de postagem personalizado (chamado Stack ) que permita ao usuário final posicionar as páginas com arrastar e soltar e fazer com que o CPT cuide do layout, da navegação e assim por diante.

O problema com a minha solução ideal são as configurações. O WordPress permite que você selecione uma página para a página inicial padrão do site. Mas ele está vinculado a um tipo de página de postagem , e não tenho certeza de onde conectar para modificar isso, para que os usuários também possam selecionar uma Pilha como a página inicial padrão.

Então, onde eu conecto para adicionar um CPT ao menu suspenso de páginas disponíveis para a página inicial padrão?

EAMann
fonte

Respostas:

11

Agradeço a @toscho pela resposta útil, mas me pareceu um pouco tola, por isso dei uma olhada e descobri que poderia adicionar um filtro:

function wpa18013_add_pages_to_dropdown( $pages, $r ){
    if('page_on_front' == $r['name']){
        $args = array(
            'post_type' => 'stack'
        );
        $stacks = get_posts($args);
        $pages = array_merge($pages, $stacks);
    }

    return $pages;
}
add_filter( 'get_pages', 'wpa18013_add_pages_to_dropdown', 10, 2 );

Atualizar

Depois de adicionar o código acima, eu consegui usar um tipo de postagem personalizado como página inicial, mas o WordPress redirecionaria os links permanentes porque não era um tipo de postagem de "página". Então http://localhost/testseria redirecionar para http://localhost/test/stacks/home-stack, que não era o que eu queria.

A adição dessa ação, no entanto, corrigiu isso e consulta meu tipo de postagem personalizado junto com as páginas da home page:

function enable_front_page_stacks( $query ){
    if('' == $query->query_vars['post_type'] && 0 != $query->query_vars['page_id'])
        $query->query_vars['post_type'] = array( 'page', 'stack' );
}
add_action( 'pre_get_posts', 'enable_front_page_stacks' );
EAMann
fonte
Também brinquei com esse filtro, mas ele deve ser restrito à consulta da primeira página. E então fui espancado por alguns comportamentos / bugs estranhos: consegui apenas 404s. Enfim +1. :)
fuxia
Boa pegada. O condicional extra dentro da função (verifique se post_typejá não está definido e page_idse não é 0) impede todos os 404s. Agora, posso executar consultas para todas as minhas postagens personalizadas, todas as minhas postagens e todas as minhas páginas sem nenhuma interferência.
EAMann
@EAmann Obrigado pelo código! Funciona como deveria, embora mude o título da primeira página para Título da postagem | Nome da página inicial, isso pode ser alterado para ser apenas o nome da página inicial?
INT
Isso não funciona em todos ... avisos servidor / erros: falta argumento 2 para wpa18013_add_pages_to_dropdown () e Undefined variable: r
Dameer
8

Talvez sim? Versão refinada da minha solução anterior .

add_filter( 'wp_dropdown_pages', 'add_cpt_to_front_page_dropdown', 10, 1 );


/**
 * Adds CPTs to the list of available pages for a static front page.
 *
 * @param  string $select Existing select list.
 * @return string
 */
function add_cpt_to_front_page_dropdown( $select )
{
    if ( FALSE === strpos( $select, '<select name="page_on_front"' ) )
    {
        return $select;
    }

    $cpt_posts = get_posts(
        array(
            'post_type'      => 'YOUR_POST_TYPE'
        ,   'nopaging'       => TRUE
        ,   'numberposts'    => -1
        ,   'order'          => 'ASC'
        ,   'orderby'        => 'title'
        ,   'posts_per_page' => -1
        )
    );

    if ( ! $cpt_posts ) // no posts found.
    {
        return $select;
    }

    $current = get_option( 'page_on_front', 0 );

    $options = walk_page_dropdown_tree(
        $cpt_posts
    ,   0
    ,    array(
            'depth'                 => 0
         ,  'child_of'              => 0
         ,  'selected'              => $current
         ,  'echo'                  => 0
         ,  'name'                  => 'page_on_front'
         ,  'id'                    => ''
         ,  'show_option_none'      => ''
         ,  'show_option_no_change' => ''
         ,  'option_none_value'     => ''
        )
    );

    return str_replace( '</select>', $options . '</select>', $select );
}
fuxia
fonte
Isso é apenas para selecionar o tipo de postagem personalizado, mas isso não faz com que ele seja exibido como primeira página? Ou eu estou esquecendo de alguma coisa?
Hameedullah Khan
@Hameedullah - Depois de selecioná-lo, o WordPress atualiza uma opção que marca qual página deve ser usada para a primeira página. Então, quando um usuário visita a primeira página, o WordPress lê a mesma opção no banco de dados.
EAMann
@Hameedullah Khan Você está certo. Isso funcionou antes da versão 3.1, agora sou redirecionado para o link permanente da postagem - e recebo uma 404. Estranha. Eu gostaria de ter tempo para isso. :(
fuxia
5

Por que não criar apenas um front-page.phparquivo de modelo, que usa uma consulta / loop normal ou (se uma opção de tema personalizada estiver configurada para exibir o CPT na página inicial), gera uma consulta / loop personalizado, com base no CPT?

O problema é que você precisaria criar uma opção de tema separada para controlar a saída da página inicial, enquanto instrui os usuários a definir a página inicial como página estática.

Para facilitar as coisas, você pode conectar sua opção Tema à leitura de configurações, usando o grupo de opções "Leitura" em sua chamada para register_settinga API de configurações, para que ela seja exibida com as opções de página inicial existentes.

Chip Bennett
fonte
Eu gosto de soluções simples e o Chip é o melhor para você. O Wordpress permite modelos personalizados para a página inicial codex.wordpress.org/Template_Hierarchy#Home_Page_display e, em seguida, é possível fazer o que quiser dentro dele.
Anmari
Esta é a solução mais fácil de manter e direta. O front-page.phpé selecionado automaticamente porque faz parte da hierarquia do modelo do wordpress. Não é preciso lembrar por que isso está acontecendo (ou precisa marcar para a próxima pessoa).
Odys
2

Acho que algo pode ter mudado desde que o EAMann escreveu sua atualização em 2011, e a função wpa18013_add_pages_to_dropdown () que ele fornece não funciona mais. Conforme mencionado em um comentário de Dameer, essa função atualmente (dezembro de 2013) gera um erro "Argumento ausente 2 para wpa18013_add_pages_to_dropdown ()"

A solução, para mim, era reescrever a função sem esse segundo parâmetro ou verificar o conteúdo. O bloco completo de código se torna:

function add_unbox_tabs_to_dropdown( $pages ){
    $args = array(
        'post_type' => 'unbox_tabs'
    );
    $items = get_posts($args);
    $pages = array_merge($pages, $items);

    return $pages;
}
add_filter( 'get_pages', 'add_unbox_tabs_to_dropdown' );

function enable_front_page_unbox_tabs( $query ){
    if('' == $query->query_vars['post_type'] && 0 != $query->query_vars['page_id'])
        $query->query_vars['post_type'] = array( 'page', 'unbox_tabs' );
}
add_action( 'pre_get_posts', 'enable_front_page_unbox_tabs' );

Observe que no exemplo acima, o tipo de postagem personalizado que estou adicionando é "unbox_tabs" em vez de "empilhar".

Matthew Bernhardt
fonte
1

Estou usando esta técnica para incluir um modelo de um plugin. Portanto, a solução da @ ChipBennett não se aplica.

Para adicionar os CPTs ( ) do plug-in na lista de páginas estáticas, modifiquei a solução do @ EAMann da seguinte maneira: 'hierarchical' => 'false'

add_action( 'admin_head-options-reading.php', 'wpse_18013_modify_front_pages_dropdown' );
add_action( 'pre_get_posts', 'wpse_18013_enable_front_page_stacks' );

function wpse_18013_modify_front_pages_dropdown()
{
    // Filtering /wp-includes/post-templates.php#L780
    add_filter( 'get_pages', 'wpse_18013_add_cpt_to_pages_on_front' );
}

function wpse_18013_add_cpt_to_pages_on_front( $r )
{
    $args = array(
        'post_type' => 'stack'
    );
    $stacks = get_posts( $args );
    $r = array_merge( $r, $stacks );

    return $r;
}

function wpse_18013_enable_front_page_stacks( $query )
{
    if( '' == $query->query_vars['post_type'] && 0 != $query->query_vars['page_id'] )
        $query->query_vars['post_type'] = array( 'page', 'stack' );
}

Referência principal v3.4.2:
pequena diferença de números de linha no 3.5 RC3, mas o código permanece o mesmo

/**
 * wp-admin/options-reading.php#L96
 * Happens inside a <li><label>-</label></li>
 */
    wp_dropdown_pages( array( 
                'name' => 'page_on_front'
            ,   'echo' => 0
            ,   'show_option_none' => __( '&mdash; Select &mdash;' )
            ,   'option_none_value' => '0'
            ,   'selected' => get_option( 'page_on_front' ) 
        ) 
    )

/**
  * wp-includes/post-template.php#L768
  */
function wp_dropdown_pages($args = '') {
    $defaults = array( /* defaults array */ );    
    $r = wp_parse_args( $args, $defaults );
    extract( $r, EXTR_SKIP );  
    $pages = get_pages( $r );
brasofilo
fonte