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.

Но мне действительно нужно отсортировать заказ по мета-значению. Поэтому я должен использовать пользовательский запрос.

пожалуйста помоги. Благодарность

phpuser
источник
1
Ниже вы говорите, что нашли ответ, что это?
Дрю Бейкер
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()?
Чип Беннетт
Я пробовал этот код, но он возвращает только подстраницы первого уровня. Мне нужна подстраница >> sub sub >> etc ... (несколько нижних уровней страниц.). Наконец я нашел решение. Спасибо за ваш ответ
phpuser
7
какое у тебя решение !?
JCHASE11
Внутри определений массива есть несколько точек с запятой, вызывающих синтаксические ошибки.
ptrin
4

Проблема

То, что у вас возникают проблемы, это "Как мне сделать X?" Это не одношаговое действие, это многошаговый процесс, и его нужно разбить на части.

Вам не нужно делать это:

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, чтобы сделать это от высшего к низшему.

А как же дети?

В середине нашего цикла нам нужно сделать рекурсивный вызов, передавая дочерний, а не родительский идентификатор.

Итак, это:

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

С этой модификацией функция теперь извлекает детей, детей детей, детей детей детей ..... и т. Д.

В конце вы можете обрезать значения в массиве, чтобы получить такие идентификаторы:

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

Используя эту стратегию, вы можете заменить значение мета-ключа любой другой метрикой или использовать рекурсивные функции другими способами.

Поскольку для полного кода требуется всего несколько секунд базового понимания и быстрой вставки копии, я не оскорбляю ваш разум блоком кода полной вставки копии.

преимущества

  • С модификацией работает для любого типа сообщения и формы данных
  • Может быть изменен для создания вложенной разметки
  • Простота кэширования для ускорения путем помещения возвращаемых массивов в переходные процессы
  • Может быть настроен с подкачкой, применяя подкачку до конца WP_Query

Проблемы, с которыми вы столкнетесь

  • У вас нет возможности узнать, сколько детей, пока вы их не найдете, поэтому затраты на производительность не увеличиваются
  • То, что вы хотите, будет генерировать много запросов, и по своей природе это дорого из-за возможных глубин.

Моя рекомендация

Я бы порекомендовал вам либо сгладить иерархию страниц, либо использовать таксономию. Например, если вы оцениваете посты, имейте таксономию Page Rating с условиями 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вы можете использовать мета значения, как изначально запрашивал автор этого вопроса.

tfrommen
источник
2

Не уверен, что это именно то, что вам нужно, но вы можете использовать функцию wp_list_pages и использовать параметры child_of и глубины.

Для получения дополнительной информации см. Следующую страницу Кодекса: 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).

Если нет, то более простой способ получить весь дочерний идентификатор:

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

$children_ids = array();
if ( ! empty( $children ) )
    foreach ( $children as $post )
        $children_ids[] = $post->ID;
ОИТН
источник
-1

Я ДЕЛАЮ ЭТУ РАБОТУ, ТОЛЬКО КОПИРУЙТЕ ВСТАВИТЬ КОД НА ВАШ ФАЙЛ PAGE.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) не очень хорошо объяснил.
2013 г.