Wp รับเพจย่อยทั้งหมดของพาเรนต์โดยใช้คิวรี wp


13

นี่คือรหัสของฉัน

$my_wp_query = new WP_Query();
$all_wp_pages = $my_wp_query->query(array('post_type' => 'page','post_parent'=>$parid,'orderby'=>'title','order'=>'ASC' ));

จะแสดงหน้าย่อยระดับแรกเท่านั้น ฉันต้องการหน้าย่อยทั้งหมดหน้าย่อยของ ... และทั้งหมด ฉันค้นหาวิธีแก้ปัญหาและฉันสามารถรับเพจย่อยทั้งหมดโดยใช้ get_pages และ wp_list_pages

แต่ฉันต้องเรียงลำดับตามค่าเมตาโพสต์ที่กำหนดเอง ดังนั้นฉันต้องใช้แบบสอบถามที่กำหนดเอง

กรุณาช่วย. ขอบคุณ


1
ด้านล่างคุณบอกว่าคุณพบคำตอบมันคืออะไร?
Drew Baker

4
คุณดูget_page_children แล้วหรือยัง?
t31os

คำตอบ:


6

ทำไมไม่ใช้เพียงget_pages()?

เช่น

<?php
// Determine parent page ID
$parent_page_id = ( '0' != $post->post_parent ? $post->post_parent : $post->ID );
// Get child pages as array
$page_tree_array = get_pages( array(
    'child_of' => $parent_page_id;
) );
?>

แต่ถ้ามันจะต้องเป็นWP_Query()วัตถุจริงๆให้ใช้วิธีการที่คล้ายกัน:

<?php
// Determine parent page ID
$parent_page_id = ( '0' != $post->post_parent ? $post->post_parent : $post->ID );
// Build WP_Query() argument array
$page_tree_query_args = array(
    'post_parent' => $parent_page_id;
);
// Get child pages as a WP_Query() object
$page_tree_query = new WP_Query( $page_tree_query_args );
?>

หากเราใช้ฟังก์ชัน get_pages () เราจะไม่สามารถใช้การเรียงลำดับ (sort_column) สำหรับฟิลด์ที่กำหนดเองได้ ยอมรับเฉพาะฟิลด์โพสต์ตารางเท่านั้น ฉันต้องใช้การเรียงลำดับสำหรับฟิลด์ที่กำหนดเอง ดังนั้นฉันเท่านั้นที่ใช้แบบสอบถาม wp () มีวิธีอื่นหรือไม่?
phpuser

คุณเห็นครึ่งหลังของคำตอบที่ฉันใช้WP_Query()หรือไม่
Chip Bennett

ฉันลองใช้รหัสนี้ แต่ส่งกลับหน้าย่อยระดับแรกเท่านั้น ฉันต้องการหน้าย่อย >> ย่อยของ >> อื่น ๆ ... (หลายระดับที่ต่ำกว่าของหน้า) ในที่สุดฉันก็พบทางออก ขอบคุณสำหรับการตอบกลับของคุณ
phpuser

7
อะไรคือทางออกของคุณ!
JCHASE11

มีอัฒภาคบางตัวภายในข้อกำหนดของอาร์เรย์ด้านบนทำให้เกิดข้อผิดพลาดทางไวยากรณ์
ptrin

4

ปัญหา

สิ่งที่คุณกำลังประสบปัญหาคือ "ฉันจะทำ X ได้อย่างไร" นี่ไม่ใช่การดำเนินการ 1 ขั้นตอน แต่เป็นกระบวนการหลายขั้นตอนและจำเป็นต้องแยกจากกัน

คุณไม่จำเป็นต้องทำสิ่งนี้:

get all the posts that are a child of X ordered by meta

คุณต้องทำสิ่งนี้:

get all the posts that are a child of X
    for each child, get all the posts that are a child
        foreach child of that child get all the posts that are a child
            ...
                hmmm we don't have any more children left

Take our list of posts and order them by meta

การแก้ปัญหาทั่วไป

ดังนั้นเพื่อที่จะเข้าใจวิธีการที่จะทำอย่างไม่มีที่สิ้นสุดจนกว่าคุณจะถึงจุดสิ้นสุดโดยไม่ต้องเข้ารหัสมันคุณต้องเข้าใจฟังก์ชั่นวนซ้ำ

เช่น

function make_zero( $amount ) {
    $amount = $amount - 1;
    if ( $amount > 1 ){
        return make_zero( $amount );
    }
    return $amount;
}

การใช้การเรียกซ้ำไปยังปัญหานี้เพื่อการแก้ไข

