Mejorando el rendimiento de mi eZ Publish (III)
En el anterior post de esta serie hablábamos del ViewCaching y terminábamos diciendo lo importante que es el exprimirlo el máximo. Es importante saber cómo funciona para no cometer errores o no desaprovechar sus ventajas. Hasta ahora hemos visto ejemplos de páginas muy sencillas (listado de artículos y detalle de artículos). Vamos ahora a plantear un nuevo tipo de página, las implicaciones que tendría el ViewCaching en ella y finalmente ver como pese a esas implicaciones podemos hacer uso de él de forma conveniente.
Supongamos la siguiente estructura de contenido.
Para las carpetas "Deportes" y todas las que cuelgan de ella queremos que nos liste los "artículos" que en la misma. Cuando estemos en en "Deportes" debería aparecernos los 9 articulos que tenemos en las 3 carpetas. Pero también queremos hacer un filtrado por el tipo de deporte y las exigencias nos obligan a hacer la selección a través de una selección entre elementos del combo.
El resultado de lo que queremos puedes verlo en http://www.unblogsobreez.com/deportistas.
El código necesario para pintar el formulario es que sigue:
<form action="{$node.url_alias|ezurl}" method="post"> <select name="category"> <option value="">Todos</option> {def $options = fetch("content", "list", hash("parent_node_id", $node.node_id))} {foreach $options as $option} <option value="{$option.node_id}">{$option.name}</option> {/foreach} </select> <input type="submit" value="Filtrar" /> </form>
mientras que para generar el listado usamos la función tree del módulo content, a la que le pasaremos el numero del nodo deportistas cuando no se haya elegido filtro y el numero del deporte en cuestión, el cual obtenemos gracias al operador ezhttp.
<ul id="news"> {def $parent = $node.node_id} {if ezhttp_hasvariable( "category", "post")} {set $parent = ezhttp( "category", "post")} {/if} {def $articles = fetch( 'content', 'tree', hash( 'parent_node_id', $parent, 'class_filter_type', 'include', 'class_filter_array', array( 'article' ), 'sort_by', array( 'published', false() ) ) ) } {foreach $articles as $article} <li>{node_view_gui view=line content_node=$article}</li> {/foreach} </ul>
Sin embargo, si pruebas el filtro verás que algo no está funcionando como debe. Por más que trates de usar el filtro, todos los deportistas aparecen una y otra vez, sin establecerse filtro alguno. ¿Por qué?. Como te decíamos en el anterior capítulo, el ViewCaching ha guardado la petición en un fichero y está llamando a ese fichero para presentar el resultado. Pero ese fichoer es html puro. No hay nada de PHP en él, con lo cual, la función que intenta detectar si nos viene algo por el POST simplemente no funciona.
Solucionando el problema
Para solucionar el problema tenemos varias opciones. La primera sería la más drástica y desde ya te recomendamos no hacerla nunca. Consistiría en desactivar el ViewCaching. De esta manera, todo el código php volvería a ejecutarse en cada petición, pero esto pasaría con todas las páginas del site. Pero no tiene sentido ninguno penalizar el rendimiento de todo el site simplemente porque en una zona o página necesitemos desactivar el cache.
Una solución intermedia consiste en establecer un valor para la variable cache_ttl únicamente en esta plantilla. Simplemente colocaríamos en la parte superior de la plantilla algo tal que así.
{set-block scope=root variable=cache_ttl}0{/set-block}
El valor indicará el tiempo de vida en segundos para el o los cachés de esta página. Puede resultarte de interés establecer un cache de una hora o un día para algunas páginas. Veremos ejemplos más adelante. En este caso, queremos invalidar el cache para esta página. Cada vez que se pida tenemos que comprobar que el usuario no está usando el filtro, y por tanto le damos el valor 0. Puedes hacer la prueba en esta otra dirección y verás como aquí si funcionarán los filtros perfectamente.
Pero esta debería ser tu última opción. Trata de usar un cache_ttl de 0 lo menos que puedas y, si puedes, encuentra soluciones que eviten usarlo. Lo que te recomendamos en este caso es un pequeño truco. Cambia el action de tu formulario y mandalo a una vista de un módulo que hayas construido tú. En esa vista captura el nodo que te están mandando desde el formulario y desde ahí, redirige al nodo que te está llegando.
Por partes. En primer lugar modificamos nuestro formulario y lo dejamos tal que así.
<form action={"examples/redirector"|ezurl} method="post"> <select name="category"> <option value="{$node.path_array.2}">Todos</option> {def $options = fetch("content", "list", hash("parent_node_id", $node.node_id))} {foreach $options as $option} <option value="{$option.node_id}">{$option.name}</option> {/foreach} </select> <input type="submit" value="Filtrar" /> </form>
En nuestro script recogeremos lo que nos llegue del formulario y redirigiremos al nodo correspondiente
$module = $Params["Module"]; $http = eZHTTPTool::instance(); $node = eZContentObjectTreeNode::fetch( $http->postVariable( "category") ); $module->redirectTo( $node->urlAlias() );
De esta forma, podremos aprovechar el cache de cada uno de los nodos carpeta. Estamos simulando enlaces a cada una de las categorías. Aquí tienes el resultado final.