Hi, I am creating a custom theme based on the Default one. I’d like to add custom classes to the <ul>
and <li>
elements of the main navigation menu. I saw the menu is built through a call to the $site->publicNav()->menu()->renderMenu(...)
function in the layout.phtml
template, but I could’nt find any documentation about this function. Is it the right way to achieve this?
Hi @boregar ,
I know you can pass in an option to add a class to the ul, but I’m not sure about the li.
<?php
echo $site->publicNav()->menu()->renderMenu(null, [
'maxDepth' => $this->themeSetting('nav_depth') - 1,
'ulClass' => 'your-class',
]);
?>
Thanks fackrellj. The ulClass
argument works and I tried to add a liClass
without success.
Anyway I need to have a finer control over the output, like conditional classes. For example, the custom classes may vary depending on the depth of the menu item, or if it has children or not etc.
Is the rendermenu
function overridable in some way? In which file is its code located?
Back after some research…
The site’s public navigation stuff is built in the /application/src/Api/Representation/SiteRepresentation.php
file using Laminas components (more info in this Laminas navigation doc).
Yes, that is correct. I wonder if you could accomplish what you need with just CSS. However, I was coming back to say that you can override the whole menu with the partial used to generate the menu Menu - laminas-navigation - Laminas Docs
That’s exactly what I am doing right now! I’ll get back with the result
Hi, the methods like setPartial() work with the $site->publicNav()->menu()
object if called this way:
echo $site->publicNav()->menu()->setPartial('...');
The Menu object has some useful methods but none of them allows to customize the classes of the menu item tags:
array(59) {
[0]=>
string(8) "__invoke"
[1]=>
string(6) "render"
[2]=>
string(10) "renderMenu"
[3]=>
string(13) "renderPartial"
[4]=>
string(23) "renderPartialWithParams"
[5]=>
string(13) "renderSubMenu"
[6]=>
string(7) "htmlify"
[7]=>
string(12) "escapeLabels"
[8]=>
string(21) "setAddClassToListItem"
[9]=>
string(21) "getAddClassToListItem"
[10]=>
string(19) "setOnlyActiveBranch"
[11]=>
string(19) "getOnlyActiveBranch"
[12]=>
string(10) "setPartial"
[13]=>
string(10) "getPartial"
[14]=>
string(16) "setRenderParents"
[15]=>
string(16) "getRenderParents"
[16]=>
string(10) "setUlClass"
[17]=>
string(10) "getUlClass"
[18]=>
string(16) "setLiActiveClass"
[19]=>
string(16) "getLiActiveClass"
[20]=>
string(6) "__call"
[21]=>
string(10) "__toString"
[22]=>
string(10) "findActive"
[23]=>
string(6) "accept"
[24]=>
string(6) "setAcl"
[25]=>
string(6) "getAcl"
[26]=>
string(6) "hasAcl"
[27]=>
string(15) "setEventManager"
[28]=>
string(15) "getEventManager"
[29]=>
string(12) "setContainer"
[30]=>
string(12) "getContainer"
[31]=>
string(12) "hasContainer"
[32]=>
string(9) "setIndent"
[33]=>
string(9) "getIndent"
[34]=>
string(11) "setMaxDepth"
[35]=>
string(11) "getMaxDepth"
[36]=>
string(11) "setMinDepth"
[37]=>
string(11) "getMinDepth"
[38]=>
string(18) "setRenderInvisible"
[39]=>
string(18) "getRenderInvisible"
[40]=>
string(7) "setRole"
[41]=>
string(7) "getRole"
[42]=>
string(7) "hasRole"
[43]=>
string(17) "setServiceLocator"
[44]=>
string(17) "getServiceLocator"
[45]=>
string(9) "setUseAcl"
[46]=>
string(9) "getUseAcl"
[47]=>
string(13) "setDefaultAcl"
[48]=>
string(14) "setDefaultRole"
[49]=>
string(17) "getClosingBracket"
[50]=>
string(7) "setView"
[51]=>
string(7) "getView"
[52]=>
string(13) "setTranslator"
[53]=>
string(13) "getTranslator"
[54]=>
string(13) "hasTranslator"
[55]=>
string(20) "setTranslatorEnabled"
[56]=>
string(19) "isTranslatorEnabled"
[57]=>
string(23) "setTranslatorTextDomain"
[58]=>
string(23) "getTranslatorTextDomain"
}
So the most promising way would be to iterate through the nodes (the “pages”) of the menu tree (the “container”) using an iterator, like in the following:
$container = $site->publicNav()->menu()->getContainer();
$iter = new RecursiveIteratorIterator($container, RecursiveIteratorIterator::SELF_FIRST);
foreach ($iter as $page) {
// render the menu item according to its depth, active status etc.
}
Hi there,
If you’d like to look at one of our themes that sets classes on the menu <li>
, you can peek at Foundation for Omeka S. In this line, it sets a partial and is able to pass parameters to it. The variables in the example are mainly to apply a class and id to the main <ul>
, but they can be anything really.
<?php echo $site->publicNav()->menu()->setPartial('common/foundation-navigation.phtml')->renderPartialWithParams(['layout' => 'vertical', 'navId' => 'main-nav']); ?>
Here is a link to the partial itself, and how it applies custom classes.
Hopefully there’s something in there that’s helpful.
Thanks kim, the code I finally wrote for my theme (built using the Bulma framework) uses a similar approach as yours (iterating through the container’s pages). I now have a nice menu