Simple Navigator Snippet for ModX Revoltution

Simple Navigator Snippet for ModX Revoltution

Simple Navigator Snippet for ModX Revoltution

I found myself needing a really simple way to pull in my sites menu, but also wanted the ability to have some placeholders for the links as well.  The following code should be created as a snippet, and called un-cached [[!YOUR_SNIPPET_NAME]]

What’s it do?

Well, simply put it generates a navigation block, and throws all your ModX site page links into a hierarchal un-ordered list of link items.  As well, as generates a bunch of dynamic placeholders in case you have a need for them.  Note:  the snippet needs to be called, prior to placing any placeholders in your content.

How Do I Use This?

Create your template or page and place the following snippet call (make sure to replace YOUR_SNIPPET_NAME, with whatever you named this…)

[[+link.Title-11]] .:. [[+link.MenuTitle-11]] .:. [[+link.URL-11]] // Pulls the link Title, Menu Title, and Link for Resource ID 11
<hr />
 [[!YOUR_SNIPPET_NAME? &Wrapper_Class=`MenuWrapper`
			 &Wrapper_ID=`MenuWrapperID`
			 &Wrapper_Extra=` data-rel="Wrapper"`
			 &Contains_Snippet=`true`
			 &Should_Cache=`false`
			 &Cache_Length=`7200`]]

What’s All This Mean?

The snippet generates a multi-level navigation structure.   It only pulls published documents, that are not hidden from the menu, and are not deleted.  The items are sorted by the parent first, then by the items menu index.  It is only capable of rendering a menu for modDocuments, and modWebLinks…   In the case of modWebLinks, it will inject the Link Attributes (useful for target=”_blank”)  It sets the link title to the resources Long Title, uses the Menu Title for display, Resource Alias for ID’s, and Resource URIs for the links  it also generates a series of placeholders:

  •  [[+link.Title-PAGEID]]
  •  [[+link.MenuTitle-PAGEID]]
  •  [[+link.URL-PAGEID]]

It is also capable of running included basic snippets if specified, and the snippet exists in the ‘Summary’ field of the resource.  This is useful if you need to pull in some other nav items from other sources… for instance, I pull in the top 5 latest articles from my blog  but need them to be displayed in my main menu  NOTE: At this time, it does not include Snippet parameters, nor does it matter if you put in the !

PROPERTIES:

 &Wrapper_Class = css class for the <nav> wrapper
 &Wrapper_ID = ID of the <nav> wrapper
 &Wrapper_Extra = any valid <nav> attributes
 &Contains_Snippet = true/false
&Should_Cache = true/false
&Cache_Length = # of seconds

Where’s My Code?

Keep your pants on, here ya go… just copy/paste it into YOUR_SNIPPET_NAME’s code

