คุณใช้ CPT เป็นหน้าแรกเริ่มต้นได้อย่างไร


20

ฉันมีลูกค้าที่ไซต์จะใช้ประโยชน์จากประเภทโพสต์ที่กำหนดเองอย่างหนักเพื่อกำหนดค่าไซต์ของพวกเขา แต่ฉันอยู่ระหว่างก้อนหินและสถานที่ที่ยากสำหรับหน้าแรกที่ต้องการ

ในความเป็นจริงหน้าแรกจะเป็น "หน้า" เฉพาะภายในเวิร์ดเพรส โดยทั่วไปจะมีหน้าสำหรับ: Intro , บล็อก , เกี่ยวกับเรา , ผลงานและติดต่อเรา พวกมันทั้งหมดจะถูกซ้อนทับกันเพื่อให้คุณสามารถเลื่อนจากหน้าหนึ่งไปอีกหน้าหนึ่ง

สัญชาตญาณแรกของฉันคือการใช้หน้า (เรียกว่าหน้าแรก ) และฝังรหัสย่อที่ยอมรับทากหน้าและแสดงลำดับที่ถูกต้อง (เช่น[pageOrder]intro, blog, about-us, portfolio, contact-us[/pageOrder]) หน้าดังกล่าวจะใช้เทมเพลตหน้าแบบกำหนดเองเพื่อจัดวางสิ่งต่าง ๆ ควบคุมการวนซ้ำและเพิ่มการนำทางไปทางด้านซ้ายของหน้า แต่ทั้งหมดดูเหมือน klunky

ทางออกที่ดีที่สุดของฉันคือการสร้างโพสต์แบบกำหนดเอง (เรียกว่าสแต็ค ) ที่อนุญาตให้ผู้ใช้วางตำแหน่งหน้าเว็บด้วยการลากวางและให้ CPT ดูแลเลย์เอาต์และการนำทางและอื่น ๆ

ปัญหากับทางออกที่ดีที่สุดของฉันคือการตั้งค่า WordPress อนุญาตให้คุณเลือกหน้าสำหรับโฮมเพจเริ่มต้นของไซต์ แต่มันเชื่อมโยงกับประเภทโพสต์ของหน้าและฉันไม่แน่ใจว่าจะขอปรับเปลี่ยนเพื่อให้ผู้ใช้สามารถเลือกสแต็คเป็นหน้าแรกเริ่มต้น

ดังนั้นฉันจะเชื่อมโยงไปยังที่ใดเพื่อเพิ่ม CPT ในรายการแบบหล่นลงของหน้าที่มีอยู่สำหรับโฮมเพจเริ่มต้น

คำตอบ:


11

ขอบคุณ @toscho สำหรับคำตอบที่มีประโยชน์ แต่ฉันรู้สึกว่าแฮ็คเล็กน้อยฉันจึงแหย่ไปรอบ ๆ และคิดว่าฉันสามารถเพิ่มตัวกรองแทนได้:

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

ปรับปรุง

หลังจากเพิ่มรหัสด้านบนฉันเป็นจริงสามารถใช้ประเภทโพสต์ที่กำหนดเองเป็นหน้าแรก แต่ WordPress จะเปลี่ยนเส้นทาง Permalinks เพราะมันไม่ใช่ประเภทโพสต์ "หน้า" ดังนั้นhttp://localhost/testจะเปลี่ยนเส้นทางไปhttp://localhost/test/stacks/home-stackซึ่งไม่ใช่สิ่งที่ฉันต้องการ

อย่างไรก็ตามการเพิ่มการกระทำนี้แก้ไขและสอบถามประเภทโพสต์ที่กำหนดเองของฉันพร้อมกับหน้าสำหรับหน้าแรก:

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

ฉันเล่นด้วยตัวกรองเช่นกัน แต่จะต้อง จำกัด การสืบค้นหน้าแรก จากนั้นฉันก็ถูกพฤติกรรมแปลก ๆ / ข้อบกพร่อง: ฉันมีเพียง 404 วินาที อย่างไรก็ตาม +1 :)
fuxia

จับดี. เงื่อนไขเพิ่มเติมภายในฟังก์ชั่น (ตรวจสอบให้แน่ใจว่าpost_typeยังไม่ได้ตั้งค่าและที่page_idไม่ใช่ 0) จะป้องกัน 404 ทั้งหมด ตอนนี้ฉันสามารถเรียกใช้แบบสอบถามสำหรับโพสต์ที่กำหนดเองทั้งหมดของฉันโพสต์ทั้งหมดและหน้าทั้งหมดของฉันโดยไม่มีการรบกวนใด ๆ
EAMann

@ EAmann ขอบคุณสำหรับรหัส! มันทำงานได้ตามที่ควรจะเป็นแม้ว่ามันจะเปลี่ยนชื่อของ frontpage เป็น Title of Post | ชื่อโฮมเพจนี้สามารถเปลี่ยนเป็นชื่อโฮมเพจได้ไหม?
INT

ไม่สามารถใช้งานได้ ... คำเตือน / ข้อผิดพลาดของเซิร์ฟเวอร์: ไม่มีอาร์กิวเมนต์ที่ 2 สำหรับ wpa18013_add_pages_to_dropdown ()และตัวแปรที่ไม่ได้กำหนด: r
Dameer

