El curioso caso del decorador de navegación fantasma golpeando el caché EE de Magento

12

Prepárate para una extraña. Por lo tanto, estoy personalizando la navegación del catálogo principal para crear un comportamiento de interfaz de usuario completo que maneje múltiples modelos de interacción (menús, menús desplegables, modales, etc.) en todos los dispositivos. Como tu lo haces.

Eso significa anular esta clase / método:

app/code/core/Mage/Page/Block/Html/Topmenu.php :: _getHtml()

Para producir una salida HTML como esta (algo simplificada):

<ul class="nav-list">
    <li class="nav-1">
        <a data-ui-action="nav-1" href="#">Bazzow</a>
        <div class="menu"> ... </div>
    </li>

    <li class="nav-2">
        <a data-ui-action="nav-2" href="#">Bazinga</a>
        <div class="menu"> ... </div>
    </li>
</ul>

Ahora, esto es bastante aburrido / estándar, excepto por el data-ui-actionatributo. Ahí es donde sucede la magia JS. Cualquier clic en elementos con ese atributo actualiza el estado de la interfaz de usuario. Lo has adivinado, la li.nav-Xclase (que agrega Magento) actúa como mi gancho para vincular el estado de la interfaz de usuario al elemento activado.

Todo bien, verdad? Encienda el caché EE. Todo bien ¿verdad? Incorrecto.

Si la página que está viendo está dentro de la jerarquía de catálogo de Bazinga (aka nav-2), de repente verá esto:

data-ui-action="nav-2 active"

¿Quién agregó la activecuerda desagradable ? El fantasma es quién.

Y ahora su estado de IU falla, porque el valor del atributo de datos ya no coincide con la <li>clase. Caza al fantasma.

La caza

  1. Primero, verifica que bajo la memoria caché EE la variable $child->getPositionClass()que produce en nav-2realidad no tiene otros (presumiblemente) valores de clase añadidos. No es asi.

  2. Comprueba que uno de los muchos scripts JS decoradores de Magento no se está ejecutando en la lista de navegación. No es.

  3. Tal vez en realidad sea algo extraño /js/varien/menu.js. Pero ya excluyó esos scripts centrales como siempre lo hace.

  4. Tal vez sea un JS en línea loco que nunca sabrías que un módulo representa fuera de la clase PHP. Busque en la fuente de la página activedentro de las <script>etiquetas. No encuentras nada

  5. Tal vez sea otro loco que JS Magento requiere, pero se carga externamente. Deshabilita JS en el navegador, pero el fantasma vive.

  6. Vuelve a su Topmenu.phpclase y elimina el atributo de datos. El problema se detiene. Que demonios.

  7. Se pregunta si otro atributo en el mismo elemento no se cierra correctamente entre comillas (hey, hay muchos anexos de clase allí). Entonces intercambias el orden de los atributos y los eliminas en varias combinaciones. No dados. Si el atributo de datos está presente, también lo está el fantasma.

  8. ¿Se pregunta qué pasaría si no es esta clase de PHP la que realiza la escritura? Hay un page_block_html_topmenu_gethtml_afterevento enviado que algo más podría usar para hackear el marcado desde más allá. Nada.

  9. Qué. Es. Sucediendo. Aquí.

La respuesta

Explique todo eso a los desarrolladores de back-end. Todos actúan confundidos. Hasta...

Brendan Falkowski
fuente

Respuestas:

10

Alguien se abre:

app/code/core/Enterprise/PageCache/Model/Container/Catalognavigation.php
Method: saveCache()
Line 107

Ves una pequeña expresión regular desagradable:

if (preg_match('/(?<=\s|^)nav-.+?(?=\s|$)/', $classValue, $matches)) {
    $categoryUniqueClasses .= ($categoryUniqueClasses ? ' ' : '') . $matches[0];
}

Lo que coincide con algo de demonio nav-dentro de esto <li>. Solo para que lo recuerdes:

<li class="nav-1">
    <a data-ui-action="nav-1" href="#">Bazzow</a>
    <div class="menu"> ... </div>
</li>

Magento espera encontrar solo nav-cadenas en los <li>elementos, pero el valor de su atributo de datos se está haciendo coincidir y hackeado. No quiero.

Por lo tanto, use una clase diferente y un atributo de datos como i-have-a-child-.

El fantasma

Un hombre de verdad hace su propia suerte, Billy Zane.

Brendan Falkowski
fuente
1
¡Problema "impresionante" y explicación!
Anna Völkl
jaja wow, eso es realmente una locura ... En un modelo del módulo de caché de página completa ... votado
Erfan