<?
 	// Set some variable we can use to set some classes, id's, extras
	$wc = (string)(strlen($Wrapper_Class) > 0) ? $Wrapper_Class : 'wrapper';
	$wi = (string)(strlen($Wrapper_ID) > 0) ? $Wrapper_ID : 'wrapper';
	$we = (string)(strlen($Wrapper_Extra) > 0) ? $Wrapper_Extra : null;
	$cs = (bool)(!empty($Contains_Snippet)) ? filter_var($Contains_Snippet, FILTER_VALIDATE_BOOLEAN) : false;	
	$sc = (bool)(!empty($Should_Cache)) ? filter_var($Should_Cache, FILTER_VALIDATE_BOOLEAN) : true;
	$cl = (int)((int)$Cache_Length > 0) ? (int)$Should_Cache : 7200;

	// Check string for snippet
	if(!function_exists('IsSnippet')){
		function IsSnippet($str){
			$pattern = '/[[!?(.*)]]/';
			return preg_match($pattern, $str, $match);
		}
	}

	// recursive function to generate our un-ordered list of menu items
	if(!function_exists('GenerateMenu')){
		function GenerateMenu($level, $parent = 0, $wc, $wi, $we, $cs, $sc, $cl){
			try {
				$lvl = ++$level;
				global $modx;
				// Check for #1, should this be cached, #2 does it already exist in the cache
				$cached = $modx->cacheManager->get('Navigator');
				if($sc && isset($cached)){
					// return our cached menu
					return $cached;
				}else{
					// get the site start
					$siteStartId = $modx->getOption('site_start');
					// Set our initial rows array
					$rows = array();
					// Run our query to get our menu items
					$sql = 'Select `id`, `menutitle`, `uri`, `longtitle`, `parent`, `link_attributes`, `class_key`, `content`, `alias`, `introtext`
										From `' . $modx->getOption(xPDO::OPT_TABLE_PREFIX) . 'site_content` 
										Where `deleted` = 0 AND `hidemenu` = 0 AND `published` = 1 AND `parent` = :parent
										Order by `parent`, `menuindex`';
					$query = new xPDOCriteria($modx, $sql, array(':parent' => $parent));
					if ($query->stmt && $query->stmt->execute()) {
						$rows = $query->stmt->fetchAll(PDO::FETCH_ASSOC);
					}
					// do some cleanup
					unset($query, $sql);
					// make sure we have some rows, and then build our html for the menu
					if($rows){
						// grab a count of our results
						$rCt = count($rows);
						$cls = ($lvl > 1) ? 'sub-item-' . $lvl : 'main-item-' . $lvl;
						$ret .= '   <ul class="' . $cls . '" id="' . $cls . '-' . $parent . '">' . "rn";
						for($i = 0; $i < $rCt; ++$i){
							// if this resource is a WebLink, show the content in it, as the URL for the href tag, otherwise, use the resource's URI
							$url = ($rows[$i]['class_key'] == 'modWebLink') ? $rows[$i]['content'] : '/' . $rows[$i]['uri'];
							// Check for the site's start id, if true, show a "blank" link, otherwise show the $url
							$showUrl = ($siteStartId == $rows[$i]['id']) ? '/' : $url;
							$la = (strlen($rows[$i]['link_attributes']) > 0) ? ' ' . $rows[$i]['link_attributes'] : null;
							$ret .= '       <li class="' . $cls . '" id="' . $rows[$i]['alias'] . '">' . "rn";
							$ret .= '           <a href="' . $showUrl . '" title="' . $rows[$i]['longtitle'] . '"' . $la . '>' . $rows[$i]['menutitle'] . '</a>' . "rn";
							$ret .= GenerateMenu($lvl, $rows[$i]['id']);
							// Check for a snippet, and render it
							$it = $rows[$i]['introtext'];
							if($cs && IsSnippet($it)){
								// if we find a snippet in the Summary field, run it, and attach it to our output   
								preg_match('/[[!?(.*)]]/', $it, $sm);
								$ret .= $modx->runSnippet($sm[1]);
								// clean up
								unset($sm);
							}
							$ret .= '       </li>' . "rn";
						}
						$ret .= '   </ul>' . "rn";

					}
					// clean up
					unset($rows);           
					// Check to see if we should cache it, if so, set it to cache, and apply the length of time it should be cached for: defaults to 2 hours
					if($sc){
						// Set the navigation to cache
						$modx->cacheManager->set('Navigator', $ret, $cl);
					}
					// return the menu
					return $ret;
				}
			} catch(Exception $e) {
				// If there was an error, make sure to write it out to the modX Error Log
				$modx->log(modX::LOG_LEVEL_ERROR, '[Navigator:GenerateMenu] Error: ' . $e->getMessage());
				return null;
			}
		}
	}

	// Generate the placeholders to use
	if(!function_exists('GeneratePlaceholders')){
		function GeneratePlaceholders($sc, $cl){
			// need to global modx object
			global $modx;
			$rows = array();
			// get the ID of the start page
			$siteStartId = (int)$modx->getOption('site_start');
			// Run our query to get our menu items-- check for the cache first
			$cached = $modx->cacheManager->get('NavigatorPHs');
			if($sc && isset($cached)){
				$rows = $cached;
				unset($cached);
			}else{
				$sql = 'Select `id`, `menutitle`, `uri`, `longtitle`, `class_key`, `content`
									From `' . $modx->getOption(xPDO::OPT_TABLE_PREFIX) . 'site_content` 
									Where `deleted` = 0 AND `hidemenu` = 0 AND `published` = 1
									Order by `parent`, `menuindex`';
				$query = new xPDOCriteria($modx, $sql, array());
				if ($query->stmt && $query->stmt->execute()) {
					$rows = $query->stmt->fetchAll(PDO::FETCH_ASSOC);
					if($sc){
						$modx->cacheManager->set('NavigatorPHs', $rows, $cl);
					}
				}
				// do some cleanup
				unset($query, $sql);
			}
			if($rows){
				$rCt = count($rows);
				for($i = 0; $i < $rCt; ++$i){
					// if this resource is a WebLink, show the content in it, as the URL for the href tag, otherwise, use the resource's URI
					$url = ($rows[$i]['class_key'] == 'modWebLink') ? $rows[$i]['content'] : '/' . $rows[$i]['uri'];
					// Check for the site's start id, if true, show a "blank" link, otherwise show the $url
					$showUrl = ($siteStartId == $rows[$i]['id']) ? '/' : $url;
					$item = array('Title-' . $rows[$i]['id'] => $rows[$i]['longtitle'],
												'MenuTitle-' . $rows[$i]['id'] => $rows[$i]['menutitle'],
												'URL-' . $rows[$i]['id'] => $showUrl);
					$modx->toPlaceholders($item, 'link');
				}
			}
			unset($rows);	
		}	
	}	

	// Fire up the placeholder generator
	GeneratePlaceholders($sc, $cl);
	// Fire up the menu
	$return = '<nav class="' . $wc . '" id="' . $wi . '"' . $we . '>' . "rn";
	$return .= GenerateMenu(0, 0, $wc, $wi, $we, $cs, $sc, $cl);
	$return .= '</nav>' . "rn";
	// Write it out to the page
	echo $return;
?>

 

Categories


Let Us Help

Get You Online

Contact Us Today

Important Cookie Information
Our website uses cookies. By continuing to browse the site you are agreeing to our use of cookies. For more details about cookies and their use, please see our Cookie Policy.