Проблема
То, что у вас возникают проблемы, это "Как мне сделать 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 и т. Д. Это даст вам список постов из коробки.
Кроме того, используйте навигационные меню и полностью обойти эту проблему