Как получить всех детей и внуков иерархического пользовательского типа сообщения?

8

Мне нужно получить все подпосты с определенным (корневым) родительским идентификатором.

get_posts( array( 'numberposts' => -1, 'post_status' => 'publish', 'post_type' => 'microsite', 'post_parent' => $root_parent_id, 'suppress_filters' => false ) );

WP-Codex: функция get_post () имеет post_parent, но не имеет параметра child_of.

Преимущество функции get_pages () в сочетании с параметром child_of заключается в том, что «... обратите внимание, что параметр child_of будет также извлекать« внуков »данного идентификатора, а не только прямых потомков.» *

Пол Гайслер
источник

Ответы:

11

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

например

function get_posts_children($parent_id){
    $children = array();
    // grab the posts children
    $posts = get_posts( array( 'numberposts' => -1, 'post_status' => 'publish', 'post_type' => 'microsite', 'post_parent' => $parent_id, 'suppress_filters' => false ));
    // now grab the grand children
    foreach( $posts as $child ){
        // recursion!! hurrah
        $gchildren = get_posts_children($child->ID);
        // merge the grand children into the children array
        if( !empty($gchildren) ) {
            $children = array_merge($children, $gchildren);
        }
    }
    // merge in the direct descendants we found earlier
    $children = array_merge($children,$posts);
    return $children;
}

// example of using above, lets call it and print out the results
$descendants = get_posts_children($post->ID);
echo '<pre>';
print_r($descendants);
echo '</pre>';

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

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

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

Том Дж Новелл
источник
Проблема с этим кодом в том, что он не дает правильного порядка; Сначала я получаю весь верхний уровень, а затем весь второй уровень в одном сплющенном массиве. Любая подсказка о том, как исправить?
dama_do_bling
Этот код не был предназначен для этого, у вас есть другая проблема, которая требует немного другого решения, и огромная доля контекста
Том Дж. Новелл
0

Просто используйте get_page_children(). Он работает для каждого типа поста (не только для страниц) и в основном то, что @TomJNowell показал в другом вопросе, но уже реализовано ядром.

$children = get_page_children( $post->ID, $GLOBALS['wp_query'] );

Выше образец как в Кодексе. Вот почему вы можете просто взять глобальный объект запроса (или любой другой объект запроса) для использования в качестве базы поиска.

кайзер
источник
Но как вы используете это для другого типа сообщения? Не заставить его работать.
dama_do_bling
0

Используйте следующий шорткод для отображения всех детей и внуков в иерархическом представлении. Использование: [my_children_list] или [my_children_list page_id = 123]

function my_children_list_func($atts, $content = null) {
    global $post;

    $a = shortcode_atts( array(
            'page_id' => ''
    ), $atts );

    $args = array( 
            'numberposts' => -1, 
            'post_status' => 'publish', 
            'post_type' => 'microsite', 
            'post_parent' => (isset($a['page_id']) && $a['page_id']) ? $a['page_id'] : $post->ID,
            'suppress_filters' => false 
    );

    $parent = new WP_Query( $args );

    ob_start();

    if ( $parent->have_posts() ) :?>
            <ul>
            <?php while ( $parent->have_posts() ) : $parent->the_post(); ?>
                    <li><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a>
                    <?php echo do_shortcode('[tadam_children_list page_id='.get_the_ID().']') ?>
                    </li>
            <?php endwhile;?>
            </ul>
    <?php endif; wp_reset_postdata();

    return ob_get_clean();
}
add_shortcode( 'my_children_list', 'my_children_list_func' );
Адам Пери
источник