Cum să incluzi și să excluzi taxonomii din arhive și fluxuri folosind 'pre_get_posts'

10 mar. 2013, 18:44:07
Vizualizări: 17.2K
Voturi: 6

Ce încerc să realizez?

Blogul meu folosește o taxonomie personalizată numită edition cu termeni precum us-canada (6), eu (7) și india (8) -- slug-ul termenului (ID).

Vreau să mă asigur că postările neatribuite unei anumite 'edition' să fie afișate sub toți termenii (adică dacă o postare nu este atribuită SUA, Europei sau Indiei, să apară în paginile de arhivă ale tuturor acestor termeni).

Ce am încercat?

Iată un exemplu de cod pentru unul dintre termeni, care ar trebui să ofere o idee despre ce încerc exact să fac și unde greșesc.

add_filter('pre_get_posts','better_editions_archive');

function better_editions_archive($query) {

    if ( $query->is_tax( 'edition', 6 ) && $query->is_main_query() ) {
        $query->set( 'post_type', array( 'post' ) );

        $query->set( 'tax_query',
            array(
                'relation' => 'AND',
                array(
                    'taxonomy' => 'category',
                    'field' => 'id',
                    'terms' => array( 1, 2, 4, 5 )
                ),
                array(
                    'taxonomy' => 'edition',
                    'field' => 'id',
                    'terms' => array( 7, 8 ),
                    'operator' => 'NOT IN'
                )
            )
        );
    }

    return $query;
}

Care e problema? Codul menționat nu funcționează (altele pe care le-am încercat: cod-1, cod-2), nu schimbă nimic. Nu apare nicio eroare de debug.

DE ASEMENEA, pentru a mă asigura că modificările se aplică și fluxurilor acestor termeni, am înlocuit linia relevantă din codul anterior cu:

function better_editions_archive($query) {

    if ( ( $query->is_tax( 'edition', 6 ) && $query->is_main_query() ) || ( $query->is_feed() && $query->is_tax( 'edition', 6 ) ) ) {

Dar asta face ca fluxurile termenilor să fie redirecționate înapoi către arhivele termenilor. Adică, cu funcția activă, example.com/edition/usa/feed/ redirecționează către example.com/edition/usa/.

ACTUALIZARE: Ce a funcționat pentru mine? (Dar...)

add_filter( 'pre_get_posts', 'better_editions_archive' );

function better_editions_archive( $query ) {
    if ( $query->is_tax( 'edition', 6 ) && $query->is_main_query() ) {

        $args = array(
            'post_type' => 'post',

            'tax_query' => array(
                'relation' => 'AND',
                array(
                    'taxonomy' => 'category',
                    'field' => 'id',
                    'terms' => array( 1, 2, 4, 5 )
                ),
                array(
                    'taxonomy' => 'edition',
                    'field' => 'id',
                    'terms' => array( 7, 8 ),
                    'operator' => 'NOT IN'
                )
            )
        );

        $query->query_vars = $args;
    }

    return $query;
}

Funcționează, dar problema este că am avut o discuție extinsă cu un dezvoltator WordPress cunoscător, care mi-a spus asta (puteți urmări întreaga conversație aici, dar este prea lungă):

Și apoi atribui acest array ca query_vars. query_vars este un obiect destul de mare. Și practic suprascrii datele de acolo și adaugi doar cele personalizate. Asta înseamnă că 'anulezi' tot ce este adăugat implicit.

El mi-a recomandat să nu folosesc această soluție, ci să merg pe metoda $query->set();.

Dar după cum puteți vedea mai sus, nu am reușit să fac cealaltă metodă să funcționeze. Așa că sunt aici pentru a vedea dacă cineva îmi poate spune ce greșesc, într-un limbaj mai puțin tehnic.

11
Comentarii

Lipsește un ) pentru a închide metoda set a lui $query->set( 'tax_query',

birgire birgire
10 mar. 2013 19:51:41

@birgire Tocmai am observat comentariul tău în timp ce eram pe cale să fac o editare. Nu a lipsit niciun ) inițial (metoda set este de fapt închisă, iar ); de închidere se află pe o altă linie mai jos). Poți să te uiți cu atenție la cod?

its_me its_me
10 mar. 2013 19:56:58

Folosește array-ul tax_query în metoda $query->set. Developerul are dreptate, tu suprascrii tot în query și este mai bine dacă doar îmbunătățești interogarea.

bueltge bueltge
12 mar. 2013 21:08:16

@bueltge Este asta ce vrei să încerc? Dacă da, am încercat. Nu a funcționat. Dacă nu, poți fi puțin mai clar? Mersi!

its_me its_me
12 mar. 2013 21:43:18

Poți clarifica în ce fel nu funcționează? Primești absolut niciun rezultat? Sau doar nu combinația de rezultate pe care te așteptai?

vancoder vancoder
12 mar. 2013 22:32:55

@vancoder da, cum am spus, nimic nu se schimbă, adică e la fel cu/fără funcția pusă. Nu primesc absolut niciun rezultat!

its_me its_me
12 mar. 2013 22:47:53

Primul array imbricat din tax_query a specificat taxonomia ca 'category'. Este corect? Sau ar trebui să fie 'edition'?

vancoder vancoder
13 mar. 2013 00:06:15

