Łączenie zapytań z różnymi argumentami dla każdego typu postu

11

Buduję sekcję w witrynie, w której łączę dwa różne typy postów w jedną pętlę, a następnie wyświetlam je losowo. Problem polega na tym, że trudno mi znaleźć sposób na ograniczenie liczby postów według typu.

Oto, co próbowałem:

  • Jedno zapytanie z wieloma typami postów można uzyskać za pomocą tablicy:

    $args = array( 'post_type' => array( 'photos', 'quotes' ), ...

    ... ale nie może ograniczać się do określonej liczby postów według typu.

  • Scalenie dwóch tablic argumentów zapytania przed uruchomieniem na nim WP_Query :

    $photos = array( 'post_type' => 'photos', 'posts_per_page' => 15, 'orderby' => 'rand' );
    $quotes = array( 'post_type' => 'quotes', 'posts_per_page' => 5, 'orderby' => 'rand' );
    
    $args = $photos + $quotes;
    // Also tried array_merge( $photos, $quotes );
    

    Nie ma w tym szczęścia. Ta ostatnia zmienna $quoteszastępuje $photosi pokazuje tylko cudzysłowy.

  • Scalanie dwóch obiektów WP_Query razem poprzez rzutowanie czcionek :

    $photos_query = new WP_Query( $photos );
    $quotes_query = new WP_Query( $quotes );
    $result = (object)array_merge( (array)$photos_query, (array)$quotes_query );
    

... i tak dalej.

Pewnie przydałby zapytanie SQL prosto do bazy danych, ale muszą być w stanie połączyć te dwa odrębne rodzaje pocztowych dla jednej pętli, ułożone losowo, i ogranicza się do pewnej ilości postów typu.

Dzięki za pomoc!

Andy Merskin
źródło

Odpowiedzi:

16

Jednym ze sposobów jest dostosowanie zapytania SQL wykonanego przy użyciu posts_clauseslub innych takich filtrów. Aby je znaleźć, wyszukaj je posts_clausesw „wp-include / query.php” i zobacz serię filtrów tuż przed tym wierszem. Te razem są w stanie dostosować dowolną część zapytania

Inną rzeczą, którą możesz zrobić, jest ręczne scalenie odpytywanych postów w obiektach

$photos_query = new WP_Query( $photos );
$quotes_query = new WP_Query( $quotes );
$result = new WP_Query();

// start putting the contents in the new object
$result->posts = array_merge( $photos_query->posts, $quotes_query->posts );

// here you might wanna apply some sort of sorting on $result->posts

// we also need to set post count correctly so as to enable the looping
$result->post_count = count( $result->posts );
Mridul Aggarwal
źródło
Twoje drugie rozwiązanie (bez SQL) załatwiło sprawę! Teraz mam pełną kontrolę nad tym, co wchodzi w to ostatnie zapytanie, zanim przejdę do pętli. Dzięki za pomoc!
Andy Merskin,
1
Pierwszy jest trudny, ale bardziej wydajny (w drugim są jeszcze 2 zapytania do bazy danych). Powiedziałbym, że sprowadza się to do osobistych preferencji
Mridul Aggarwal
Byłby bardzo zainteresowany sposobem na osiągnięcie pierwszego rozwiązania! Potrzebne filtry itp. Czy to wymaga UNIONjakiegoś rodzaju w sql dla każdego typu post_?
Solomon Closson
@SolomonClosson ten filtr może pomóc- codex.wordpress.org/Plugin_API/Filter_Reference/posts_clauses
Mridul Aggarwal
7

@mridual aggarwal twoja odpowiedź jest bardzo bardzo dobra, ale niestety tak naprawdę nie łączy 2 wp_query, pokazuje tylko posty z obu w ustawieniu, mam na myśli 5 postów z pierwszego i 5 z drugiego, ale nie posortowane w jednym, więc mam to rozwiązanie i przynajmniej dokładnie osiągnęło cel dla siebie

<?php
$term = get_term_by( 'slug', get_query_var( 'tag' ), "post_tag" );
$tagslug = $term->slug;
$post_types = get_post_types('','names');
?>
<?php
//first query
$blogposts = get_posts(array(
    'tag' => $tagslug, //first taxonomy
    'post_type' => $post_types,
    'post_status' => 'publish',
    ));
//second query
$authorposts = get_posts(array(
    'bookauthor' => $tagslug, //second taxonomy
    'post_type' => $post_types,
    'post_status' => 'publish',
    ));
$mergedposts = array_merge( $blogposts, $authorposts ); //combine queries

$postids = array();
foreach( $mergedposts as $item ) {
$postids[]=$item->ID; //create a new query only of the post ids
}
$uniqueposts = array_unique($postids); //remove duplicate post ids

$posts = get_posts(array(
        //new query of only the unique post ids on the merged queries from above
    'post__in' => $uniqueposts,  
    'post_type' => $post_types,
    'post_status' => 'publish',
    ));
foreach( $posts as $post ) :
setup_postdata($post);
?>
// posts layout
<?php endforeach; ?>
<?php wp_reset_postdata();?>
adnan
źródło