We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 22303 MODX Staff
    • 10,725 Posts
    Below is a new version of the DropMenu snippet Ryan and I used to build all the menus for the MODx CMS site. Please take a look and see if you can find any bugs or might have any suggestions for improving this before we decide to include it as the default menu snippet in future releases.

    Latest features include the addition of menutitle to list of available fields to use for link text or title, exclusion of documents not marked with the Show in Menu flag, configurable classes for top level and nested elements, optional DIV containers that can be used to create hover zones, and more.

    Here are all the available snippet parameters:

    $menuName [ string ] - Sets the name of the menu, including the placeholder, and top level DIV id (if topdiv option is true)
    $startDoc [int] - The parent ID of your menu. Default 0: [[DropMenu?startDoc=10]]
    $textOfLinks [ string ] - The database field you want the text of your links to be. The default is menutitle, but if you prefer it can be any of the following: id, pagetitle, description, parent, alias, longtitle, introtext
    $removeNewLines [ true | false ] - If you want new lines removed from code. Default is false, But it is generally better for IE when lists are styled vertically if it is set to true
    $levelLimit [ int ] - Maximum number of levels to include. The default 0 will allow all levels. Example: [[DropMenu?levelLimit=2]]
    $showDescription [true | false] - Specify if you would like to include the description next to each link. Default is false
    $titleOfLinks [ string ] - Field used to populate the link title attributes. The default is description, but if you prefer it can be any of the following: menutitle, id, pagetitle, description, parent, alias, longtitle, introtext
    $selfAsLink [ true | false ] - Define if the current page should be a link (true) or not (false)
    $topdiv [ true | false ] - Indicates if the top level UL is wrapped by a containing DIV block
    $topdivClass [ string ] - CSS Class for DIV wrapping top level UL
    $topnavClass [ string ] - CSS Class for top level UL
    $subdiv [ true | false ] - Indicates if nested UL’s should be wrapped by containing DIV blocks
    $subdivClass [ string ] - CSS Class for DIV blocks wrapping nested UL elements
    $subnavClass [ string ] - CSS Class for nested UL’s
    $hereClass [ string ] - CSS Class for LI and A when they are the currently selected page, as well as any ancestors of the current page (YOU ARE HERE)
    $pre [ string ] - Text to append before links inside of LIs
    $post [ string ] - Text to append before links inside of LIs
    $orderBy [ string ] - Document field to sort menu by
    $orderDesc [true | false] - Order results in descending order? Default is false

    And here is the code (code is also in attachment, but note the PHP tags are in the file if you copy and paste the code into a snippet):
    // ###########################################
    // DropMenu                                  #
    // ###########################################
    // Configurable menu / navigation builder using UL tags
    // Offers optional DIV wrappers for top level and nested menus (useful for hover zones)
    // as well as configurable classes for the DIV, UL, and LI elements.  It even
    // marks ancestors of and the current element with a hereClass (indicating you are here 
    // and in this area of the site).  Also applies .last CSS class to final LI in each UL.
    //
    // Developed by Vertexworks.com and Opengeek.com
    // Feel free to use if you keep this header and credits in place
    //
    // Inspired by List Site Map by Jaredc, SimpleList by Bravado, 
    // and ListMenuX by OpenGeek
    
    // ###########################################
    // Usage Examples                            #
    // ###########################################
    // Creates menu with wrapping DIV with id=myMenu, starting at the site root, two levels deep,
    // with descriptions next to the links, and nested UL elements with class=nestedLinks; output
    // of menu can be placed in layout using placeholder named myMenu ( e.g. [ +myMenu+ ] )
    // [ [DropMenu?menuName=myMenu&startDoc=0&levelLimit=2&topdiv=true&showDescription=true&subnavClass=nestedLinks] ]
    //
    // Creates topMenu from site root, including only 1 level, with class=topMenubar applied to the top level UL
    // and class=activeLink applied to current page LI
    // [ [DropMenu?menuName=topMenu&startDoc=0&levelLimit=1&topnavClass=topMenubar&here=activeLink] ]
    //
    // Creates dropmenu 3 levels deep, with DIV wrappers around all nested lists styled with class=hoverZone
    // and currentPage LI styled with class=currentPage
    // [ [DropMenu?levelLimit=3&subdiv=true&subdivClass=hoverZone&subnavClass=menuZone&here=currentPage] ]
    //
    // Creates dropmenu of infinite levels, ordered by menutitle in descending order
    // [ [DropMenu?orderBy=menutitle&orderDesc=true] ]
    
    // ###########################################
    // Configuration parameters                  #
    // ###########################################
    // $menuName [ string ]
    // Sets the name of the menu, placeholder, and top level DIV id (if topdiv option is true)
    $menuName = (empty($menuName)) ? 'dropmenu' : "$menuName";
    
    // $siteMapRoot [int]
    // The parent ID of your root. Default 0. Can be set in 
    // snippet call with startDoc (to doc id 10 for example):
    // [[DropMenu?startDoc=10]]
    $siteMapRoot = 0;
    
    // $titleOfLinks [ string ]
    // What database field do you want the title of your links to be?
    // The default is pagetitle because it is always a valid (not empty)
    // value, but if you prefer it can be any of the following:
    // menutitle, id, pagetitle, description, parent, alias, longtitle, introtext
    $textOfLinks = (empty($textOfLinks)) ? 'menutitle' : "$textOfLinks";
    
    // $removeNewLines [ true | false ]
    // If you want new lines removed from code, set to true. This is generally
    // better for IE when lists are styled vertically. 
    $removeNewLines = (!isset($removeNewLines)) ? false : ($removeNewLines==true);
    
    // $maxLevels [ int ]
    // Maximum number of levels to include. The default 0 will allow all
    // levels. Also settable with snippet variable levelLimit:
    // [[DropMenu?levelLimit=2]]
    $maxLevels = 0;
    
    // $showDescription [true | false]
    // Specify if you would like to include the description
    // with the page title link.
    $showDescription = (!isset($showDescription)) ? false : ($showDescription==true);
    
    // $titleOfLinks [ string ]
    // What database field do you want the title of your links to be?
    // The default is pagetitle because it is always a valid (not empty)
    // value, but if you prefer it can be any of the following:
    // menutitle, id, pagetitle, description, parent, alias, longtitle, introtext
    $titleOfLinks = (empty($titleOfLinks)) ? 'description' : "$titleOfLinks";
    
    // $selfAsLink [ true | false ]
    // Define if the current page should be a link (true) or not (false)
    $selfAsLink = (!isset($selfAsLink)) ? false : ($selfAsLink==true);
    
    // $topdiv [ true | false ]
    // Indicates if the top level UL is wrapped by a containing DIV block
    $topdiv = (!isset($topdiv)) ? false : ($topdiv==true);
    
    // $topdivClass [ string ]
    // CSS Class for DIV wrapping top level UL
    $topdivClass = (empty($topdivClass)) ? 'topdiv' : "$topdivClass";
    
    // $topnavClass [ string ]
    // CSS Class for top level UL
    $topnavClass = (empty($topnavClass)) ? 'topnav' : "$topnavClass";
    
    // $subdiv [ true | false ]
    // Indicates if nested UL's should be wrapped by containing DIV blocks
    $subdiv = (!isset($subdiv)) ? false : ($subdiv==true);
    
    // $subdivClass [ string ]
    // CSS Class for DIV blocks wrapping nested UL elements
    $subdivClass = (empty($subdivClass)) ? 'subdiv' : "$subdivClass";
    
    // $subnavClass [ string ]
    // CSS Class for nested UL's
    $subnavClass = (empty($subnavClass)) ? 'subnav' : "$subnavClass";
    
    // $hereClass [ string ]
    // CSS Class for LI and A when they are the currently selected page, as well
    // as any ancestors of the current page (YOU ARE HERE)
    $hereClass = (empty($hereClass)) ? 'here' : $hereClass;
    
    // $pre [ string ]
    // Text to append before links inside of LIs
    $pre = (empty($pre)) ? '' : "$pre";
    
    // $post [ string ]
    // Text to append before links inside of LIs
    $post = (empty($post)) ? '' : "$post";
    
    // $orderBy [ string ]
    // Document field to sort menu by
    $orderBy = (empty($orderBy)) ? 'menuindex' : "$orderBy";
    
    // $orderDesc [true | false]
    // Order results in descending order?  default is false
    $orderDesc = (!isset($orderDesc)) ? false : ($orderDesc==true);
    
    // ###########################################
    // End config, the rest takes care of itself #
    // ###########################################
    
    // Initialize
    $MakeMap = "";
    $siteMapRoot = (isset ($startDoc)) ? $startDoc : $siteMapRoot;
    $maxLevels = (isset ($levelLimit)) ? $levelLimit : $maxLevels;
    $ie = ($removeNewLines) ? '' : "\n";
    
    // Overcome single use limitation on functions
    global $MakeMap_Defined;
    
    if (!isset ($MakeMap_Defined)) {
    	function filterHidden($var) {
    		return (!$var['hidemenu']==1);
    	}
    	function MakeMap($callBy, $listParent, $listLevel, $description, $titleOfLinks, $maxLevels, $inside, $pre, $post, $selfAsLink, $ie, $activeLinkIDs, $topdiv, $topdivClass, $topnavClass, $subdiv, $subdivClass, $subnavClass, $hereClass, $textOfLinks, $orderBy, $orderDesc) {
    
    		$children = $callBy->getActiveChildren($listParent, $orderBy, (!$orderDesc) ? 'ASC' : 'DESC', 'id, pagetitle, description, isfolder, parent, alias, longtitle, menutitle, hidemenu, introtext, content_dispo, contentType, type');
    
    		if (is_array($children) && !empty ($children)) {
    
    			$children = array_filter($children, "filterHidden");
    			$numChildren = count($children);
    			// determine if it's a top category or not
    			$toplevel = !$inside;
    			$topdivcls = (!empty ($topdivClass)) ? ' class="'.$topdivClass.'"' : '';
    			$topdivblk = ($topdiv) ? "<div$topdivcls>" : '';
    			$topnavcls = (!empty ($topnavClass)) ? ' class="'.$topnavClass.'"' : '';
    			$subdivcls = (!empty ($subdivClass)) ? ' class="'.$subdivClass.'"' : '';
    			$subdivblk = ($subdiv) ? "<div$subdivcls>$ie" : '';
    			$subnavcls = (!empty ($subnavClass)) ? ' class="'.$subnavClass.'"' : '';
    			$output = ($toplevel) ? "$topdivblk<ul$topnavcls>$ie" : "$ie$subdivblk<ul$subnavcls>$ie";
    
    			//loop through and process subchildren
    			foreach ($children as $child) {
    				// figure out if it's a containing category folder or not 
    				$numChildren --;
    				$isFolder = $child['isfolder'];
    				$itm = "";
    
    				if (!$inside) {
    					$itm .= (!$selfAsLink && ($child['id'] == $callBy->documentIdentifier)) ? $pre.$child[$textOfLinks].$post : '<a href="[~'.$child['id'].'~]" title="'.$child[$titleOfLinks].'">'.$pre.$child[$textOfLinks].$post.'</a>';
    				}
    				elseif ($isFolder && $inside) {
    					$itm .= '<a href="[~'.$child['id'].'~]" title="'.$child[$titleOfLinks].'">'.$child[$textOfLinks].'</a>';
    				} else {
    					$itm .= ($child['alias'] > '0') ? '<a href="[~'.$child['id'].'~]" title="'.$child[$titleOfLinks].'">'.$child[$textOfLinks].'</a>' : '<span>'.$child[$textOfLinks].'</span>';
    				}
    
    				// loop back through if the doc is a folder and has not reached the max levels
    				if ($isFolder && (($maxLevels == 0) || ($maxLevels > $listLevel +1))) {
    					$itm .= MakeMap($callBy, $child['id'], $listLevel +1, $description, $titleOfLinks, $maxLevels, true, $pre, $post, $selfAsLink, $ie, $activeLinkIDs, $topdiv, $topdivClass, $topnavClass, $subdiv, $subdivClass, $subnavClass, $hereClass, $textOfLinks, $orderBy, $orderDesc);
    				}
    
    				if ($itm && !$selfAsLink && ($child['id'] == $callBy->documentIdentifier)) {
    					$output .= "    <li class=\"$hereClass". ($numChildren == 0 ? ' last' : '')."\">$itm</li>$ie";
    				}
    				elseif ($itm) {
    					if ($numChildren == 0) {
    						$class = 'last';
    					}
    					if (is_array($activeLinkIDs)) {
    						if (in_array($child['id'], $activeLinkIDs)) {
    							$class .= ($class ? ' ' : '').'here';
    						}
    					}
    					if ($class) {
    						$class = ' class="'.$class.'"';
    					}
    					$output .= "<li$class>$itm</li>$ie";
    					$class = '';
    				}
    			}
    			$output .= "</ul>$ie";
    			$output .= ($toplevel) ? (($topdiv) ? "</div>$ie" : "") : (($subdiv) ? "</div>$ie" : "");
    		}
    		return $output;
    	}
    	$MakeMap_Defined = true;
    }
    
    $currentID = $modx->documentIdentifier;
    $parentID = $currentID;
    
    // find the parent docs of the current "you-are-here" doc
    // used in the logic to mark parents as such also
    while ($parentID != $siteMapRoot && $parentID != 0) {
    	$parent = $modx->getParent($parentID, 0);
    	if ($parent) {
    		$parentID = $parent['id'];
    		$activeLinkIDs[] = $parentID;
    	} else {
    		$parentID = 0;
    	}
    }
    
    $modx->setPlaceholder($menuName, MakeMap($modx, $siteMapRoot, 0, $showDescription, $titleOfLinks, $maxLevels, false, $pre, $post, $selfAsLink, $ie, $activeLinkIDs, $topdiv, $topdivClass, $topnavClass, $subdiv, $subdivClass, $subnavClass, $hereClass, $textOfLinks, $orderBy, $orderDesc));
    


    Note that I made this version use a placeholder to assign the menu output, but we can easily make this optional, so it will return the output directly from the snippet or via a placeholder, depending on user preferences.

    I’ll release this and prepare it for inclusion in the installer for future versions once I get a little feedback on it.

    Cheers...
      • 25663 MODX Staff
      • 12,272 Posts
      Thanks for the update... just what the doctor ordered!

      Not updated on the site yet?
        Ryan Thrash, MODX Co-Founder
        Follow me on Twitter at @rthrash or catch my occasional unofficial thoughts at thrash.me
        • 22303 MODX Staff
        • 10,725 Posts
        Quote from: rthrash at Aug 27, 2005, 08:24 AM

        Thanks for the update... just what the doctor ordered!

        Not updated on the site yet?

        No, thought I’d find some time to test it a little more thoroughly, and get some feedback before I go changing any configurations on the site accordingly. ;-)
          • 25663 MODX Staff
          • 12,272 Posts
          We need to make this snippet not render empty ULs, not render pages that are deleted, and also consider creating a new config option:

          + $noLinkOnEmpty [ boolean ] -- skip pages with no content in the content field (default true)

          This would functionally the same as self-as-link being turned off, and quite useful for creating category headings in sites navigation lists. We also might think about passing an array of content + TVs as an optional thing to check in case some folks don’t use content as their main content field.

            Ryan Thrash, MODX Co-Founder
            Follow me on Twitter at @rthrash or catch my occasional unofficial thoughts at thrash.me
            • 25663 MODX Staff
            • 12,272 Posts
            Here’s the current code from pixelhick.com, for ease of reference:

            // ###########################################
            // DropMenu                                  #
            // ###########################################
            // Configurable menu / navigation builder using UL tags
            // Offers optional DIV wrappers for top level and nested menus (useful for hover zones)
            // as well as configurable classes for the DIV, UL, and LI elements.  It even
            // marks ancestors of and the current element with a hereClass (indicating you are here 
            // and in this area of the site).  Also applies .last CSS class to final LI in each UL.
            //
            // Developed by Vertexworks.com and Opengeek.com
            // Feel free to use if you keep this header and credits in place
            //
            // Inspired by List Site Map by Jaredc, SimpleList by Bravado, 
            // and ListMenuX by OpenGeek
            //
            // Configuration parameters:
            // 
            // &menuName        - name of a placeholder for placing the output in the layout
            // &topnavClass     - CSS class for styling the class assigned to the outermost UL
            
            // ###########################################
            // Usage Examples                            #
            // ###########################################
            // Creates menu with wrapping DIV with id=myMenu, starting at the site root, two levels deep,
            // with descriptions next to the links, and nested UL elements with class=nestedLinks; output
            // of menu can be placed in layout using placeholder named myMenu ( e.g. [ +myMenu+ ] )
            // [[DropMenu? &menuName=`myMenu` &startDoc=`0` &levelLimit=`2` &topdiv=`true` &showDescription=`true` &subnavClass=`nestedLinks`]]
            //
            // Creates topMenu from site root, including only 1 level, with class=topMenubar applied to the top level UL
            // and class=activeLink applied to current page LI
            // [[DropMenu? &menuName=`topMenu` &startDoc=`0` &levelLimit=`1` &topnavClass=`topMenubar` &here=`activeLink`]]
            //
            // Creates dropmenu 3 levels deep, with DIV wrappers around all nested lists styled with class=hoverZone
            // and currentPage LI styled with class=currentPage
            // [[DropMenu? &levelLimit=3 &subdiv=true &subdivClass=hoverZone &subnavClass=menuZone &here=currentPage]]
            //
            // Creates dropmenu of infinite levels, ordered by menutitle in descending order
            // [[DropMenu?orderBy=menutitle&orderDesc=true]]
            
            // ###########################################
            // Configuration parameters                  #
            // ###########################################
            // $menuName [ string ]
            // Sets the name of the menu, placeholder, and top level DIV id (if topdiv 
            // option is true). Set to "dropmenu" by default.
            $menuName = (empty($menuName)) ? 'dropmenu' : "$menuName";
            
            // $siteMapRoot [int]
            // The parent ID of your root. Default 0. Can be set in 
            // snippet call with startDoc (to doc id 10 for example):
            // [[DropMenu?startDoc=10]]
            $siteMapRoot = 0;
            
            // $testOfLinks [ string ]
            // What database field do you want the title of your links to be?
            // The default is pagetitle because it is always a valid (not empty)
            // value, but if you prefer it can be any of the following:
            // menutitle, id, pagetitle, description, parent, alias, longtitle, introtext
            $textOfLinks = (empty($textOfLinks)) ? 'menutitle' : "$textOfLinks";
            
            // $removeNewLines [ true | false ]
            // If you want new lines removed from code, set to true. This is generally
            // better for IE when lists are styled vertically. 
            $removeNewLines = (!isset($removeNewLines)) ? false : ($removeNewLines==true);
            
            // $maxLevels [ int ]
            // Maximum number of levels to include. The default 0 will allow all
            // levels. Also settable with snippet variable levelLimit:
            // [[DropMenu?levelLimit=2]]
            $maxLevels = 0;
            
            // $showDescription [true | false]
            // Specify if you would like to include the description
            // with the page title link.
            $showDescription = (!isset($showDescription)) ? false : ($showDescription==true);
            
            // $titleOfLinks [ string ]
            // What database field do you want the title of your links to be?
            // The default is pagetitle because it is always a valid (not empty)
            // value, but if you prefer it can be any of the following:
            // menutitle, id, pagetitle, description, parent, alias, longtitle, introtext
            $titleOfLinks = (empty($titleOfLinks)) ? 'description' : "$titleOfLinks";
            
            // $selfAsLink [ true | false ]
            // Define if the current page should be a link (true) or not (false)
            $selfAsLink = (!isset($selfAsLink)) ? false : ($selfAsLink==true);
            
            // $topdiv [ true | false ]
            // Indicates if the top level UL is wrapped by a containing DIV block
            $topdiv = (!isset($topdiv)) ? false : ($topdiv==true);
            
            // $topdivClass [ string ]
            // CSS Class for DIV wrapping top level UL
            $topdivClass = (empty($topdivClass)) ? 'topdiv' : "$topdivClass";
            
            // $topnavvClass [ string ]
            // CSS Class for CSS class assigned to the top level UL
            $topdivClass = (empty($topdivClass)) ? 'topnav' : "$topnavClass";
            
            // $subdiv [ true | false ]
            // Indicates if nested UL's should be wrapped by containing DIV blocks
            $subdiv = (!isset($subdiv)) ? false : ($subdiv==true);
            
            // $subdivClass [ string ]
            // CSS Class for DIV blocks wrapping nested UL elements
            $subdivClass = (empty($subdivClass)) ? 'subdiv' : "$subdivClass";
            
            // $hereClass [ string ]
            // CSS Class for LI and A when they are the currently selected page, as well
            // as any ancestors of the current page (YOU ARE HERE)
            $hereClass = (empty($hereClass)) ? 'here' : $hereClass;
            
            // $pre [ string ]
            // Text to append before links inside of LIs
            $pre = (empty($pre)) ? '' : "$pre";
            
            // $post [ string ]
            // Text to append before links inside of LIs
            $post = (empty($post)) ? '' : "$post";
            
            // $orderBy [ string ]
            // Document field to sort menu by
            $orderBy = (empty($orderBy)) ? 'menuindex' : "$orderBy";
            
            // $orderDesc [true | false]
            // Order results in descending order?  default is false
            $orderDesc = (!isset($orderDesc)) ? false : ($orderDesc==true);
            
            // ###########################################
            // End config, the rest takes care of itself #
            // ###########################################
            
            // Initialize
            $MakeMap = "";
            $siteMapRoot = (isset($startDoc)) ? $startDoc : $siteMapRoot;
            $maxLevels = (isset($levelLimit)) ? $levelLimit : $maxLevels;
            $ie = ($removeNewLines) ? '' : "\n";
            
            // Overcome single use limitation on functions
            global $MakeMap_Defined;
            
            if (!isset ($MakeMap_Defined)) {
            	function filterHidden($var) {
            		return (!$var['hidemenu']==1);
            	}
            	function MakeMap($callBy, $listParent, $listLevel, $description, $titleOfLinks, $maxLevels, $inside, $pre, $post, $selfAsLink, $ie, $activeLinkIDs, $topdiv, $topdivClass, $topnavClass, $subdiv, $subdivClass, $subnavClass, $hereClass, $textOfLinks, $orderBy, $orderDesc) {
            
            		$children = $callBy->getActiveChildren($listParent, $orderBy, (!$orderDesc) ? 'ASC' : 'DESC', 'id, pagetitle, description, isfolder, parent, alias, longtitle, menutitle, hidemenu, introtext, content_dispo, contentType, type');
            
            		if (is_array($children) && !empty ($children)) {
            
            			// filter out the content that is set to be hidden from menu snippets
            			$children = array_filter($children, "filterHidden");
            			$numChildren = count($children);
            
            			// determine if it's a top category or not
            			$toplevel = !$inside;
            
            			// build the output
            			$topdivcls = (!empty ($topdivClass)) ? ' class="'.$topdivClass.'"' : '';
            			$topdivblk = ($topdiv) ? "<div$topdivcls>" : '';
            			$topnavcls = (!empty ($topnavClass)) ? ' class="'.$topnavClass.'"' : '';
            			$subdivcls = (!empty ($subdivClass)) ? ' class="'.$subdivClass.'"' : '';
            			$subdivblk = ($subdiv) ? "<div$subdivcls>$ie" : '';
            			$subnavcls = (!empty ($subnavClass)) ? ' class="'.$subnavClass.'"' : '';
            			$output = ($toplevel) ? "$topdivblk<ul$topnavcls>$ie" : "$ie$subdivblk<ul$subnavcls>$ie";
            
            			//loop through and process subchildren
            			foreach ($children as $child) {
            				// figure out if it's a containing category folder or not 
            				$numChildren --;
            				$isFolder = $child['isfolder'];
            				$itm = "";
            
                            // if menutitle is blank fall back to pagetitle for menu link
                            $textOfLinks = (empty($child[menutitle])) ? 'pagetitle' : "$textOfLinks"; 
            
            				if (!$inside) {
            					$itm .= (!$selfAsLink && ($child['id'] == $callBy->documentIdentifier)) ? $pre.$child[$textOfLinks].$post : '<a href="[~'.$child['id'].'~]" title="'.$child[$titleOfLinks].'">'.$pre.$child[$textOfLinks].$post.'</a>';
            				}
            				elseif ($isFolder && $inside) {
            					$itm .= '<a href="[~'.$child['id'].'~]" title="'.$child[$titleOfLinks].'">'.$child[$textOfLinks].'</a>';
            				} else {
            					$itm .= ($child['alias'] > '0') ? '<a href="[~'.$child['id'].'~]" title="'.$child[$titleOfLinks].'">'.$child[$textOfLinks].'</a>' : '<span>'.$child[$textOfLinks].'</span>';
            				}
            
            				// loop back through if the doc is a folder and has not reached the max levels
            				if ($isFolder && (($maxLevels == 0) || ($maxLevels > $listLevel +1))) {
            					$itm .= MakeMap($callBy, $child['id'], $listLevel +1, $description, $titleOfLinks, $maxLevels, true, $pre, $post, $selfAsLink, $ie, $activeLinkIDs, $topdiv, $topdivClass, $topnavClass, $subdiv, $subdivClass, $subnavClass, $hereClass, $textOfLinks, $orderBy, $orderDesc);
            				}
            
            				if ($itm && !$selfAsLink && ($child['id'] == $callBy->documentIdentifier)) {
            					$output .= "    <li class=\"$hereClass". ($numChildren == 0 ? ' last' : '')."\">$itm</li>$ie";
            				}
            				elseif ($itm) {
            					if ($numChildren == 0) {
            						$class = 'last';
            					}
            					if (is_array($activeLinkIDs)) {
            						if (in_array($child['id'], $activeLinkIDs)) {
            							$class .= ($class ? ' ' : '').'here';
            						}
            					}
            					if ($class) {
            						$class = ' class="'.$class.'"';
            					}
            					$output .= "<li$class>$itm</li>$ie";
            					$class = '';
            				}
            			}
            			$output .= "</ul>$ie";
            			$output .= ($toplevel) ? (($topdiv) ? "</div>$ie" : "") : (($subdiv) ? "</div>$ie" : "");
            		}
            		return $output;
            	}
            	$MakeMap_Defined = true;
            }
            
            $currentID = $modx->documentIdentifier;
            $parentID = $currentID;
            
            // find the parent docs of the current "you-are-here" doc
            // used in the logic to mark parents as such also
            while ($parentID != $siteMapRoot && $parentID != 0) {
            	$parent = $modx->getParent($parentID, 0);
            	if ($parent) {
            		$parentID = $parent['id'];
            		$activeLinkIDs[] = $parentID;
            	} else {
            		$parentID = 0;
            	}
            }
            
            // $modx->setPlaceholder($menuName, MakeMap($modx, $siteMapRoot, 0, $showDescription, $titleOfLinks, $maxLevels, false, $pre, $post, $selfAsLink, $ie, $activeLinkIDs, $topdiv, $topdivClass, $topnavClass, $subdiv, $subdivClass, $subnavClass, $hereClass, $textOfLinks, $orderBy, $orderDesc));
            return MakeMap($modx, $siteMapRoot, 0, $showDescription, $titleOfLinks, $maxLevels, false, $pre, $post, $selfAsLink, $ie, $activeLinkIDs, $topdiv, $topdivClass, $topnavClass, $subdiv, $subdivClass, $subnavClass, $hereClass, $textOfLinks, $orderBy, $orderDesc);
            
              Ryan Thrash, MODX Co-Founder
              Follow me on Twitter at @rthrash or catch my occasional unofficial thoughts at thrash.me
              • 28042 ☆ A M B ☆
              • 24,524 Posts
              Has DropMenu been updated since the 0.9.1 release?
                Studying MODX in the desert - http://sottwell.com
                Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
                Join the Slack Community - http://modx.org
                • 25663 MODX Staff
                • 12,272 Posts
                Not really, but it definitely will be; there are a few bugs and feature requests on the bugtracker listsed.
                  Ryan Thrash, MODX Co-Founder
                  Follow me on Twitter at @rthrash or catch my occasional unofficial thoughts at thrash.me