8

อาจจะงั้นเหรอ? รุ่นกลั่นของการแก้ปัญหาก่อนหน้านี้ของฉัน

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

นี่เป็นเพียงการเลือกประเภทโพสต์ที่กำหนดเอง แต่มันไม่ได้แสดงประเภทโพสต์ที่กำหนดเองเป็นหน้าแรก? หรือฉันหายไปบางอย่าง
Hameedullah Khan

@Hameedullah - เมื่อคุณเลือกแล้ว WordPress จะอัปเดตตัวเลือกที่ทำเครื่องหมายว่าควรใช้หน้าใดในหน้าแรก จากนั้นเมื่อผู้ใช้เยี่ยมชมหน้าแรก WordPress อ่านตัวเลือกเดียวกันกลับมาจากฐานข้อมูล
EAMann

@Hameedullah Khan คุณพูดถูก สิ่งนี้ใช้ได้ก่อน 3.1 ตอนนี้ฉันเปลี่ยนเส้นทางไปยังลิงก์ถาวรของโพสต์ - และฉันได้รับ 404 แปลก ฉันหวังว่าฉันจะมีเวลาสำหรับสิ่งนี้ :(
fuxia

5

เหตุใดจึงไม่เพียงสร้างfront-page.phpไฟล์เทมเพลตที่ใช้ทั้งคิวรี / ลูปปกติหรือ (หากมีการตั้งค่าตัวเลือกธีมที่กำหนดเองเพื่อแสดง CPT บนหน้าแรก) จะแสดงเอาต์พุตเคียวรี / ลูปที่กำหนดเองตาม CPT

ปัญหาที่เกิดขึ้นคือคุณจะต้องสร้างตัวเลือก Theme แยกต่างหากเพื่อควบคุมเอาต์พุตของ Front Page ในขณะเดียวกันก็แนะนำให้ผู้ใช้ตั้งค่า Front Page เป็นหน้าคงที่

เพื่อให้สิ่งต่าง ๆ ง่ายขึ้นคุณสามารถเชื่อมโยงตัวเลือกชุดรูปแบบของคุณเข้ากับการตั้งค่าการอ่านโดยใช้กลุ่มตัวเลือก "การอ่าน" ในการโทรของคุณregister_settingผ่านทาง API การตั้งค่าเพื่อให้ปรากฏขึ้นพร้อมกับตัวเลือก


ฉันชอบโซลูชันที่เรียบง่ายและ Chip ฉันคิดว่าสิ่งที่ดีที่สุดของคุณคือ Wordpress อนุญาตให้ใช้เทมเพลตที่กำหนดเองสำหรับหน้าแรก codex.wordpress.org/Template_Hierarchy#Home_Page_display จากนั้นผู้ใช้สามารถทำสิ่งที่ชอบได้ภายในนั้น
anmari

นี่เป็นวิธีการบำรุงรักษาที่ง่ายที่สุดและตรงไปตรงมา front-page.phpถูกเลือกโดยอัตโนมัติเพราะเป็นส่วนหนึ่งของลำดับชั้น WordPress แม่แบบ ไม่จำเป็นต้องจำสาเหตุที่เกิดขึ้น (หรือจำเป็นต้องทำเครื่องหมายลงเพื่อคนต่อไป)
Odys

2

ฉันคิดว่าบางอย่างอาจมีการเปลี่ยนแปลงตั้งแต่ EAMann เขียนอัปเดตของเขาในปี 2011 และฟังก์ชั่น wpa18013_add_pages_to_dropdown () ของเขาไม่ได้ทำงานอีกต่อไป ตามที่ระบุไว้ในความคิดเห็นโดย Dameer ฟังก์ชั่นนี้ในปัจจุบัน (ธันวาคม 2013) ส่งข้อผิดพลาด "ไม่มีอาร์กิวเมนต์ 2 สำหรับ wpa18013_add_pages_to_dropdown ()"

วิธีแก้ปัญหาสำหรับฉันต่อไปคือการเขียนฟังก์ชั่นใหม่โดยไม่มีพารามิเตอร์ตัวที่สองหรือตรวจสอบเนื้อหา บล็อกเต็มของรหัสนั้นจะกลายเป็น:

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

โปรดทราบว่าในตัวอย่างด้านบนประเภทโพสต์ที่กำหนดเองที่ฉันเพิ่มคือ "unbox_tabs" มากกว่า "สแต็ค"


1

ฉันใช้เทคนิคนี้เพื่อรวมแม่แบบจากปลั๊กอิน ดังนั้นโซลูชันของ @ ChipBennett จึงไม่มีผล

ในการเพิ่ม CPT's ( ) จากปลั๊กอินในรายการหน้าคงที่ฉันได้แก้ไขโซลูชันของ @ EAMann ดังนี้: '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' );
}

การอ้างอิงหลัก v3.4.2:
ความแตกต่างเล็กน้อยของหมายเลขบรรทัดใน 3.5 RC3 แต่รหัสยังคงเหมือนเดิม

/**
 * 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 );
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.