WP_Query y uso de una variable para 'cat'=> en el array args = ¿Bug de WP?
Para esta discusión, aquí hay una versión de mi consulta dentro de category.php:
wp_reset_query();
$category_id = get_cat_ID(single_cat_title('', false));
$my_query = new WP_Query(array(
'posts_per_page' => SOME_DEFINED_VALUE,
'cat' => $category_id,
'paged' => ( get_query_var('paged') ? get_query_var('paged') : 1 ),
'post_type' => array('post','post_custom_1','post_custom_2','post_custom_3')
));
// print_r($my_query);
En resumen, no funciona. Esto es lo que he notado.
Cuando hago print_r($my_query); puedo ver las query_vars en la primera línea. No coinciden con mis argumentos del array. Por ejemplo, posts_per_page vuelve a algún otro valor predeterminado (no la CONSTANTE), y la lista post_type ya no incluye post (lo cual debería/debe incluir).
Si elimino la línea con 'cat'=> o codifico el valor directamente ('cat'=> 3) entonces todo funciona como se espera. Las query_vars restantes aparecen en el print_r. Todo bien :)
He probado lo siguiente sin éxito:
- Convertir la variable en una CONSTANTE, igual que posts_per_page (que no causa problemas).
- Concatenar comillas alrededor del número $category_id - El resultado es el mismo que sin comillas. No funciona.
- 'cat' => array($category_id) - Obtuve un error - No le gustó que fuera un array.
¿Alguien tiene sugerencias?
Ahora, esto es lo que sí "funcionó" (entiéndase: pude usar mi $category_id y al hacerlo no afectó el resto de los args en la lista del array WP_Query()).
'cat' => '"-'$category_id'"',
Es decir, podría negar ese ID de categoría. Loco, ¿verdad?
A menos que pueda resolverlo correctamente, voy a tener una cadena separada por comas de todas mis categorías negadas, analizar la categoría actual y luego usar esa cadena para hacer la consulta. En otras palabras, si mis categorías fueran A, B y C, en lugar de hacer una consulta para A (como uno esperaría hacer)
'cat' => A
Voy a consultar por no B, no C.
'cat' => -B,-C
Espero que haya una solución menos improvisada. He estado en esto demasiadas horas y estoy lo suficientemente desesperado como para usar este hack y terminar con esto. Dicho esto, esto definitivamente parece un bug en el core. Sí, estoy usando 3.5.1 (¿o ya vamos por .2 o .3?). Mi punto es que estoy en la última versión (y esto hacía lo mismo en 3.2.x).
Por cierto, he visto este problema publicado en otros lugares (por ejemplo, foros de WP). La única solución sugería que los args array no fueran un array sino una cadena. Incluso si eso es posible con WP_Query, ¿cómo haría la lista/array para los post_types como una cadena? Finalmente, si estoy haciendo algo mal, entonces la página de ayuda del Codex necesita una actualización, ¿no?
Ayuda. :)

¿Dónde/cómo estás definiendo $category_id
?
Consulta la entrada del Codex para los parámetros de categoría de WP_Query()
. WP_Query()
espera que los IDs de categoría se pasen como enteros, no como cadenas:
- Si
$category_id
es un entero, pásalo a'cat'
. - Si
$category_id
es un array (de IDs de categoría, nuevamente como enteros), pásalo a'category__in'

Gracias @Chip. Esta línea, justo encima de la consulta:
$category_id = get_cat_ID(single_cat_title('', false));
Si la imprimo en pantalla, está ahí y me parece correcta. De hecho, query_vars SÍ incluye 'cat'=> el problema es que per_page y post_types se comportan de forma extraña. No estoy usando una variable no declarada o un tipo incorrecto. Por lo que puedo ver, ese no es el problema. ¿Alguna otra sugerencia? Gracias de nuevo

¿Y qué devuelve esa línea? Prueba con un var_dump( $category_id )
.

Agregué/probé esto: $category_id = (int)get_cat_ID(single_cat_title('', false)); var_dump( $category_id ); y WP_Query ignora mis argumentos y usa valores por defecto. Buen intento, pero hasta donde puedo ver el tipo (string o int) no es el problema. Y si envuelvo el int $var en '"'.$var.'"' NO funciona. PERO '"-'.$var.'"'; sí funciona. NOT = OK, de lo contrario mis argumentos se descartan y usa algunos valores por defecto (?)

Entonces, como un intento remoto, ¿probaste hacer un type-cast de $category_id
como integer?

