Come si usa un CPT come pagina iniziale predefinita?


20

Ho un cliente il cui sito utilizzerà pesantemente tipi di posta personalizzati per configurare il proprio sito. Ma sono tra un rock e un posto difficile per la loro home page richiesta.

In realtà, la home page sarà una pila di "pagine" specifiche all'interno di WordPress. Fondamentalmente, ci saranno pagine per: Introduzione , Blog , Chi siamo , Portfolio e Contattaci . Saranno tutti impilati uno sopra l'altro in modo da poter scorrere da una pagina all'altra.

Il mio primo istinto è stato quello di utilizzare solo una pagina (chiamata Home ) e incorporare un shortcode che accetta le slug di pagina e genera l'ordine corretto (es.[pageOrder]intro, blog, about-us, portfolio, contact-us[/pageOrder] ). La pagina userebbe un modello di pagina personalizzato per disporre le cose, controllare il ciclo e aggiungere la navigazione sul lato sinistro della pagina. Ma tutto sembra klunky.

La mia soluzione ideale sarebbe quella di creare un tipo di post personalizzato (chiamato Stack ) che consenta all'utente finale di posizionare le pagine con trascinamento e di far sì che il CPT si occupi del layout e della navigazione e così via.

Il problema con la mia soluzione ideale sono le impostazioni. WordPress ti consente di selezionare una pagina per la home page predefinita del sito. Ma è legato a un tipo di pagina di post , e non sono sicuro di dove agganciarlo per modificarlo in modo che gli utenti possano anche selezionare uno Stack come home page predefinita.

Quindi, dove devo collegarmi per aggiungere un CPT all'elenco a discesa delle pagine disponibili per la home page predefinita?

Risposte:


11

Grazie a @toscho per la risposta utile, ma mi è sembrato un po 'hacker, quindi ho cercato un po' in giro e ho capito che avrei potuto aggiungere un 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 );

Aggiornare

Dopo aver aggiunto il codice sopra, sono stato davvero in grado di utilizzare un tipo di post personalizzato come pagina iniziale, ma WordPress reindirizzava i permalink perché non era un tipo di post "pagina". Quindi http://localhost/testreindirizzerei a http://localhost/test/stacks/home-stack, che non era quello che volevo.

L'aggiunta di questa azione, tuttavia, l'ha risolto e richiede il mio tipo di post personalizzato insieme alle pagine per la 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' );

Ho giocato anche con un filtro del genere, ma deve essere limitato alla query della prima pagina. E poi sono stato battuto da alcuni strani comportamenti / bug: ho avuto solo 404 secondi. Comunque +1. :)
fuxia

Buona pesca. Il condizionale aggiuntivo all'interno della funzione (assicurarsi che post_typenon sia già impostato e che page_idnon sia 0) impedisce tutti i 404. Ora posso eseguire query per tutti i miei post personalizzati, tutti i miei post e tutte le mie pagine senza alcuna interferenza.
EAMann,

@EAmann Grazie per il codice! Funziona come dovrebbe, anche se cambia il titolo della prima pagina in Titolo del post | Nome della home page, può essere modificato in qualche modo per essere solo il nome della home page?
INT

Questo non funziona affatto ... avvertimenti / errori del server: Argomento mancante 2 per wpa18013_add_pages_to_dropdown () e variabile non
definita

8

Può darsi? Versione raffinata della mia soluzione precedente .

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 );
}

Questo serve solo a selezionare il tipo di post personalizzato, ma ciò non lo fa visualizzare quel tipo di post personalizzato come prima pagina? Oppure mi sfugge qualcosa?
Hameedullah Khan,

@Hameedullah - Dopo averlo selezionato, WordPress aggiorna un'opzione che contrassegna quale pagina dovrebbe essere utilizzata per la prima pagina. Quindi, quando un utente visita la prima pagina, WordPress legge la stessa opzione dal database.
EAMann,

@Hameedullah Khan Hai ragione. Questo ha funzionato prima della 3.1, ora sono reindirizzato al permalink del post - e ottengo un 404. Strano. Vorrei avere tempo per questo. :(
fuxia

5

Perché non solo creare un front-page.phpfile modello, che utilizza una normale query / Loop o (se un'opzione Tema personalizzato è impostata per visualizzare il CPT sulla prima pagina), genera una query / Loop personalizzata, basata sul CPT?

Il problema è che dovresti creare un'opzione Tema separata per controllare l'output della Pagina principale, mentre allo stesso tempo istruisci gli utenti a impostare la Pagina iniziale su pagina statica.

Per semplificare le cose, è possibile collegare l'opzione Tema alla lettura delle impostazioni, utilizzando il gruppo di opzioni "Lettura" nella chiamata register_settingtramite l'API Impostazioni, in modo che venga visualizzato con le opzioni della Pagina iniziale esistenti.


Mi piacciono le soluzioni semplici e Chip penso che il tuo sia il migliore. Wordpress consente modelli personalizzati per la prima pagina codex.wordpress.org/Template_Hierarchy#Home_Page_display e quindi si può fare tutto ciò che gli piace.
anmari,

Questa è la soluzione più mantenibile e semplice. Il front-page.phpviene selezionato automaticamente, perché è parte della gerarchia template wordpress. Non c'è bisogno di ricordare perché questo sta accadendo (o è necessario contrassegnarlo per la persona successiva).
Odys,

2

Penso che qualcosa potrebbe essere cambiato da quando EAMann ha scritto il suo aggiornamento nel 2011 e la funzione wpa18013_add_pages_to_dropdown () che fornisce non funziona più. Come menzionato in un commento di Dameer, questa funzione attualmente (dicembre 2013) genera un errore "Argomento mancante 2 per wpa18013_add_pages_to_dropdown ()"

La soluzione, comunque, per me era riscrivere la funzione senza quel secondo parametro, o controllare il suo contenuto. L'intero blocco di codice diventa quindi:

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' );

Nell'esempio sopra, il tipo di post personalizzato che sto aggiungendo è "unbox_tabs" anziché "stack".


1

Sto usando questa tecnica per includere un modello da un plugin. Quindi, la soluzione di @ ChipBennett non si applica.

Per aggiungere i CPT ( ) dal plug-in nell'elenco di Pagine statiche, ho modificato la soluzione di @ EAMann come segue: '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' );
}

Core reference v3.4.2:
leggera differenza dei numeri di riga in 3.5 RC3, ma il codice rimane lo stesso

/**
 * 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 );
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.