Add Dropdowns to Main Menu Through the Site Admin (Copy & Paste into Site Header/Footer Injections)

Hey @denvergeeks,

I fortuitously came across this just yesterday thanks to @Cathy_Sarisky’s mention of it (thanks!) at the very moment that I needed it (I must have skipped over it when you first posted it as not applicable to me). And wow, talk about fantastic! I wouldn’t have imagined one could do this with the in-built navigation, but I guess if you know JS you can do “anything” you want.

Anyhow, although I’d hard-code submenus into my personal theme if needed and adjust from there, I’m currently putting together a site and theme for a colleague who I’d prefer to be able to edit these submenus himself via the admin. But not only am I setting things up with Edition rather than Casper, but I’ve also created custom nav menus with custom classes. Suffice to say, the dropdown script doesn’t work at all and the subitems appear as regular (parent) menu items in the nav.

I tried looking through the JS (which I don’t know in the slightest) and couldn’t decipher what I needed to change. Any chance you could let me know which selectors I need to customise?

Thanks again for this!

@Stromfeldt , do you have jQuery loading? This solution uses jQuery, but it doesn’t seem to load in my theme. (I loaded up Edition, pasted in the code injection above, and then checked my console log to see the problem.)

Ah, great question. I tend to go overboard with JS and thus jQuery on my other themes, and just assumed it was included – which it wasn’t. Thanks!

Regardless, inserting jQuery just before the mentioned JS resulted in nothing else besides re-aligning things a bit (strangely enough).

EDIT: No, wait, I see something appearing on mobile (but not desktop)! Let me play around…

So for some reason the nav on my desktop view disappears when adding the jQuery, but when I shrink down the browser to mobile width I can see the nav. I’ll have to look into that.

Otherwise, it seems that the script is activated and doing something, but I probably have the selectors incorrect as the script isn’t assigning the subitems to the parents.

This is what happens when I hover over the parent item:

I got it working on my demo site (yes, with Edition).

I did get it working, although styling wasn’t perfect. Here’s what I had. YMMV depending on whether your menu is transparent and desired colors. (Prior to changes I had white on white - ugh!)

ul.ghost-submenu li {
    list-style: none;
    white-space: nowrap;
    margin-left: 0px !important;
}

ul.ghost-submenu {
    border-radius: 5px;
    position: absolute;
    visibility: hidden;
    z-index: 1;
    opacity: 0;
    top: 30px;
    transition: 0.3s;
    box-shadow: 0 1px 5px 0 rgb(0 0 0 / 14%);
    max-width: unset !important;
    
    /* Edit below to adjust Dropdown Menu positioning and color */
    left: 0;
    margin-top: -15px;
    padding: 5px 20px 10px 10px;
    background: #000;
    color: #fff;
}

I’m not seeing what you’re seeing with dropdown menus (unless I have too many other items and it goes into the …, in which case things get weird).
Not hovered:


Hovered:

I didn’t change any selectors, but there’s a lot going on with the nav in this theme (the …, the transparent or not setting), so YMMV!

1 Like

You’re correct. I tried substituting vanilla Edition for my customised Edition, as well as removed all of my custom CSS in code injection, and the dropdown nav fully works on both desktop and mobile.

Even without this issue I’ve admittedly kind of butchered Edition, which actually fully works except for this. Time to work backwards and see if I can isolate the issue.

Thanks very much for clearing this up for me!

1 Like

I’m happy to help anywhere I can. I’ll need links to live installs where I can tinker in the code inspector!

2 Likes

Thanks very much for the offer but… I got it!

I’d placed the <ul><li></li></ul> structure of the nav inside another <ul><li></li></ul> structure, which I kinda knew was asking for trouble when I did it even though it seemed to work fine at the time. But when I later discovered your dropdown menu script and then applied it I’d forgotten that I’d included that sloppy code – which obviously was gonna cause conflicts.

Anyway, I’m re-coding things now in a more proper manner.

Thanks to both of you @denvergeeks and @Cathy_Sarisky! (If you’d like I’ll DM you with the site’s link once it’s live if you want to see the script in the wild.)

Of course! I’d love to see what you’ve done!

1 Like

Hello @themeix, I somehow missed out on the fact that the script is originally yours. Thanks for this, very interesting approach! I’ve got a bit of a bug though, so thought I might throw it by you.

I’ve got everything working fine, except that when the home page is initially loaded, and when one navigates to any other page/post (or simply reloads the site), the submenus flash below / next to the nav momentarily. And it’s not just my implementation of the script – if you look at any of the other attempts above they all do the same thing, albeit to different degrees (see here and here). My implementation is even worse, possibly because there’s many more subitems (I can DM you with a link and password if you’re interested).

I took a look at your Learn theme, which appears to use the same script, and which doesn’t flash. I also saw on the script’s repo mentioned above that the most recent commit (from over a year ago) is one that includes “fix menu flash issue”, but which doesn’t seem to fix this flash issue. I decided to try and copy and paste the related JS from Learn and replace the JS mentioned in your repo with it, but that just made the whole thing inoperable (it’s possible I copied/pasted incorrectly, but I don’t think so).

Is there any chance that you’ve made a further fix to the script that you’d be willing to share?

Thanks again for this!

2 Likes

Also, I made a few adjustments to the CSS and how to set up the links on the dashboard’s navigation page.

First off, if you don’t want a click on a parent item to result in a redirect to the homepage, substitute http://localhost:2368/#! or https://yourdomain.com/#! with simply #.