Supongo que tiene que ver con la forma en que obtienes la categoría. Configuré la función en un blog en el que estoy trabajando; $category_id
siempre es 0.
Así que para verificarlo uso esta línea para $category_id
:
global $post;
$category_id = get_the_category($post->ID)[0]->term_id;
Es una forma rápida de obtener la primera categoría asignada a una publicación.
Después de eso, la consulta estaba bien y el parámetro cat
en la consulta se llena correctamente.

Gracias @Simon. Permíteme aclarar un poco. El 'cat' => $var sí funciona (más o menos). Aparece en el query_var. Sin embargo, cuando uso una $var para hacer esa asignación, otras cosas se descontrolan (por ejemplo, posts_per_page, post_type, etc.). No estoy recibiendo un error. Lo que sucede es que el array de argumentos que uso en WP_Query() no coincide con lo que veo en el print_r() *cuando intento asignar 'cat' => con una $var. Sí, dale vueltas a eso :) Además, estoy tratando de usar la línea de código que mencionas y me aparece: Parse error: syntax error, unexpected '['. ??

Agregué el global $post
, supongo que esto es lo que produce el error de análisis, lo siento.
No noté en mis pruebas nada malo excepto el $category_id
vacío.
Solo una nota, no uso print_r que es difícil de leer, uso el plugin de consola que permite ver variables en la consola de firebug. Es muy útil y hace que la lectura sea mucho más fácil

Bueno...yo había agregado el global $post; la primera vez y aún así obtuve el error. Supongo que por eso estaba preguntando. Extraño, ¿no?

Ok, esto debería funcionar solo en una página individual, no en la página de categoría, ¡perdón por no aclararlo antes! Es interesante, pero probablemente haya una explicación para tu problema.

Revisé tu código original en una página category.php y funciona correctamente. No hay desorden en post_type o post_per_page.

Gracias de nuevo @Simon. Sospecho que hay algún tipo de "fuga" de add en otra parte del tema. Yo no hice la construcción, solo estoy a cargo de mejoras. Pero incluso así, esto es un error del núcleo de WP en mi opinión. Debería obtener un error / debería fallar, o debería obtener los resultados basados en los argumentos de la consulta. Como está, obtengo una consulta aleatoria cuando hay una condición particular (pero legítima) (es decir, 'cat' => $var). Pregunta: Que se solucione el error de WP pronto es poco probable, entonces ¿qué tal solucionar problemas / encontrar una solución alternativa? ¿Alguna idea? Gracias de nuevo.

Quizás intenta cambiar el tema solo para verificar el comportamiento y la consistencia de los resultados devueltos. Como funciona para mí y otro compañero aquí, supongo que no hay un error en el núcleo, sino algún otro hook en el tema o un plugin.

