Problem
Problem z chwytaniem to „Jak zrobić X?” To nie jest jednoetapowe działanie, to wieloetapowy proces i należy go rozdzielić.
Nie musisz tego robić:
get all the posts that are a child of X ordered by meta
Musisz to zrobić:
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
Ogólne rozwiązanie
Tak więc, aby zrozumieć, jak to robić w nieskończoność, dopóki nie osiągniesz końca, bez twardego kodowania, musisz zrozumieć funkcje rekurencyjne.
na przykład
function make_zero( $amount ) {
$amount = $amount - 1;
if ( $amount > 1 ){
return make_zero( $amount );
}
return $amount;
}
Zastosowanie rekurencji do tego problemu w celu rozwiązania
Więc twój rodzic jest $parid
, a twoja meta post ma klucz $metakey
.
Przekazujemy go do funkcji, aby złapać swoje dzieci.
$children = get_children_with_meta( $parid, $metakey );
Następnie posortujemy tablicę $ dzieci, klucze będą identyfikatorami postów, a wartości będą meta wartościami.
asort($children);
i pozwala zdefiniować funkcję jako:
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();
}
}
Daje to tablicę identyfikatorów postów i wartości, uporządkowanych od najniższej do najwyższej. Możesz użyć innych funkcji sortowania PHP, aby to zrobić od najwyższej do najniższej.
Co teraz z dziećmi dla dzieci?
W środku naszej pętli musimy wykonać połączenie rekurencyjne, przekazując dziecko, a nie identyfikator rodzica.
Więc to:
$q->the_post();
$meta_value = get_post_meta(get_the_ID(), $metakey, true );
$children[get_the_ID() ] = $meta_value;
Staje się to:
$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 );
Dzięki tej modyfikacji funkcja pobiera teraz dzieci, dzieci dzieci, dzieci dzieci ..... itd
Na koniec możesz przyciąć wartości z tablicy, aby uzyskać takie identyfikatory:
$post_ids = array_keys( $children );
$q = new WP_Query( array( 'post__in' => $post_ids );
// etc
Korzystając z tej strategii, możesz zastąpić wartość klucza meta dowolną inną metryką lub użyć funkcji rekurencyjnych na inne sposoby.
Ponieważ pełny kod wymaga tylko kilku sekund podstawowego zrozumienia i szybkiego wklejenia, nie obrażę twojej inteligencji blokiem wklejania pełnego kodu.
Zalety
- Dzięki modyfikacji działa na dowolny typ postu i formę danych
- Można go zmodyfikować, aby wygenerować zagnieżdżone znaczniki
- Łatwo buforuj, aby przyspieszyć, umieszczając zwrócone tablice w stanach nieustalonych
- Może być skonfigurowany ze stronicowaniem poprzez zastosowanie stronicowania na końcu WP_Query
Problemy, które napotkasz
- Nie możesz dowiedzieć się, ile jest dzieci, dopóki ich nie znajdziesz, więc koszty wydajności nie są skalowane
- To, czego chcesz, wygeneruje wiele zapytań i jest z natury kosztowne z uwagi na potencjalną głębokość.
Moja rekomendacja
Polecam albo spłaszczyć hierarchię stron, albo zastosować taksonomię. Np. Jeśli oceniasz posty, zastosuj taksonomię oceny strony z terminami 1,2,3,4 i 5 itd. W ten sposób otrzymasz post z pudełka.
Możesz też użyć menu nawigacji i całkowicie ominąć ten problem