Los elementos de menú, las páginas y las taxonomías (jerárquicas) son todos ejemplos de datos con una estructura en forma de árbol: los términos pueden tener padres, hijos y hermanos. Por lo general, nos gustaría reflejar esta estructura en el formato HTML. Para mostrar un menú, por ejemplo, queremos que el HTML sea de una lista de enlaces de "nivel superior", con listas anidadas de sus hijos, que a su vez contengan listas anidadas de sus hijos, y así sucesivamente. Este tutorial lo guiará a través de una clase que proporciona WordPress, que hace que la realización de este marcado sea extremadamente simple.
La clase walker es una clase abstracta diseñada para ayudar a atravesar y mostrar elementos que tienen una estructura jerárquica (o similar a un árbol). En realidad, no 'hace' (en el sentido de generar HTML) cualquier cosa. Simplemente traza cada rama de su árbol: tiene que ser extendido por otras clases que le dicen qué hacer para cada elemento con el que se encuentra. WordPress proporciona sus propias clases ampliadas, tales como:
Walker_Nav_Menu
- para visualizar el HTML para los menús de navegaciónWalker_Page
- para mostrar una lista de páginasWalker_Category
- para mostrar una lista de términos de taxonomía.Cada una de estas clases extiende la clase Walker simplemente dictando los resultados de la clase en cada elemento y nivel del árbol. Para desmitificar esta clase, analizaremos sus métodos principales y un par de ejemplos de cómo usarla. La clase en sí se puede encontrar aquí..
Caminar
caminar ($ elementos, $ max_depth)
La clase walker se inicia con el método walk y es este método el que devuelve el HTML una vez que se ha generado. Acepta dos argumentos:
$ max_depth
- establece cuántas generaciones exploramos$ args
. Esto luego se pasa a otros métodos en la claseEl método de caminar selecciona los elementos de "nivel superior", aquellos sin padres, y los coloca en una sola matriz. El resto, los hijos, se colocan en una segunda matriz donde la clave es el ID de su padre (es una matriz bidimensional, ya que un padre puede tener varios hijos):
$ children_elements = array ('1' => array () // Array de elementos correspondientes a los hijos de 1, '4' => array () // Array de elementos que corresponden a los hijos de 4);
A continuación, recorre cada uno de los elementos principales y aplica el método. elemento de visualización
.
Display_Element
display_element ($ element, & $ children_elements, $ max_depth, $ depth = 0, $ args, & $ output)
Como el nombre sugiere elemento de visualización
Es responsable de mostrar un elemento en nuestro árbol. De hecho, llama a varias funciones para hacer esto. Estas funciones se dejan en blanco deliberadamente en la clase Walker, y son éstas las que se modifican en las clases ampliadas, ya que determinan el HTML real devuelto. Éstos incluyen:
start_lvl
- una función para devolver el HTML para el inicio de un nuevo nivel. En el caso de las listas, esto sería el comienzo de una nueva 'sub-lista', y por lo tanto sería responsable de devolver la
etiquetaend_lvl
- Llamado cuando hayamos terminado un nivel. En el ejemplo del menú de navegación, esta función es responsable de finalizar la sub-lista con una etiqueta de lista de cierre
start_el
- la función responsable de mostrar el elemento actual en el que estamos. En el caso de los menús, esto significa
etiqueta y enlace del artículo.end_el
- La función llamada después de un elemento y todos sus elementos secundarios se han mostrado. Para nuestro ejemplo de menú esto significa devolver un cierre.
Entonces que hace elemento de visualización
en realidad hacer? En realidad es donde tiene lugar toda la magia de la clase Walker. Primero echemos un vistazo a los argumentos que se dan:
$ elemento
- Este es el elemento en el que estamos actualmente en nuestro árbol.$ children_elements
- una serie de todos elementos hijos (no solo hijos del elemento mencionado anteriormente). Esta es la segunda matriz formada en el caminar
Método y las claves son los identificadores del padre..$ max_depth
- ¿Qué tan abajo podemos explorar?$ profundidad
- que tan abajo estamos actualmente$ args
- argumentos opcionales (mencionados anteriormente)$ salida
- El HTML hasta ahora. Esto se añade a medida que exploramos más del árbol.. los elemento de visualización
método de primeras llamadas start_el
que se encarga de mostrar el elemento. Exactamente cómo lo hace depende del contexto. Para un menú desplegable puede ser o para un menú de navegación puede
. Tenga en cuenta que todavía no hay una etiqueta de cierre. Si este elemento tiene hijos, primero debemos mostrarlos para que estén anidados dentro de este elemento ...
Entonces, a continuación, verifica si el elemento actual en el que estamos tiene hijos y no hemos alcanzado la profundidad máxima. Si es así, exploramos a cada uno de los niños a su vez, llamando elemento de visualización
para cada uno de ellos (con el argumento de profundidad incrementado en uno). De esta manera el elemento de visualización
Recursivamente se llama a sí mismo hasta que llegamos al fondo..
Supongamos que hemos llegado al 'fondo' (un elemento sin hijos o con la profundidad máxima), entonces llama end_el
que añade la etiqueta de cierre. Ahí está la instancia actual de elemento de visualización
Termina y nos movemos de nuevo al padre que aplica. elemento de visualización
al siguiente niño, hasta que hayamos procesado a cada uno de sus hijos. Cuando el padre ya no tiene más hijos, retrocedemos por el árbol, y así sucesivamente hasta que se explora cada rama. ¿Confuso? Es un diagrama que espero que aclare las cosas:
El uso de la clase Walker hace que la visualización de datos jerárquicos personalizados sea muy simple. Supongamos que tiene una matriz de objetos, con 'etiqueta
','Identificación de los padres
'y'object_id
'propiedades que desea mostrar una lista de. Esto ahora se puede lograr fácilmente con una clase muy simple:
Nota: La clase extendida es responsable de establecer dónde encontrar el ID de un elemento y el de su padre.
la clase Walker_Simple_Example extiende Walker // Establezca las propiedades del elemento que proporcionan el ID del elemento actual y su var primario $ db_fields = array ('parent' => 'parent_id', 'id' => 'object_id'); // Muestra el inicio de un nivel. P.ej '
Puede ampliar las clases de walker para cambiar el contenido que se muestra, alterar el HTML generado o incluso evitar que se muestren ciertas ramas. Funciones tales como:
wp_nav_menu
wp_list_pages
wp_list_categories
Ofrezca una opción para especificar su propia clase de Walker personalizada, lo que le permite modificar su apariencia con relativa facilidad al especificar su propia clase de Walker personalizada. En muchos casos, en realidad es más fácil extender una extensión de walker apropiada, en lugar de la propia clase de Walker..
Supongamos que desea tener un (sub) menú secundario relacionado con su menú principal. Esto puede tomar la forma de enlaces que se encuentran justo debajo de su menú principal o en una barra lateral que muestra solo los elementos del menú 'descendiente' de la 'página de nivel superior' actual. Como ejemplo del diagrama anterior, si estamos en las subpáginas 'Archivo', 'Autor' o 'Noticias', nos gustaría mostrar todos los enlaces a continuación 'Archivo'. Ya que Walker_Nav_Menu
hace la mayor parte de lo que queremos, extenderemos esa clase en lugar de la clase Walker. Esto nos ahorra mucho esfuerzo, ya que la Walker_Nav_Menu
añade las clases apropiadas ('corriente
','ancestro actual
'etc) a los enlaces pertinentes. Vamos a extender el Walker_Nav_Menu
Clase walker para alterar ligeramente la lógica, y evitar que muestre enlaces de nivel superior o cualquiera de los descendientes de las páginas 'no root'.
En primer lugar, en sus archivos de plantilla, utilizaremos el wp_nav_menu ()
Funciona dos veces, apuntando a la misma. ubicación del tema (Lo llamaré 'primario
'). Si aún no tiene una ubicación de tema registrada, debe leer este artículo. Cualquiera que sea la ubicación del tema que esté utilizando, debe guardar un menú en esa ubicación. Mostraremos este menú dos veces. Primero, donde quiera que aparezca su menú de 'nivel superior':
wp_nav_menu (array ('theme_location' => 'primary', 'depth' => 1));
Entonces, nuevamente, con un andador personalizado, para mostrar solo las páginas secundarias (relevantes).
wp_nav_menu (array ('theme_location' => 'primary', 'walker' => nuevo SH_Child_Only_Walker (), 'depth' => 0));
En primer lugar, no queremos mostrar los padres de nivel superior. Recordemos que la función responsable de la apertura. etiqueta y el enlace es
start_el
y la función responsable del cierre. etiqueta es
end_el
. Simplemente verificamos si estamos en el nivel de los padres. Si lo somos, no hacemos nada. De lo contrario, continuamos 'como de costumbre' y llamamos a la función desde Walker_Nav_Menu
clase.
// No imprime la función de elementos de nivel superior start_el (& $ output, $ item, $ depth = 0, $ args = array ()) if (0 == $ depth) retorno; parent :: start_el (& $ output, $ item, $ depth, $ args); function end_el (& $ output, $ item, $ depth = 0, $ args = array ()) if (0 == $ depth) retorno; parent :: end_el (& $ output, $ item, $ depth, $ args);
Extendemos el elemento de visualización
. Esta función es responsable de viajar por las ramas. Queremos detenerlo en sus pistas si estamos en el nivel superior y no en el enlace raíz actual. Para verificar si la sucursal en la que estamos es "actual", verificamos si el elemento tiene alguna de las siguientes clases:item-menu actual
','actual-menu-parent
','menú-ancestro actual
'.
// Solo sigue una función de rama display_element ($ element, & $ children_elements, $ max_depth, $ depth = 0, $ args, & $ output) // Comprueba si el elemento es una clase de 'elemento actual' $ current_element_markers = array 'current-menu-item', 'current-menu-parent', 'current-menu-ancestor'); $ current_class = array_intersect ($ current_element_markers, $ element-> classes); // Si el elemento tiene una clase 'actual', es un antecesor del elemento actual $ ancestor_of_current =! Empty ($ current_class); // Si se trata de un enlace de nivel superior y no es el actual o antepasado del elemento del menú actual, deténgase aquí. if (0 == $ depth &&! $ ancestor_of_current) devuelve; parent :: display_element ($ element, & $ children_elements, $ max_depth, $ depth, $ args, & $ output);
Ahora extendemos el start_lvl
y end_lvl
funciones Estos son responsables de generar el HTML que envuelve un nivel (en este caso, el
etiquetas). Si estamos en el nivel superior, no queremos mostrar estas etiquetas (después de que no se muestren todos los contenidos).
// No envuelva la función de nivel superior start_lvl (& $ output, $ depth = 0, $ args = array ()) if (0 == $ depth) retorno; parent :: start_lvl (& $ output, $ depth, $ args); function end_lvl (& $ output, $ depth = 0, $ args = array ()) if (0 == $ depth) retorno; parent :: end_lvl (& $ output, $ depth, $ args);
Esa clase en su totalidad:
la clase SH_Child_Only_Walker extiende Walker_Nav_Menu // No inicie la función de nivel superior start_lvl (& $ output, $ depth = 0, $ args = array ()) if (0 == $ depth) retorno; parent :: start_lvl (& $ output, $ depth, $ args); // No finalice la función de nivel superior end_lvl (& $ output, $ depth = 0, $ args = array ()) if (0 == $ depth) retorno; parent :: end_lvl (& $ output, $ depth, $ args); // No imprime la función de elementos de nivel superior start_el (& $ output, $ item, $ depth = 0, $ args = array ()) if (0 == $ depth) retorno; parent :: start_el (& $ output, $ item, $ depth, $ args); function end_el (& $ output, $ item, $ depth = 0, $ args = array ()) if (0 == $ depth) retorno; parent :: end_el (& $ output, $ item, $ depth, $ args); // Solo sigue una función de rama display_element ($ element, & $ children_elements, $ max_depth, $ depth = 0, $ args, & $ output) // Comprueba si el elemento es una clase de 'elemento actual' $ current_element_markers = array ('elemento del menú actual', 'padre del menú actual', 'antepasado del menú actual'); $ current_class = array_intersect ($ current_element_markers, $ element-> classes); // Si el elemento tiene una clase 'actual', es un antecesor del elemento actual $ ancestor_of_current =! Empty ($ current_class); // Si se trata de un enlace de nivel superior y no es el actual o antepasado del elemento del menú actual, deténgase aquí. if (0 == $ depth &&! $ ancestor_of_current) return parent :: display_element ($ element, & $ children_elements, $ max_depth, $ depth, $ args, & $ output);
Una vez que entienda cómo funciona la clase walker, puede extenderlo (o las extensiones existentes de WordPress) para modificar la forma en que se muestran sus datos jerárquicos. Por ejemplo, usted puede: