dlen Posted April 30, 2016 Share Posted April 30, 2016 Hi there, i just want to share the code of what the subject line says. The pages to appear in the menu have a custom field "in_main_menu" of type checkbox checked. The item <li>s of the actually shown page and in the direttissima upwards - except home - get the class "current". The item <ul>s of submenus get the class "submenu". This is basically Ryans Code from here run through a meatgrinder. I hope useful for any beginners like me looking for a solution to a similar problem. Any improvement welcome! Now the code: /** * A recursive menu containing home. (It is added to the list of menu items while $level =1). * In order to be included, a page must have a custom field "in_main_menu" of type "checkbox", * and the latter has to be checked. * All submenu <ul>s get class "submenu". * All <li>s in the direttissima upwards of the page shown - except home - get the class "current". * Takes $root out of the recursion in order to not have all pages twice. * All menu items, that have children, do not have a link to their content, but act merely as switches. * You can switch this behaviour off by replacing * * $href = ( $item == $root || !$item->numChildren ? "$item->url" : "#" ); * * with * * $href = $item->url; * * Or you can make it conditional by querying a second custom field "has_own_page", e.g. * * $href = ( $item == $root || !$item->numChildren || $item->has_own_page ? "$item->url" : "#" ); * * Intended to be used without arguments, i.e. "selectiveMenu();" , i.e. always starting with site root. */ function selectiveMenu(Page $root = null) { $shownPage = wire('page'); if(is_null($root)) $root = wire('pages')->get('/'); $level = count($root->parents); $ul_class_string = (($level > 0) ? "class='submenu'" : ""); $out = "\n<ul {$ul_class_string}>"; $parents = $shownPage->parents; $items = $root->children; if ($level == 0) $items->prepend($root); foreach( $items as $item) { if ($item->in_main_menu) { $s = ''; $li_class_string = ( ( $parents->has($item) && $item !== $root ) || $item === $shownPage ? "class='current'" : "" ); if($item->numChildren && $item !== $root) { $s = str_replace("\n", "\n\t\t", selectiveMenu($item)); } $href = ( $item == $root || !$item->numChildren ? "$item->url" : "#" ); $out .= "\n\t<li {$li_class_string}>\n\t\t<a href='{$href}'>{$item->title}</a>$s\n\t</li>"; } } $out .= "\n</ul>"; return $out; } 1 Link to comment Share on other sites More sharing options...
dlen Posted June 1, 2016 Author Share Posted June 1, 2016 An updated version with some more features /** * A recursive menu containing home. * If no root page is given, site root will be taken. * If and only if the second parameter is given, only pages will be included, that have a custom field of type "checkbox", * and the latter has to be checked. This field is the parameter to be given. Example with field "in_main_menu": * * selectiveMenu(null, $fields->in_main_menu); * * All submenu <ul>s get class "submenu". * All <li>s in the direttissima upwards of the page shown - except home - get the class "current". * All menu items, that have the template name 'no_content' do not have a link to their content, but act merely as switches * to their subpages. This template must have also the selector field, if the parameter is given. * * Intended to be used without arguments, i.e. "selectiveMenu();" , i.e. always starting with site root. * * @param Page root page of the menu * @param Field menu_selector_field pages with this "checkbox" field in their template set to "checked" are represented * @param string menu_id The id the outermost ul - tag gets. * @return string */ function selectiveMenu(Page $root = null, Field $menu_selector_field = null, $menu_id = null) { $shownPage = wire('page'); if(is_null($root)) $root = wire('pages')->get('/'); $level = count($root->parents); $ul_class_string = (($level > 0) ? "class='submenu'" : ""); $ul_id_string = ($menu_id ? "id='$menu_id'" : ""); $out = "\n<ul {$ul_class_string} {$ul_id_string}>"; $parents = $shownPage->parents; $items = $root->children; if ($level == 0) $items->prepend($root); foreach( $items as $item) { if ($item->$menu_selector_field || !$menu_selector_field) { $s = ''; $li_class_string = ( ( $parents->has($item) && $item !== $root ) || $item === $shownPage ? "class='current'" : "" ); if($item->numChildren(true) && $item !== $root) { $s = str_replace("\n", "\n\t\t", selectiveMenu($item, $menu_selector_field)); } $href_attr = ( $item == $root || $item->template->name != 'no_content' ? "href='$item->url'" : "" ); $out .= "\n\t<li {$li_class_string}>\n\t\t<a $href_attr>{$item->title}</a>$s\n\t</li>"; } } $out .= "\n</ul>"; return $out; } Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now