Incluir y excluir taxonomías en archivos y feeds con 'pre_get_posts' en WordPress

10 mar 2013, 18:44:07
Vistas: 17.2K
Votos: 6

¿Qué estoy intentando hacer?

Mi blog utiliza una taxonomía personalizada llamada edition con términos como us-canada (6), eu (7) e india (8) -- slug del término (ID).

Quiero asegurarme de que los posts no asignados a ninguna 'edition' específica se muestren bajo todos los términos (es decir, si un post no está asignado a usa, europa o india, aparecerá en las páginas de archivo de todos estos términos).

¿Qué he intentado?

Aquí está el código de ejemplo relacionado con uno de los términos, que debería darte una idea de lo que estoy intentando hacer exactamente, y lo que podría estar haciendo mal.

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;
}

¿Qué está mal? El código mencionado no funciona (otros que he probado: código-1, código-2), no cambia nada. Tampoco hay ningún error de depuración.

Entonces, ¿qué podría estar haciendo mal?

ADEMÁS, para asegurarme de que los cambios también se apliquen a los feeds de estos términos, reemplacé la línea relevante en el código mencionado con esto:

function better_editions_archive($query) {

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

Pero eso comienza a redirigir los feeds de los términos de vuelta a los archivos de los términos. Es decir, con la función en su lugar, example.com/edition/usa/feed/ redirige de vuelta a example.com/edition/usa/.

De nuevo, no tengo idea de qué podría estar haciendo mal.

ACTUALIZACIÓN: ¿Qué ha funcionado para mí? (Pero...)

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;
}

Funciona, pero el problema es que tuve una extensa discusión con un desarrollador de WordPress experto, y me dijo esto (puedes seguir la conversación completa aquí, pero es muy larga):

Y luego estás asignando este array como query_vars. Ahora bien, query_vars es un objeto bastante grande. Y básicamente estás sobrescribiendo los datos que hay ahí y solo agregando tus personalizados. Esto significa que 'desconfiguras' todo lo que se agrega por defecto.

Básicamente me aconsejó no usar esta solución, y en su lugar usar el método $query->set();.

Pero como puedes ver más arriba, no pude hacer que el otro funcionara. Así que estoy aquí para ver si alguien puede decirme qué estoy haciendo mal, en un lenguaje menos técnico.

11
Comentarios

Falta un ) para cerrar el método set de $query->set( 'tax_query',

birgire birgire
10 mar 2013 19:51:41

@birgire Acabo de notar tu comentario mientras estaba a punto de hacer una edición. Tampoco había ningún ) faltante inicialmente (el set en realidad está cerrado, y el cierre ); está en otra línea más abajo). ¿Podrías revisar bien el código?

its_me its_me
10 mar 2013 19:56:58

Usa el array tax_query en el método $query->set. El desarrollador tiene razón, estás sobrescribiendo todo en la query y es mejor si mejoras la query.

bueltge bueltge
12 mar 2013 21:08:16

@bueltge ¿Es esto lo que quieres que intente? Si es así, lo probé. No funcionó. Si no, ¿puedes ser un poco más claro? ¡Gracias!

its_me its_me
12 mar 2013 21:43:18

¿Puedes aclarar de qué manera no está funcionando? ¿No obtienes ningún resultado? ¿O simplemente no la combinación de resultados que esperas?

vancoder vancoder
12 mar 2013 22:32:55

@vancoder sí, como dije, no hay cambios, es decir, es lo mismo con/sin la función en su lugar. ¡No obtengo ningún resultado!

its_me its_me
12 mar 2013 22:47:53

El primer arreglo anidado de tax_query especificó la taxonomía como 'category'. ¿Es esto correcto? ¿O debería ser 'edition'?

vancoder vancoder
13 mar 2013 00:06:15