Gracias de nuevo @Simon. Ojalá fuera tan fácil como cambiar temas, pero esto tiene que ver con tipos de publicaciones personalizados adicionales y demás que están integrados en este tema personalizado. Especifico una consulta. Hago la solicitud. WP usa un conjunto diferente de argumentos. Incluso si es otro plugin, etc. sigue siendo un error (para mí). No tiene sentido permitir plugins, etc. y luego no tener forma de saber cuál es responsable de "rechazar" la solicitud e intercambiarla por la suya. Eso no deja mucha fe en WP_Query, ¿verdad? Además... 'cat'=> -1,-3,-4 funciona pero 'cat'=> 2 no. Eso también me parece un error, ¿no? :(

Por cierto, resulta que el "truco" del "not" tampoco funciona del todo. El next_posts_link() se muestra en la última página. Lo que me lleva a creer que está usando un conjunto diferente de argumentos al que estoy enviando con mi cadena de "not cats" y otros argumentos. Ahora estoy atascado y perplejo.

Hola @Simon - Gracias por el empujón. Finalmente encontré un add_action( 'pre_get_posts', 'function_to_modify_the_query_in_category_php'). Sí, esa función estaba aumentando los parámetros estándar de la consulta. Por qué también había código en el category.php no estoy seguro. Obviamente, me distraje. Dicho esto, todavía no explica por qué 'cat'=> $var hizo las cosas raras. Valor codificado manualmente bien, $var no bien. Eso sigue siendo bastante extraño en mi opinión, de una manera que se siente como un error. Pero de nuevo, metí la pata bastante en este caso, ¿eh? Gracias de nuevo por tu ayuda.

De nada @Chief Alchemist. pre_get_posts
era el candidato correcto para ese comportamiento.

Como nota adicional... para cualquiera que esté leyendo esto... por favor, comenta tu código. Nunca sabes quién más podría tener que trabajar en él. Un simple "los argumentos de esta consulta se amplían con la función: xyz() en functions.php" me habría ahorrado mucho tiempo. 10 segundos pueden ahorrarle a alguien - incluyéndote a ti mismo - horas.

Probé tu función y funciona bien, así que probablemente tengas un error con algún otro código en tu tema o un conflicto con algún plugin. O quizás tu bucle no es correcto.
Como referencia, probé el siguiente código en category.php
en twentyeleven, la salida fue correcta, sin errores.
wp_reset_query();
define("SOME_DEFINED_VALUE", 5);
$category_id = get_cat_ID(single_cat_title('', false));
$my_query = new WP_Query(array(
'posts_per_page' => SOME_DEFINED_VALUE,
'cat' => $category_id,
'paged' => ( get_query_var('paged') ? get_query_var('paged') : 1 ),
'post_type' => array('post','post_custom_1','post_custom_2','post_custom_3')
));
var_dump($my_query);

Hola @Wyck - Sí, eso es lo que tiendo a creer. Es decir, hay algo en otro lado. Supongo que porque los valores predeterminados (es decir, los que reemplazan mi array de argumentos por algún otro conjunto de valores query_arr) tienen que venir de algún lado, ¿no? Pero eso es por lo que estoy aplicando el we_reset. Al forzarlo, debería dejarme con una pizarra limpia, ¿verdad? Aún así, ¿por qué establecer 'cat'=> (y hasta donde puedo ver, solo ese parámetro) con una $var sería un problema? Ese nivel de rareza se siente como un gran problema para mí. ¿Tú? Dicho todo esto... ¿alguna idea sobre una solución? ¿O cómo encontrar el error/agujero en el tema?

Revisa esa página de plantilla en busca de otros loops o si está incluyendo otras partes de plantillas (include
o get_template_part
), desactívalos y mira si funciona, elimina widgets de carga, desactiva plugins, verifica si algo está secuestrando la query mediante pre_get_posts
, comprueba si algo más está usando tu $my_query
(cambia el nombre).

Cuando dividí tu código en partes manejables para analizarlo, encontré que el problema probablemente estaba en la línea "paged" dentro del arreglo.
wp_reset_query();
$category_id = get_cat_ID(single_cat_title('', false));
$paged = ( get_query_var('paged') )? get_query_var('paged') : 1 ;
$query = array(
'posts_per_page' => 5,
'cat' => $category_id,
'paged' => $paged ,
'post_type' => array('post','custom_1','custom_2','custom_3')
);
$loop = new WP_Query( $query);
print_r($loop);
Como puedes ver, agregué un paréntesis adicional alrededor del primer get_query_var
para convertirlo en un operador ternario correcto. Probé esto en mi entorno de prueba y funcionó correctamente.
Saludos, Andy

Gracias @Andy Killen. Lamentablemente no funcionó. En este punto debe ser algo en otra parte del tema. Dicho esto, esperaría que wp_reset_query() me diera un estado limpio, ¿verdad? Tal como está, el que 'cat' sea asignado con un $val hace que WP busque otro conjunto de args. Esos SÍ parecen un conjunto que el sitio está usando en otro lugar. Lo que no entiendo es por qué. ¿Por qué no está usando los args que le estoy pidiendo que use? Y mejor aún, dado que no estoy obteniendo errores reales, ¿cómo debería intentar identificar esta "fuga"? Cualquier sugerencia sería muy apreciada. ¡Gracias!

Estoy de acuerdo con Wyck (actualmente abajo), esto es muy probablemente un problema con otro plugin o tu tema. Intentaría desactivar todos los plugins y probar de nuevo, y si eso no funciona, probaría poner tu categories.php en el tema twentyten o similar y probar allí.
El wp_reset_query() no es tan vital en esta situación. Podrías ver esto como un bucle anidado dentro del bucle estándar si realmente quisieras, ya que estás usando tu propia variable para almacenar el bucle no importará tanto.

¿Qué tal si simplemente hago una consulta SQL adecuada? Eso no va a añadir sobrecarga adicional, etc., ¿correcto? Simplemente me parece que para cuando rastreé el origen de la "fuga" - y quizás nunca pueda hacerlo ya que el uso de una $var activando un "bug" es bastante extraño para empezar, ¿no? - podría simplemente escribir una sentencia SQL y no tener que preocuparme por WP_Query() y sus problemas.

En realidad, creo que mi Plan A por ahora va a ser una cadena con todos los gatos excluidos. Y luego eliminaré el gato actual. Ups, creo que ya mencioné esto como solución. Es una locura pero funcionará. Y si algún día encuentro el agujero, simplemente puedo eliminar este "hack".
