menumain is the menu in question, and above is it’s required include position in the markup. The menu displays correctly, but there is no “Edit Menu” button displayed in the CMS, which is a problem.
If I simply move the hst tag outside of the header tag, the menu is displayed in the wrong place, but now the “Edit Menu” button displays as expected.
Are you sure the menu button isn’t in the markup at all? It should be a div with class “hippo-overlay-element-menu-link” located in a generated div at the bottom of the body with class “hst-overlay”.
Did you change the default markup of the EssentialsMenuComponent in any way? The default markup puts the button inside a div with class “has-edit-button” [1], for which the default CSS which sets “position: relative” [2] so the button is positioned relative to that div [3].
The “menumain” parent components seems to be a container. What’s the hst:xtype property of that container?
Your second point made me realise that the adding of the button to the page is happening with JavaScript, not server rendered by the <@hst.cmseditmenu menu=menu /> tag as I initially thought, so I took a step back and disabled my own custom JavaScript on the page completely, and that now shows the Edit Menu button as expected. So something in my own JavaScript is causing it to not render. I will slowly start adding my own code back, to find what the cause is.
Thanks for helping out.
For completeness, I’ll still answer your questions.
I did an inspect in my Chome developer tools, and “hippo-overlay-element-menu-link” was not found. I did however find an empty “hst-overlay” class div.
I did change the default EssentialsMenuComponent, and the “has-edit-button” div was indeed removed, but adding it back and also replacing my markup completely with the default EssentialsMenuComponent markup did not solve the issue. This point did however steer me in the right direction.
The hst:xtype property for the container is hst.vbox
Your second point made me realise that the adding of the button to the page is happening with JavaScript, not server rendered by the <@hst.cmseditmenu menu=menu /> tag as I initially thought, so I took a step back and disabled my own custom JavaScript on the page completely, and that now shows the Edit Menu button as expected. So something in my own JavaScript is causing it to not render. I will slowly start adding my own code back, to find what the cause is.
Interesting! The overlay markup is indeed generated by JavaScript. Once the initial page load in the iframe is done (i.e. when the iframe element emits the ‘load’ event) the DOM in the iframe is searched for server-side generated HTML comments that contain certain meta-data in the form of JSON. These comments mark certain DOM elements as being a container, a component, “insert menu button here” etc. If the hippo-overlay div is empty it means this parsing did not happen for some reason.
Some question to pinpoint where it goes wrong:
does the contain a link element like this? (the host name and hash number in the file may be different)
does your JavaScript define a global object “window.SPA”? If so the Channel Manager thinks you channel renders an SPA (e.g. some React app), which requires a specific integration.
I was able to pin down exactly why and where in my custom JS this is happening, but the situation is probably very unique to my use case.
Part of the menu bar that contains the HST Menu also contains some customer details like the customer’s name, etc. These customer details do not come from the CMS though, I get it from an external REST service and then rendered into the menu bar using VueJS.
What I think what is happening is that the DOM is then modified twice; first by by the CMS after the ‘load’ event you mention, and then again when data is received from the external service by the Vue framework. So the CMS is working correctly and adding the edit button, but the second DOM modification seems to be what is removing button again.
Changing my template markup slightly so that Vue only targets very specific elements and not the HST menu solved the issue while keeping my cutomer detail section intact.
I have now fully solved my issue, while still keeping my template as I initially wanted it. Even though my situation is fairly unique, I thought I’ll add what I found here to fully close the loop, in case it might help someone else down the road.
I had to dig into both the Channel Manager JavaScript and the framework I’m using on top my my site (VueJS), to understand the problem. The problem was actually twofold.
Firstly, with VueJS you add an HTML id to an parent element that needs to be reactive to the data. Vue internally creates a virtual DOM that it then after doing it’s thing renders back in place of the original parent element and it’s children. By default any comments is removed in this process, which was causing the first problem, as it was removing the Hippo generated comments with meta data. Luckily the framework comes with an option to preserve comments, so that was a simple fix once I figured it out.
That however then highlighted a second issue caused by my own menu CSS. My menu items are inline elements, and I placed the Edit Menu button container in oneof these menu items. Within the Channel Manager JavaScript there is an OverlayService class, which has a _getElementPosition method. In this method it gets the size and coordinates of the button container, in order to place the Edit Button relative to it. Since the element was an inline element, the size and coordinates was returned as 0, which was then applied to the button, thus caused it not to display on the page. The fix was to change the CSS of my menu items to be block elements instead.