@vancoder Según mi entendimiento así debería ser. El primer arreglo debería decir 'mostrar publicaciones de todas las categorías' mientras que el segundo arreglo debería sobrescribirlo un poco y decir, si la(s) publicación(es) pertenece(n) a cualquier otro término de taxonomía personalizada (edition) diferente al archivo de término que estás viendo, no lo muestres. ¿Entiendes la idea de lo que estoy tratando de hacer aquí? Me pregunto si eso no está claro en mi pregunta. Déjame saber si necesitas más información.

its_me its_me
13 mar 2013 00:24:32

Estoy 100% seguro de lo que buscas, pero he editado mi respuesta basándome en una suposición educada.

vancoder vancoder
13 mar 2013 00:32:40

@Thone: Me refiero a esto, lo que ahora está en la respuesta $query->set( 'tax_query', array() ) ;) Ayer no me fue posible escribir una respuesta, lo leí en mi móvil.

bueltge bueltge
13 mar 2013 12:18:13

@bueltge Ya lo estoy haciendo. Por favor mira el primer bloque de código.

its_me its_me
13 mar 2013 14:17:07
Mostrar los 6 comentarios restantes
Todas las respuestas a la pregunta 2
7
17

Lo intentaré de nuevo.

Lo siguiente debería modificar la consulta principal, de modo que incluya en su bucle cualquier publicación que no pertenezca a ningún término de la taxonomía personalizada Edition.

add_filter('pre_get_posts','mejorar_archivo_ediciones');

function mejorar_archivo_ediciones( $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
Comentarios

Acabo de intentar eso. No cambió nada. Tampoco hay errores de depuración/sugerencias. Gracias por intentarlo. :)

its_me its_me
12 mar 2013 21:44:40

Como método de depuración, puedes probar print_r($query) en tu primer código de ejemplo. En alguna parte del resultado debería aparecer el SQL generado. Añádelo aquí, podría ser útil.

vancoder vancoder
12 mar 2013 22:25:55

Solo para verificar - ¿estás usando WP 3.5 o superior, verdad?

vancoder vancoder
12 mar 2013 22:34:31

¿Sí, la última versión de WordPress (¡siempre!)? Y para el debug, ¿quieres que reemplace return $query; con print_r($query);? ¿Es eso lo que quieres que haga?

its_me its_me
12 mar 2013 22:38:36

Si es así, esto es lo que obtuve: http://paste.kde.org/694496/ -- ¿Eso dice algo? (No lo entendí).

its_me its_me
12 mar 2013 22:39:52

¡Oh Dios mío, eso funcionó! Y sin más cambios también está modificando los feeds de los términos de taxonomía personalizados, tal como lo hace con los archivos de los términos (que, por supuesto, es lo que quiero). ¿Así es como funciona o estoy soñando? ¿No necesitamos agregar algo como ( is_feed() && is_.... )?

its_me its_me
13 mar 2013 07:17:10

Debería funcionar en cualquier página de términos bajo la taxonomía Edition. No estoy seguro acerca de los feeds. Aceptaré la recompensa si funciona :)

vancoder vancoder
13 mar 2013 18:28:31
Mostrar los 2 comentarios restantes
0

Nota para mí: La respuesta de @vancoder es básicamente una versión mejorada (y automatizada) de esto:

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;
}

(Lo que hace el código) Si es el archivo para cualquier término que pertenezca a la taxonomía personalizada 'edition', entonces...

  1. El código no interfiere con la función por defecto de las páginas de archivo de los términos, es decir, los posts asignados a un término de la taxonomía personalizada 'edition' se mostrarán (como es habitual) en el archivo del término correspondiente.

  2. Pero si un post no está asignado a ninguno de los términos dados de la taxonomía personalizada (ver 'terms' => array( 6, 7, 8 ) y 'operator' => 'NOT IN'), entonces muestra dichos posts en las páginas de archivo de todos los términos de la taxonomía personalizada.

  3. El código también afecta a los feeds de dichos términos, y por lo tanto, los feeds reflejan el contenido de las páginas de archivo, que es justo lo que necesito. En caso de que no quieras que los feeds se vean afectados, es decir, si quieres que los cambios solo se apliquen a las páginas de archivo, reemplaza el IF con esto:

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