Get ready for a weird one. So I'm customizing the primary catalog navigation to build a state-full UI behavior that handles multiple interaction models (menus, dropdowns, modals, etc) across devices. Like you do.
That means overriding this class/method:
app/code/core/Mage/Page/Block/Html/Topmenu.php :: _getHtml()
To produce HTML output like this (somewhat simplified):
<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>
Now, this is pretty boring/standard except for the data-ui-action
attribute. That's where the JS magic happens. Any clicks on elements with that attribute update the UI state. You guessed it, the li.nav-X
class (which Magento adds) acts as my hook to bind the UI state to the activated element.
All good, right? Turn on EE cache. All good right? Wrong.
If the page you're viewing is within the catalog hierarchy of Bazinga (aka nav-2
), then suddenly you will see this:
data-ui-action="nav-2 active"
Who added the nasty active
string? The phantom is who.
And now your UI state fails, because the data attribute's value doesn't match the <li>
class anymore. Hunt down the phantom.
The Hunt
First, you check that under EE cache the variable
$child->getPositionClass()
which outputsnav-2
doesn't actually have other (presumably) class values appended. It does not.You check that one of Magento's many decorator JS scripts isn't executing on the nav list. It's not.
Maybe it's actually some odd thing in
/js/varien/menu.js
. But you already excluded those core scripts like you always do.Maybe it's some crazy inline JS you'd never know a module renders out of the PHP class. Search the page source for
active
within<script>
tags. You find nothing.Maybe it's some other crazy JS Magento requires but loads externally. You disable JS in the browser, but the phantom lives.
You go back to your
Topmenu.php
class and remove the data attribute. The problem stops. What the hell.You wonder if another attribute on the same element isn't properly quote-closed (hey, lots of class appending happens in there). So you swap the order of attributes and remove them in various combination. No dice. If the data attribute is present, so is the phantom.
You wonder what if it's not this PHP class doing the deed? There's a dispatched
page_block_html_topmenu_gethtml_after
event something else might use to hack over the markup from beyond. Nothing.What. Is. Happening. Here.
The answer
Explain all that to the backend devs. Everyone act confused. Until...