Ciekawy przypadek fantomowego dekoratora nawigacji uderzającego w pamięć EE Magento

12

Przygotuj się na dziwne. Dlatego dostosowuję nawigację katalogu głównego, aby zbudować zachowanie interfejsu użytkownika z pełnym stanem, które obsługuje wiele modeli interakcji (menu, menu rozwijane, modały itp.) Na różnych urządzeniach. Tak jak ty.

Oznacza to zastąpienie tej klasy / metody:

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

Aby wygenerować wynik HTML w ten sposób (nieco uproszczony):

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

Teraz jest to dość nudne / standardowe z wyjątkiem data-ui-actionatrybutu. To tam dzieje się magia JS. Wszelkie kliknięcia elementów o tym atrybucie aktualizują stan interfejsu użytkownika. Zgadłeś, li.nav-Xklasa (dodana przez Magento) działa jak mój haczyk, aby powiązać stan interfejsu użytkownika z aktywowanym elementem.

Wszystko dobrze, prawda? Włącz pamięć podręczną EE. Wszystko dobrze, prawda? Źle.

Jeśli przeglądana strona znajduje się w hierarchii katalogu Bazinga (aka nav-2), nagle zobaczysz:

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

Kto dodał paskudny activeciąg? Fantom jest kim.

A teraz twój stan interfejsu kończy się niepowodzeniem, ponieważ wartość atrybutu danych nie pasuje <li>już do klasy. Zapoluj na upiór.

Polowanie

  1. Najpierw sprawdzasz, czy pod pamięcią podręczną EE do zmiennej, $child->getPositionClass()której dane wyjściowe w nav-2rzeczywistości nie są dołączone inne (przypuszczalnie) wartości klasy. To nie.

  2. Sprawdzasz, czy jeden z wielu skryptów JS dekoratora Magento nie działa na liście nawigacji. To nie jest.

  3. Może to naprawdę dziwna rzecz /js/varien/menu.js. Ale już wykluczyłeś te podstawowe skrypty, jak zawsze.

  4. Może to jakiś zwariowany wbudowany JS, którego nigdy nie wiadomo, że moduł renderuje się z klasy PHP. Wyszukaj źródło strony w activeobrębie <script>tagów. Nic nie znajdziesz

  5. Może to jakiś inny zwariowany JS Magento wymaga, ale ładuje się na zewnątrz. Wyłączasz JS w przeglądarce, ale fantom żyje.

  6. Wracasz do swojej Topmenu.phpklasy i usuwasz atrybut danych. Problem ustaje. Co do cholery.

  7. Zastanawiasz się, czy inny atrybut tego samego elementu nie jest poprawnie zamknięty w cudzysłowie (hej, dzieje się tam wiele dopisywania klas). Więc zamieniasz kolejność atrybutów i usuwasz je w różnych kombinacjach. Nie ma kości. Jeśli atrybut danych jest obecny, to również fantom.

  8. Zastanawiasz się co zrobić, jeśli nie jest to klasa PHP robi czyn? Jest page_block_html_topmenu_gethtml_afterzdarzenie wywoływane przez coś innego, co może zhakować znaczniki z zewnątrz. Nic.

  9. Co. Jest. Wydarzenie. Tutaj.

Odpowiedź

Wyjaśnij to wszystkim twórcom backendu. Wszyscy zachowują się zdezorientowani. Aż do...

Brendan Falkowski
źródło

Odpowiedzi:

10

Ktoś pęka:

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

Widzisz paskudne, małe wyrażenie regularne:

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

Który pasuje do jakiegoś diabła nav-w tym <li>. Właśnie dlatego pamiętasz:

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

Magento spodziewa się znaleźć tylko nav-ciągi znaków na <li>elementach, ale wartość atrybutu danych jest dopasowywana i zhakowana. Nie chcę.

Więc użyj innej atrybutu klasy i danych, takich jak i-have-a-child-.

Upiór

Prawdziwy człowiek ma własne szczęście, Billy Zane.

Brendan Falkowski
źródło
1
„Niesamowity” problem i wyjaśnienie!
Anna Völkl,
haha wow, to jest naprawdę szalone ... W modelu pełnego modułu pamięci podręcznej strony ... przegłosowano
Erfan