ดังนั้นพ่อแม่ของคุณและเมตาโพสต์ของคุณมีสำคัญของ$parid$metakey

ให้มันผ่านเข้าไปในฟังก์ชั่นเพื่อจับลูกของมัน

$children = get_children_with_meta( $parid, $metakey );

จากนั้นเราจะจัดเรียงแถว $ children คีย์จะเป็นรหัสโพสต์และค่าจะเป็นค่าเมตา

asort($children);

และให้นิยามฟังก์ชันเป็น:

function get_children_with_meta( $parent_id, $metakey ) {
    $q = new WP_Query( array( 'post_parent' => $parent_id, 'meta_key' => $metakey ));
    if ( $q->have_posts() ) {
        $children - array();
        while ( $q->have_posts() ) {
            $q->the_post();
            $meta_value = get_post_meta(get_the_ID(), $metakey, true );
            $children[get_the_ID() ] = $meta_value;
        }
        return $children;
    } else {
        // there are no children!!
        return array();
    }
}

สิ่งนี้จะช่วยให้คุณได้รับรหัสโพสต์และค่าต่างๆเรียงตามลำดับจากต่ำไปมาก คุณสามารถใช้ฟังก์ชั่นการจัดเรียง PHP อื่น ๆ เพื่อทำจากมากไปน้อย

ตอนนี้สิ่งที่เกี่ยวกับเด็กเด็ก

ในระหว่างการวนรอบเราจำเป็นต้องทำการเรียกซ้ำเรียกผ่านเด็กมากกว่า ID หลัก

ดังนั้นนี่คือ:

$q->the_post();
$meta_value = get_post_meta(get_the_ID(), $metakey, true );
$children[get_the_ID() ] = $meta_value;

กลายเป็นสิ่งนี้:

$q->the_post();
$meta_value = get_post_meta(get_the_ID(), $metakey, true );
$children[get_the_ID() ] = $meta_value;

// now get the childrens children
$grandchildren = get_children_with_meta( get_the_ID(), $metakey );

// merge the grandchildren and the children into the same list
$children = array_merge( $children, $grandchildren );

ด้วยการปรับเปลี่ยนนี้ฟังก์ชั่นตอนนี้ดึงเด็กเด็กเด็กเด็กเด็กเด็ก ..... ฯลฯ

ในตอนท้ายคุณสามารถตัดค่าในอาร์เรย์เพื่อรับ ID ดังนี้:

