• New version of Wayfinder#

  • dflock Reply #1, 3 years, 4 months ago

    Reply
    Good news everyone! During my development travails, I've created an updated version of Wayfinder that fixes two issues and adds two handy new features!
    Fixes
    I've incorporated this fix which makes the hereClass work properly with weblinks in the menu and I've fixed the SQL query to work around the MySQL 5.0.51 sorting bug.

    New Features
    lastRowTpl
    I've also added a new parameter called lastRowTpl which allows you specify a chunk to be used for the last menu item output. It works the same way as all the other wayfinder tpl's and defaults to using rowTpl is it isn't specified.

    It's very useful for little menu's that currently look like this if you do them with Wayfinder:

    item1 | item2 | item3 | lastitem |

    and should look like this:

    item1 | item2 | item3 | lastitem

    Odd & Even classes
    Finally, I've added support for even & odd classes on rows. These work like all the other wayfinder classes - you specify a class name in the parameter and this will be added to the wf.classes placeholder. These ones are only output on the appropriate rows, though - and you don't have to specify both if you don't want to - it'll still work with just one.

    These are really useful for menu's which are supposed to be stripey, with every other item a different colour.

    To implement this, I've modified both Wayfinder files. You can download the new versions from here (.zip) or here (.tar.gz). I've included the patches here, as they're shorter and let you see what's changed.
    Here's the patch for the snippet file, wayfinder.snippet.php.patch:

    --- Downloads/web_dev/MODx/Add-ons/wayfinder/wayfinder.snippet.php 
    +++ www/dev/modx/wayfinder.snippet.php 
    @@ -3,11 +3,13 @@
     ::::::::::::::::::::::::::::::::::::::::
      Snippet name: Wayfinder
      Short Desc: builds site navigation
    - Version: 2.0
    + Version: 2.0.1
      Authors: 
     	Kyle Jaebker (muddydogpaws.com)
     	Ryan Thrash (vertexworks.com)
      Date: February 27, 2006
    + 06 January 2009 - Modified by dunc@codeistry.com : added lastRowTpl and weblinks here patch.
    + 15 July 2008 - Modified by dunc@codeistry.com - added odd & even classes
     ::::::::::::::::::::::::::::::::::::::::
     Description:
         Totally refactored from original DropMenu nav builder to make it easier to
    @@ -72,12 +74,15 @@
     	'level' => isset($levelClass) ? $levelClass: '',
     	'self' => isset($selfClass) ? $selfClass : '',
     	'weblink' => isset($webLinkClass) ? $webLinkClass : '',
    +	'odd' => isset($oddClass) ? $oddClass : '',
    +	'even' => isset($evenClass) ? $evenClass : '',
     );
     
     //get user templates
     $wf->_templates = array(
     	'outerTpl' => isset($outerTpl) ? $outerTpl : '',
     	'rowTpl' => isset($rowTpl) ? $rowTpl : '',
    +	'lastRowTpl' => isset($lastRowTpl) ? $lastRowTpl : '',
     	'parentRowTpl' => isset($parentRowTpl) ? $parentRowTpl : '',
     	'parentRowHereTpl' => isset($parentRowHereTpl) ? $parentRowHereTpl : '',
     	'hereTpl' => isset($hereTpl) ? $hereTpl : '',


    and here's the include file, wayfinder.inc.php.patch:

    --- Downloads/web_dev/MODx/Add-ons/wayfinder/wayfinder.inc.php 
    +++ www/dev/modx/wayfinder.inc.php 
    @@ -3,11 +3,14 @@
     ::::::::::::::::::::::::::::::::::::::::
      Snippet name: Wayfinder
      Short Desc: builds site navigation
    - Version: 2.0
    + Version: 2.0.1
      Authors: 
     	Kyle Jaebker (muddydogpaws.com)
     	Ryan Thrash (vertexworks.com)
    - Date: March 03, 2007
    + Date: February 27, 2006
    + 
    + 06 January 2009 - Modified by dunc@codeistry.com : added lastRowTpl and weblinks here patch.
    + 15 July 2008 - Modified by dunc@codeistry.com - added odd & even classes
     ::::::::::::::::::::::::::::::::::::::::
     */
     
    @@ -88,6 +91,7 @@
     		foreach ($menuDocs as $docId => $docInfo) {
     			$docInfo['level'] = $level;
     			$docInfo['first'] = $firstItem;
    +			$docInfo['counter'] = $counter;
     			$firstItem = 0;
     			//Determine if last item in group
     			if ($counter == ($numSubItems) && $numSubItems > 1) {
    @@ -163,13 +167,17 @@
             } elseif ($resource['level'] > 1 && $this->_templates['innerRowTpl']) {
                 $usedTemplate = 'innerRowTpl';
             } else {
    -            $usedTemplate = 'rowTpl';
    +        	if ($resource['last'] == '1' && $this->_templates['lastRowTpl']) {
    +        		$usedTemplate = 'lastRowTpl';
    +        	} else {
    +            	$usedTemplate = 'rowTpl';
    +        	}
             }
             //Get the template
             $useChunk = $this->_templates[$usedTemplate];
     		//Setup the new wrapper name and get the class names
             $useSub = $resource['hasChildren'] ? "[+wf.wrapper.{$resource['id']}+]" : "";
    -        $classNames = $this->setItemClass('rowcls',$resource['id'],$resource['first'],$resource['last'],$resource['level'],$resource['isfolder'],$resource['type']);
    +        $classNames = $this->setItemClass('rowcls',$resource['id'],$resource['first'],$resource['last'],$resource['level'],$resource['isfolder'],$resource['type'],$resource['counter']);
             if ($classNames) $useClass = ' class="' . $classNames . '"';
             //Setup the row id if a prefix is specified
             if ($this->_config['rowIdPrefix']) {
    @@ -205,7 +213,7 @@
         }
     	
     	//determine style class for current item being processed
    -    function setItemClass($classType, $docId = 0, $first = 0, $last = 0, $level = 0, $isFolder = 0, $type = 'document') {
    +    function setItemClass($classType, $docId = 0, $first = 0, $last = 0, $level = 0, $isFolder = 0, $type = 'document', $counter =  '') {
             global $modx;
             $returnClass = '';
             $hasClass = 0;
    @@ -245,7 +253,7 @@
                     $hasClass = 1;
                 }
                 //Set here class if specified
    -            if (!empty($this->_css['here']) && $this->isHere($docId)) {
    +            if (!empty($this->_css['here']) && $this->isHere($docId, $type)) {
                     $returnClass .= $hasClass ? ' ' . $this->_css['here'] : $this->_css['here'];
                     $hasClass = 1;
                 }
    @@ -259,15 +267,36 @@
                     $returnClass .= $hasClass ? ' ' . $this->_css['weblink'] : $this->_css['weblink'];
                     $hasClass = 1;
                 }
    +			//Set class for even items
    +			if (!empty($this->_css['even'])) {
    +				if (($counter) && !($counter % 2)) {
    +					$returnClass .= $hasClass ? ' ' . $this->_css['even'] : $this->_css['even'];
    +					$hasClass = 1;
    +				}
    +			}
    +			//Set class for odd items
    +			if (!empty($this->_css['odd'])) {
    +				if (($counter) && ($counter % 2)) {
    +					$returnClass .= $hasClass ? ' ' . $this->_css['odd'] : $this->_css['odd'];
    +					$hasClass = 1;
    +				}
    +			}
             }
     
             return $returnClass;
         }
     	
     	//determine "you are here"
    -    function isHere($did) {
    -        return in_array($did,$this->parentTree);
    -    }
    +	function isHere($did, $type='document') {
    +		// begin weblink 'here' patch
    +		if ($type == 'reference') {
    +			global $modx;
    +			$doc = $modx->getDocumentObject('id', $did);
    +			$did = $doc['content'];
    +		}
    +		// end weblink 'here' patch
    +		return in_array($did,$this->parentTree);
    +	}
     	
     	//Add the specified css & javascript chunks to the page
         function regJsCss() {
    @@ -348,7 +377,7 @@
     	        if($docgrp = $modx->getUserDocGroups()) $docgrp = implode(",",$docgrp);
     	        // build query
     	        $access = ($modx->isFrontend() ? "sc.privateweb=0" : "1='{$_SESSION['mgrRole']}' OR sc.privatemgr=0").(!$docgrp ? "" : " OR dg.document_group IN ({$docgrp})");
    -			$sql = "SELECT DISTINCT {$fields} FROM {$tblsc} sc LEFT JOIN {$tbldg} dg ON dg.document = sc.id WHERE sc.published=1 AND sc.deleted=0 AND ({$access}){$menuWhere} AND sc.id IN (".implode(',',$ids).") GROUP BY sc.id ORDER BY {$sort} {$this->_config['sortOrder']} {$sqlLimit};";
    +			$sql = "SELECT DISTINCT {$fields} FROM {$tblsc} sc LEFT JOIN {$tbldg} dg ON dg.document = sc.id WHERE sc.published=1 AND sc.deleted=0 AND ({$access}){$menuWhere} AND sc.id IN (".implode(',',$ids).") ORDER BY {$sort} {$this->_config['sortOrder']} {$sqlLimit};";
     			//run the query
     			$result = $modx->dbQuery($sql);
     	        $resourceArray = array();
    @@ -491,7 +520,7 @@
                 if (empty($v) || !$templateCheck) {
                     if ($n === 'outerTpl') {
                         $this->_templates[$n] = '<ul[+wf.classes+]>[+wf.wrapper+]</ul>';
    -                } elseif ($n === 'rowTpl') {
    +                } elseif ($n === 'rowTpl' || $n === 'lastRowTpl') {
                         $this->_templates[$n] = '<li[+wf.id+][+wf.classes+]><a href="[+wf.link+]" title="[+wf.title+]" [+wf.attributes+]>[+wf.linktext+]</a>[+wf.wrapper+]</li>';
     				} elseif ($n === 'startItemTpl') {
     					$this->_templates[$n] = '<h2[+wf.id+][+wf.classes+]>[+wf.linktext+]</h2>[+wf.wrapper+]';


    I'm using these on live sites, because I'm a crazy fool, but if we can get some more testing from everyone, maybe this can be added to the repository as a new version and maybe then into the main MODx distribution, so that everyone can share the love.

    What do you think?


  • dev_cw Reply #2, 3 years, 4 months ago

    Reply
    Looks like a good idea. I will test it sometime soon.

    While you are at it I always thought that a way to assign an ID to the outerTpl would be cool. It seems that I am always needing to create an outerTpl simply to include an ID.

    Something like &outerId=`navigation` would output <ulnavigation> so you would not need a custom tpl.
    I think you would also need to have a [+wf.outerId+] placeholder to use in the outerTpl.

    Is there a way to have PHx in Wayfinder like it is in Ditto?


  • dflock Reply #3, 3 years, 4 months ago

    Reply
    No idea about PHx - I might see how ditto does this.

    I can easily add the outerID thing at some point, maybe this weekend.


  • bunk58 Reply #4, 3 years, 4 months ago

    Reply
    Thanks Duncan Works a treat in overcoming the MySQL 5.0.51 sorting bug.


  • rthrash Reply #5, 3 years, 4 months ago

    Reply
    Good work Duncan. It'd be great to log these into JIRA so they can make it into the main distribution as well.
    http://svn.modxcms.com/jira/secure/IssueNavigator.jspa?reset=true&mode=hide&pid=10033


  • chucktrukk Reply #6, 3 years, 4 months ago

    Reply
    cw,

    I always use an empty outerTpl and just manually wrap my wayfinder calls with <ul>. Makes it easier for me.


  • dev_cw Reply #7, 3 years, 4 months ago

    Reply
    No idea about PHx - I might see how ditto does this.
    Need to weigh overhead vs function since menus can be everywhere. But if possible it would rock.

    I always use an empty outerTpl and just manually wrap my wayfinder calls with <ul>. Makes it easier for me.
    But isn't a blank tpl a custom tpl? Or do you simply do &outerTpl=``? To overcome this I sometimes use a snippet to generate the ID based on parent or ultimate parent ID.

    BTW - this works great dflock, thanks for this update.


  • dflock Reply #8, 3 years, 4 months ago

    Reply
    I'll have a go at getting these into Jira tomorrow - I haven't used it before, so I'll do my best.

    I'll have a look at the OuterID thing too - it ought to be simple to implement and won't really complicate Wayfinder any, so why not?

    You could then do stuff like:

    [[Wayfinder?[!SnippetCall?id`!]` ...]]

    or whatever.


  • cipa Reply #9, 3 years, 4 months ago

    Reply
    here simple feature that I needed to code myself

    'categoryTplId' => isset($categoryTplId) ? $categoryTplId : FALSE,

    +

    $resource['template']=="0" || $resource['template']==$this->_config['categoryTplId']

    It adds a little more flexibility when a container has different template then blank and &categoryFoldersTpl is used

    I guess 1 in 50 projects will need this


  • opengeek Reply #10, 3 years, 4 months ago

    Reply
    Quote from: dflock at Jan 06, 2009, 05:37 PM
    I've fixed the SQL query to work around the MySQL 5.0.51 sorting bug.
    Does this "workaround" for the MySQL bug work properly when a document is in multiple document groups since you removed the group by?