Secondly, if you don’t want the cursor to appear as a pointer when hovering over the parent but do when it hovers over the children, add in this:

.menu-item-has-children a:hover {
    cursor: default;
}
.menu-item-has-children ul li a:hover {
    cursor: pointer;
}
2 Likes

I suspect that the flash is somewhat unavoidable with this approach. Ghost renders the menu with all the items, and then the code injection rearranges it to make the drop-downs. So it becomes a question of how fast the code injection can do that, and does the user notice it visually or not. On my super fast internet at work, I see no flashes on one of your examples, and the barest hint of a wiggle on the second one. But if you’re on less speedy internet and the redraw doesn’t happen until the browser downloads a copy of jQuery and then runs your code injection, then yeah, it’s probably going to visibly rearrange.

Hopefully themeix will reply, but from inspecting the Learn theme demo, it looks like he starts the menu with opacity: 0 (making it invisible) [I’m guessing this is in the .hbs file], then sets it to opacity: 1 when the code injection is done. So instead of changing layouts (‘flashing’) when the code injection runs, the menu rearranges while invisible, then appears.

I don’t think the primary issue is the speed of the Internet connection so much as it is how many child items you have. If you have just one child item perhaps just a few things will shift to the right, almost imperceptibly. If you have many child items then not only might things to their right shift over but all page material below will jerk down for a moment, as is happening in my case. It looks really bad.

Yeah, that’s essentially what I gathered as well. So for it to “work” means the menu must inherently fade in. Better, but perhaps not ideal, particularly if your menu isn’t at the very top of the page.

Neat idea for allowing customizable dropdowns via the admin, but due to the fact that Ghost renders the nav items before the script can rearrange it all I think I may just revert to hard-coding the menu into the theme.

I have the same problem as @thedansmock, I can select only the first subitem, the moment I try to hover over the second one the menu closes itself.
I’m using the current casper version (v5.3.1) and have not modified the theme in any way apart from a few changes in the “Settings”-screen of the theme (like removing the publication cover). Nor am I using any other code injections, so that can’t be the problem either. I also am just working on my local PC right now, the site isn’t online yet.
What I have noticed, however, is that it seems to break the moment I’m linking to at least one post and not just pages in the submenu. Is there a way around this that doesn’t involve turning all the posts into pages?

Update: I found out that I have actually mentioned the important change I made: I removed the publication cover. As long as there is one (it doesn’t matter that whether it’s the standard one) the menu works as intended, the moment I remove it, I can only select the first subitem. Anyone has any idea why?

This sounds like a problem with the css selector. Maybe check the structure of that part of the page - is it a nav containing ul li elements? Can you link a page with the broken behavior (if it isn’t running on localhost)? Or provide access to the broken code?

As I mentioned, it’s running on localhost, so I can’t simply link it. For your second suggestion, I’m not even remotley experienced at website development, but if I use the page inspector I get the following code for the dropdown menu (and it’s the same, no matter whether the dropdown menu works or not):

<ul class="nav ghost-dropdown-menu">
    <li class="nav-startseite nav-current" style="opacity: 1;">
    	<a href="http://localhost:2368/">Startseite</a>
    </li>
    <li class="nav-uber-uns" style="opacity: 1;">
    	<a href="http://localhost:2368/about/">Über uns</a>
    </li>
    <li class="nav-beitrage-has_child nav-current menu-item-has-children" style="opacity: 1;">
    	<a href="http://localhost:2368/#!">Beiträge </a>
    	<ul class="ghost-submenu">
    		<li class="nav-wiktionary-subitem subitem" style="opacity: 1;">
    			<a href="http://localhost:2368/wiktionary/">Wiktionary </a>
    		</li>
    		<li class="nav-das-ischtar-tor-subitem subitem" style="opacity: 1;">
    			<a href="http://localhost:2368/das-ischtar-tor/">Das Ischtar Tor </a>
    		</li>
    		<li class="nav-die-buste-der-nofretete-subitem subitem" style="opacity: 1;">
    			<a href="http://localhost:2368/die-bueste-der-nofretete/">Die Büste der Nofretete </a>
    		</li>
    		<li class="nav-agyptisches-erbe-in-museen-subitem subitem" style="opacity: 1;">
    			<a href="http://localhost:2368/aegyptischeserbe/">Ägyptisches Erbe in Museen </a>
    		</li>
    	</ul>
    	<svg xmlns="http://www.w3.org/2000/svg" width="11" height="7" fill="currentColor" class="bi bi-caret-down" viewBox="0 0 11 7">
    		<path d="M5.4999 6.20003L0.649902 1.35003L1.3499 0.650024L5.4999 4.80002L9.6499 0.650024L10.3499 1.35003L5.4999 6.20003Z"></path>
    	</svg>
    </li>   
</ul>

But as I said, I haven’t changed any of the .hbs-files of the theme nor have I injected any code (either for the theme files or just for one page), so it really shouldn’t be broken.

If you are so inclined to fully understand the drop-down menu approach here, @themeix.official has provided the method in several themes. Not free, but certainly an economical and re-usable solution that can be incorporated into any other theme with a bit of copy-and-paste coding.

As examples:

and

These two themes demonstrate both a basic drop-down menu as well as a mega-menu in Ghost themes.

I am sure that many of the theme-builders here on the forums can integrate such features into any theme!

As highlighted above, this is an imperfect solution that does not work with all themes, requires some coding knowledge and even when it does work, often shows the code whilst the page is loading.

If anyone would like to see dropdown menus added as a feature by Ghost, you can vote for it here.