$post_ids = array_keys( $children );
$q = new WP_Query( array( 'post__in' => $post_ids );
// etc

การใช้กลยุทธ์นี้คุณสามารถแทนที่ค่าคีย์เมตาด้วยเมทริกอื่น ๆ หรือใช้ฟังก์ชันแบบเรียกซ้ำในวิธีอื่น

เนื่องจากรหัสเต็มต้องการเพียงไม่กี่วินาทีของความเข้าใจพื้นฐานและการคัดลอกอย่างรวดเร็วฉันจึงไม่ดูถูกสติปัญญาของคุณด้วยการวางบล็อคการคัดลอกแบบเต็มของรหัส

ข้อดี

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

ปัญหาที่คุณจะพบ

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

คำแนะนำของฉัน

ฉันอยากจะแนะนำให้คุณทำให้ลำดับชั้นของหน้าแบนหรือใช้ taxonomy แทน เช่นหากคุณโพสต์การให้คะแนนมีการจัดอันดับหน้าภาษีด้วยเงื่อนไข 1,2,3,4 และ 5 เป็นต้นซึ่งจะช่วยให้คุณมีรายชื่อโพสต์ออกจากกล่อง

หรือใช้เมนูการนำทางและหลีกเลี่ยงปัญหานี้โดยสิ้นเชิง


3

รับเพจย่อยปัจจุบันทั้งหมดซ้ำ ๆ

get_childrenนี่เป็นวิธีการที่ใช้เรียกซ้ำ ใส่สิ่งต่อไปนี้ในของคุณfunctions.php:

function get_all_subpages($page, $args = '', $output = OBJECT) {
    // Validate 'page' parameter
    if (! is_numeric($page))
        $page = 0;

    // Set up args
    $default_args = array(
        'post_type' => 'page',
    );
    if (empty($args))
        $args = array();
    elseif (! is_array($args))
        if (is_string($args))
            parse_str($args, $args);
        else
            $args = array();
    $args = array_merge($default_args, $args);
    $args['post_parent'] = $page;

    // Validate 'output' parameter
    $valid_output = array(OBJECT, ARRAY_A, ARRAY_N);
    if (! in_array($output, $valid_output))
        $output = OBJECT;

    // Get children
    $subpages = array();
    $children = get_children($args, $output);
    foreach ($children as $child) {
        $subpages[] = $child;

        if (OBJECT === $output)
            $page = $child->ID;
        elseif (ARRAY_A === $output)
            $page = $child['ID'];
        else
            $page = $child[0];

        // Get subpages by recursion
        $subpages = array_merge($subpages, get_all_subpages($page, $args, $output));
    }

    return $subpages;
}

วิธีใช้งาน

ใช้ฟังก์ชั่นด้านบนทุกที่ที่คุณต้องการเช่นนี้

$all_current_subpages = get_all_subpages(0);

ฟังก์ชั่นรองรับargsพารามิเตอร์ (สตริงแบบสอบถามหรืออาร์เรย์) และoutputประเภท (ดูด้านบน)

ดังนั้นคุณสามารถใช้มันได้เช่น:

$args = array(
    'post_status' => 'private',
    'order_by' => 'post_date',
    'order' => 'DESC',
);
$all_current_subpages = get_all_subpages(42, $args, ARRAY_A);

และเนื่องจากการขึ้นต่อกันget_children=> get_posts=> WP_Queryคุณสามารถใช้ค่าเมตาตามที่ผู้เขียนคำถามนี้ขอในตอนแรก


2

ไม่แน่ใจว่านี่คือสิ่งที่คุณเป็นจริงหรือไม่ แต่คุณสามารถใช้ฟังก์ชัน wp_list_pages และใช้พารามิเตอร์ 'child_of' และ 'ความลึก'

ดูหน้าต่อไปนี้ใน Codex สำหรับข้อมูลเพิ่มเติม: http://codex.wordpress.org/Function_Reference/wp_list_pages


2

ฉันได้ทำซ้ำฟังก์ชันที่ได้รับรหัสเด็กทั้งหมดของหน้าหลัก หลังจากที่เรามีรหัสแล้วเราจะทำการค้นหาหน้าต่างๆและสามารถเรียงลำดับผลลัพธ์โดยใช้เมตาคีย์ / ค่า

// Gets all the children ids of post_parent
function _get_children_ids( $post_parent ) {
    $results = new WP_Query( array(
        'post_type' => 'page',
        'post_parent' => $post_parent
    ) );

    $child_ids = array();
    if ( $results->found_posts > 0 )
        foreach ( $results->posts as $post ) // add each child id to array
            $child_ids[] = $post->ID;

    if ( ! empty( $child_ids ) )
        foreach ( $child_ids as $child_id ) // add further children to array
            $child_ids = array_merge( $child_ids, _get_children_ids( $child_id ) );

    return $child_ids;
}

$children_ids = _get_children_ids( 9 ); // use your numeric page id or get_the_id()

$results = new WP_Query( array(
    'post_type'   => 'page',
    'post__in'   => $children_ids
    #'meta_key'   => 'meta_key', // your meta key
    #'orderby'    => 'meta_key',
    /* 'meta_query' => array( // optional meta_query
        array(
            'key' => 'meta_key', // key
            'value' => array(3, 4), // values
            'compare' => 'IN', // operator
        )
    ) */
) );

var_dump( $results );

หากคุณต้องการจัดเรียงเด็ก ๆ โดยใช้เมตาคีย์ / ค่าในลักษณะลำดับชั้นคุณควรส่งค่า meta_key และ order_by ไปยัง WP_Query ในฟังก์ชัน _get_children_ids (แทน WP_Query สุดท้าย)

หากไม่เป็นเช่นนั้นวิธีที่ง่ายกว่าในการรับ id เด็กทั้งหมดคือ:

$children = get_pages( 'child_of=9');

$children_ids = array();
if ( ! empty( $children ) )
    foreach ( $children as $post )
        $children_ids[] = $post->ID;

-1

ฉันทำงานนี้ได้เพียงคัดลอกรหัสผ่านไปยังหน้าของคุณไฟล์ PHP

//REDIRECT TO FIRST CHILD FROM PARENT PAGE

// Build WP_Query() argument array
$page_tree_query_args = array(
    'post_parent' => $post -> ID,
    'post_type' => 'page',
    'order' => 'asc'
);
// Get child pages as a WP_Query() object
$page_tree_query = new WP_Query( $page_tree_query_args );
if(!empty($page_tree_query -> posts)){
    $first_subpage = $page_tree_query -> posts[0] -> ID;
    wp_redirect( get_permalink( $first_subpage ) );
    exit;   
}

นี่คือ A) ไม่ทำงาน ( $post -> ID?), B) ไม่ใช่สิ่งที่ขอ, C) ไม่ได้อธิบายได้ดีมาก
tfrommen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.