@vancoder Din câte înțeleg eu, așa ar trebui să fie. Primul array ar trebui să spună 'afișează postări din toate categoriile', iar al doilea array ar trebui să îl suprascrie puțin și să spună, dacă postarea/postările aparțin oricărui alt termen de taxonomie personalizată (edition) decât arhiva termenului pe care o vizualizezi, nu le afișa. Înțelegi ideea pe care încerc să o exprim aici? Mă întreb dacă nu este clar în întrebarea mea. Spune-mi dacă ai nevoie de mai multe informații.

its_me its_me
13 mar. 2013 00:24:32

Sunt 100% sigur de ce vrei să obții, dar am editat răspunsul meu pe baza unei presupuneri educate.

vancoder vancoder
13 mar. 2013 00:32:40

@Thone: Mă refer la asta, ce este acum în răspuns $query->set( 'tax_query', array() ) ;) Ieri nu am putut scrie un răspuns, am citit pe telefon.

bueltge bueltge
13 mar. 2013 12:18:13

@bueltge Deja fac asta. Te rog să vezi primul bloc de cod.

its_me its_me
13 mar. 2013 14:17:07
Arată celelalte 6 comentarii
Toate răspunsurile la întrebare 2
7
17

Voi încerca din nou.

Următorul cod ar trebui să modifice interogarea principală, astfel încât să includă în bucla sa orice articole care nu aparțin niciunui termen din taxonomia personalizată "Edition".

add_filter('pre_get_posts','better_editions_archive');

function better_editions_archive( $query ) {

    if ( $query->is_tax( 'edition' ) && $query->is_main_query() ) {
        $terms = get_terms( 'edition', array( 'fields' => 'ids' ) );
        $query->set( 'post_type', array( 'post' ) );
        $query->set( 'tax_query', array(
            'relation' => 'OR',
            array(
                'taxonomy' => 'edition',
                'field' => 'id',
                'terms' => $terms,
                'operator' => 'NOT IN'
            )
        ) );
    }

    return $query;
}
12 mar. 2013 21:08:19
Comentarii

Tocmai am încercat asta. Nu a schimbat nimic. Nici erori/sugestii de depanare. Mulțumesc pentru încercare. :)

its_me its_me
12 mar. 2013 21:44:40

Ca metodă de depanare, poți încerca print_r($query) în primul tău cod exemplu. În output ar trebui să fie SQL-ul generat. Adaugă-l aici, ar putea fi util.

vancoder vancoder
12 mar. 2013 22:25:55

Doar pentru verificare - folosești WP 3.5 sau mai nou, corect?

vancoder vancoder
12 mar. 2013 22:34:31

Da, cea mai recentă versiune de WordPress (mereu!). Și pentru depanare, vrei să înlocuiesc return $query; cu print_r($query);? Asta vrei să fac?

its_me its_me
12 mar. 2013 22:38:36

Dacă da, iată ce am obținut: http://paste.kde.org/694496/ -- Spune asta ceva? (Nu am înțeles.)

its_me its_me
12 mar. 2013 22:39:52

Oh Doamne, a funcționat! Și fără alte modificări, modifică și feed-urile termenilor de taxonomie personalizată la fel cum face pentru arhivele termenilor (ceea ce, desigur, este ceea ce doresc). Așa funcționează sau doar visez? Nu trebuie să adăugăm ceva de genul ( is_feed() && is_.... )?

its_me its_me
13 mar. 2013 07:17:10

Ar trebui să funcționeze pe orice pagină de termeni din cadrul taxonomiei Edition. Nu sunt sigur despre fluxuri. Dar voi accepta recompensa dacă funcționează :)

vancoder vancoder
13 mar. 2013 18:28:31
Arată celelalte 2 comentarii
0

Notă pentru mine: Răspunsul lui @vancoder este practic o versiune mai bună (& automatizată) a acestuia:

add_filter('pre_get_posts','better_editions_archive');

function better_editions_archive($query) {

    if ( $query->is_tax( 'edition') && $query->is_main_query() ) {

        $query->set( 'post_type', array( 'post' ) );

        $query->set( 'tax_query',
            array(
                array(
                    'taxonomy' => 'edition',
                    'field' => 'id',
                    'terms' => array( 6, 7, 8 ),
                    'operator' => 'NOT IN'
                )
            )
        );

    }

    return $query;
}

(Ce spune codul) Dacă este arhiva pentru orice termen care aparține taxonomiei personalizate 'edition', atunci...

  1. Codul nu interferează cu funcționalitatea implicită a paginilor de arhivă pentru termeni, adică postările atribuite unui termen din taxonomia personalizată 'edition' vor fi (ca de obicei) afișate în arhiva termenului respectiv.

  2. Dar dacă o postare nu este atribuită niciunui dintre termenii taxonomiei specificate (vezi 'terms' => array( 6, 7, 8 ) și 'operator' => 'NOT IN'), atunci afișează astfel de postări în paginile de arhivă ale tuturor termenilor taxonomiei personalizate.

  3. Codul afectează și fluxurile RSS ale acestor termeni, astfel că fluxurile reflectă conținutul paginilor de arhivă, exact ceea ce am nevoie. În cazul în care nu doriți ca fluxurile să fie afectate, adică dacă doriți ca modificările să se aplice doar paginilor de arhivă, înlocuiți condiția IF cu aceasta:

    if ( $query->is_tax( 'edition') && $query->is_main_query() && ! $query->is_feed() ) {
    
13 mar. 2013 15:44:27