Wie wird ein CPT als Standardhomepage verwendet?


20

Ich habe einen Kunden, dessen Site stark von benutzerdefinierten Beitragstypen Gebrauch macht, um deren Site zu konfigurieren. Aber ich bin zwischen einem Stein und einem harten Ort für ihre angeforderte Homepage.

In Wirklichkeit wird die Homepage ein Stapel spezifischer "Seiten" in WordPress sein. Grundsätzlich gibt es Seiten für: Intro , Blog , Über uns , Portfolio und Kontakt . Sie werden alle übereinander gestapelt, sodass Sie von einer Seite zur nächsten blättern können.

Mein erster Instinkt war, einfach eine Seite ( Home genannt ) zu verwenden und einen Shortcode einzubetten, der Seiten-Slugs akzeptiert und die richtige Reihenfolge ausgibt (dh [pageOrder]intro, blog, about-us, portfolio, contact-us[/pageOrder]). Die Seite verwendet eine benutzerdefinierte Seitenvorlage, um die Elemente anzuordnen, die Schleife zu steuern und der linken Seite eine Navigation hinzuzufügen. Aber das scheint alles klunkig.

Meine ideale Lösung wäre, einen benutzerdefinierten Beitragstyp ( Stapel ) zu erstellen , der es dem Endbenutzer ermöglicht, die Seiten per Drag-Drop zu positionieren und das CPT für Layout und Navigation usw. zu sorgen.

Das Problem mit meiner idealen Lösung sind Einstellungen. Mit WordPress können Sie eine Seite für die Standardhomepage der Site auswählen. Aber es ist an einen Pfosten Typen gebunden Seite , und ich bin nicht sicher , wo in einzuhaken , das zu ändern , so dass Benutzer auch eine Auswahl könnten Stapel als Standard - Homepage.

Wo kann ich mich anmelden, um der Dropdown-Liste der verfügbaren Seiten für die Standardhomepage einen CPT hinzuzufügen?

Antworten:


11

Vielen Dank an @toscho für die hilfreiche Antwort, aber es fühlte sich für mich etwas hackisch an, also stöberte ich ein bisschen herum und fand heraus, dass ich stattdessen einen Filter hinzufügen könnte:

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

Aktualisieren

Nach dem Hinzufügen des obigen Codes konnte ich zwar einen benutzerdefinierten Beitragstyp als Startseite verwenden, aber WordPress leitete die Permalinks um, da es sich nicht um einen Beitragstyp "Seite" handelte. So http://localhost/testwürde Umleitung zu http://localhost/test/stacks/home-stack, das war nicht das, was ich wollte.

Das Hinzufügen dieser Aktion hat das behoben und meinen benutzerdefinierten Beitragstyp zusammen mit Seiten für die Homepage abgefragt:

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

Ich habe auch mit einem solchen Filter gespielt, aber er muss auf die Titelseitenabfrage beschränkt sein. Und dann wurde ich von einigen seltsamen Verhaltensweisen / Fehlern geschlagen: Ich bekam nur 404s. Wie auch immer +1. :)
fuxia

Guter Fang. Die zusätzliche Bedingung innerhalb der Funktion (stellen Sie sicher, dass sie post_typenoch nicht gesetzt ist und dass sie page_idnicht 0 ist) verhindert alle 404s. Ich kann jetzt Abfragen für alle meine benutzerdefinierten Beiträge, alle meine Beiträge und alle meine Seiten ohne Störung ausführen.
EAMann

@EAmann Danke für den Code! Es funktioniert wie es sollte, obwohl es den Titel der Titelseite in Title of Post | ändert Homepage-Name, kann dies in irgendeiner Weise so geändert werden, dass es nur der Homepage-Name ist?
INT

Dies funktioniert überhaupt nicht ... Server-Warnungen / -Fehler : Fehlendes Argument 2 für wpa18013_add_pages_to_dropdown () und Undefinierte Variable: r
Dameer

8

Vielleicht so? Verfeinerte Version meiner früheren Lösung .

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

Dies dient nur zur Auswahl des benutzerdefinierten Beitragstyps, bewirkt jedoch nicht, dass dieser benutzerdefinierte Beitragstyp als Startseite angezeigt wird. oder fehlt mir etwas
Hameedullah Khan

@Hameedullah - Sobald Sie es ausgewählt haben, aktualisiert WordPress eine Option, die markiert, welche Seite für die Startseite verwendet werden soll. Wenn ein Benutzer dann die Startseite besucht, liest WordPress dieselbe Option aus der Datenbank zurück.
EAMann

@Hameedullah Khan Du hast recht. Das hat vor 3.1 funktioniert, jetzt bin ich auf den Permalink des Posts umgeleitet - und ich bekomme eine 404. Seltsam. Ich wünschte, ich hätte Zeit dafür. :(
fuxia

5

Warum nicht einfach eine front-page.phpVorlagendatei erstellen, die entweder eine normale Abfrage / Schleife verwendet oder (wenn eine benutzerdefinierte Designoption zum Anzeigen des CPT auf der Startseite festgelegt ist) eine benutzerdefinierte Abfrage / Schleife basierend auf dem CPT ausgibt?

Das Problem dabei ist, dass Sie eine separate Theme-Option erstellen müssen, um die Ausgabe der Startseite zu steuern, und gleichzeitig Benutzer anweisen müssen, die Startseite auf statische Seite zu setzen.

Zur Vereinfachung können Sie Ihre Theme-Option in das Einstellungslesen einbinden, indem Sie die Optionsgruppe "Lesen" in Ihrem Aufruf register_settingüber die Settings-API verwenden, damit sie mit den vorhandenen Front-Page-Optionen angezeigt wird.


Ich mag einfache Lösungen und Chip ist meiner Meinung nach die beste. Wordpress erlaubt benutzerdefinierte Vorlagen für die Startseite codex.wordpress.org/Template_Hierarchy#Home_Page_display und dann kann man tun, was man will.
Anmari

Dies ist die wartungsfreundlichste und einfachste Lösung. Die front-page.phpwird automatisch ausgewählt, da sie Teil der WordPress-Vorlagenhierarchie ist. Sie müssen sich nicht daran erinnern, warum dies geschieht (oder es für die nächste Person notieren).
Odys

2

Ich denke, dass sich etwas geändert hat, seit EAMann sein Update 2011 geschrieben hat und die von ihm bereitgestellte Funktion wpa18013_add_pages_to_dropdown () nicht mehr funktioniert. Wie in einem Kommentar von Dameer erwähnt, gibt diese Funktion derzeit (Dezember 2013) den Fehler "Fehlendes Argument 2 für wpa18013_add_pages_to_dropdown ()" aus.

Die Lösung bestand für mich sowieso darin, die Funktion ohne diesen zweiten Parameter neu zu schreiben oder den Inhalt zu überprüfen. Der vollständige Codeblock wird dann zu:

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

Beachten Sie, dass der benutzerdefinierte Beitragstyp, den ich hinzufüge, im obigen Beispiel "unbox_tabs" und nicht "stack" ist.


1

Ich verwende diese Technik , um eine Vorlage aus einem Plugin einzuschließen. Die Lösung von @ ChipBennett trifft also nicht zu.

Um die CPTs ( ) aus dem Plugin in die Liste der statischen Seiten einzufügen, habe ich die @ EAMann-Lösung wie folgt geändert: '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' );
}

Kernreferenz v3.4.2:
geringfügiger Unterschied der Zeilennummern in 3.5 RC3, Code bleibt jedoch gleich

/**
 * 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 );
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.