Dec 04, 2008, 12:55 AM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
Search via SMF or Google: modx forums all of modxcms.com web
  MODxCMS.com   Forums   Help Login Register  
News:Read what MODx Developers say: MODx Dev. Blogs
Pages: [1]   Go Down
  Print  
Author Topic: [Snippet] - DropMenu with activeTreeOnly option  (Read 5847 times)
0 Members and 1 Guest are viewing this topic.
Lammikko
Full Member
***
Posts: 157



WWW
« on: Apr 16, 2006, 03:22 AM »

Standard DropMenu snippet with activeTreeOnly option.

Advantages
- Reduces database requests in large multilevel menustructures
- Makes pages with large multilevel menustructures smaller and faster to download
- Reduces CSS hassle with basic menu building

Option activeTreeOnly is "false" by default
- DropMenu works as usual

If option activeTreeOnly is "true", eg [!DropMenu?activeTreeOnly=true!]
- DropMenu builds only the topmenu level and active submenu tree
- Longer example: http://modxcms.com/forums/index.php/topic,3557.msg25637.html#msg25637]

Not fully tested yet but works fine with my huge three level menustructure.

Code:
// ###########################################
// 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 Class (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
//
// TO DO: configuration parameters above, more usage examples, CSS examples, output indenting

// ###########################################
// 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                  #
// ###########################################

// $phMode [ true | false ]
// Whether you want it to output a [+placeholder+] or simply return the output.
// Defaults to false.
$phMode = false;

// $menuName [ string ]
// Sets the name of the menu, placeholder, and top level DIV id (if topdiv
// option is true). Set to "dropmenu" by default.
$phName = (!isset($phName)) ? 'dropmenu' : "$phName";

// $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;

// $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;


// $textOfLinks [ string ]
// What database field do you want the actual link text 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
// TO DO: set text to be first non-empty of an array of options
$textOfLinks = (!isset($textOfLinks)) ? 'menutitle' : "$textOfLinks";

// $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 = (!isset($titleOfLinks)) ? 'description' : "$titleOfLinks";

// $pre [ string ]
// Text to append before links inside of LIs
$pre = (!isset($pre)) ? '' : "$pre";

// $post [ string ]
// Text to append before links inside of LIs
$post = (!isset($post)) ? '' : "$post";

// $selfAsLink [ true | false ]
// Define if the current page should be a link (true) or not (false)
$selfAsLink = (!isset($selfAsLink)) ? false : ($selfAsLink==true);

// $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 = (!isset($hereClass)) ? 'here' : $hereClass;



// $showDescription [true | false]
// Specify if you would like to include the description
// with the page title link.
$showDescription = (!isset($showDescription)) ? false : ($showDescription==true);

// $descriptionField [ string ]
// What database field do you want the description to be?
// The default is description. If you specify a field, it will attempt to use it
// first then fall back until it finds a non-empty field in description, introtext,
// then longtitle so it really tries not be empty. It can be any of the following:
// menutitle, id, pagetitle, description, parent, alias, longtitle, introtext
// TO DO: set description to the first non-empty of an array of options
$descriptionField = (!isset($descriptionField)) ? 'description' : "$descriptionField";


// $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 = (!isset($topdivClass)) ? 'topdiv' : "$topdivClass";

// $topnavClass [ string ]
// CSS Class for the top-level (root) UL
$topnavClass = (!isset($topnavClass)) ? 'topnav' : "$topnavClass";



// $useCategoryFolders [ true | false ]
// If you want folders without any content to render without a link to be used
// as "category" pages (defaults to true). In order to use Category Folders,
// the template must be set to (blank) or it won't work properly.
$useCategoryFolders = (!isset($useCategoryFolders)) ? true : "$useCategoryFolders";

// $categoryClass [ string ]
// CSS Class for folders with no content (e.g., category folders)
$categoryClass = (!isset($categoryClass)) ? 'category' : "$categoryClass";



// $subdiv [ true | false ]
// Indicates if nested UL's should be wrapped by containing DIV blocks
// This is useful for creating "hover zones"
// (see http://positioniseverything.net/css-dropdowns.html for a demo)
// TO CONSIDER: Setting a subdiv class at all turns on hover DIVs?
$subdiv = (!isset($subdiv)) ? false : ($subdiv==true);

// $subdivClass [ string ]
// CSS Class for DIV blocks wrapping nested UL elements
$subdivClass = (!isset($subdivClass)) ? 'subdiv' : "$subdivClass";



// $orderBy [ string ]
// Document field to sort menu by
$orderBy = (!isset($orderBy)) ? 'menuindex' : "$orderBy";

// $orderDesc [true | false]
// Order results in descending order?  default is false
$orderDesc = (!isset($orderDesc)) ? false : ($orderDesc==true);


// HACK: activeTreeOnly
// $activeTreeOnly [ true | false ]
// Define if the menutree should show all menuitems or only those in active menutree branch
$activeTreeOnly = (!isset($activeTreeOnly)) ? false : ($activeTreeOnly==true);


// ###########################################
// End config, the rest takes care of itself #
// ###########################################

$debugMode = false;

// Initialize
$MakeMap = "";
$siteMapRoot = (isset($startDoc)) ? $startDoc : $siteMapRoot;
$maxLevels = (isset($levelLimit)) ? $levelLimit : $maxLevels;
$ie = ($removeNewLines) ? '' : "\n";
//Added by Remon: (undefined variables php notice)
$activeLinkIDs = array();
$subnavClass = '';

// Overcome single use limitation on functions
global $MakeMap_Defined;

if (!isset ($MakeMap_Defined)) {
  function filterHidden($var) {
    return (!$var['hidemenu']==1);
  }
  function filterEmpty($var) {
      return (!empty($var));
  }
  function MakeMap($modx, $listParent, $listLevel, $description, $titleOfLinks, $maxLevels, $inside, $pre, $post, $selfAsLink, $ie, $activeLinkIDs, $topdiv, $topdivClass, $topnavClass, $subdiv, $subdivClass, $subnavClass, $hereClass, $useCategoryFolders, $categoryClass, $showDescription, $descriptionField, $textOfLinks, $orderBy, $orderDesc, $activeTreeOnly, $debugMode) {
    // Added by Remon. Define this variable _here_ ;-)
    $output = '';

    $children = $modx->getActiveChildren($listParent, $orderBy, (!$orderDesc) ? 'ASC' : 'DESC', 'id, pagetitle, description, isfolder, parent, alias, longtitle, menutitle, hidemenu, introtext, content_dispo, contentType, type, template');
    // filter out the content that is set to be hidden from menu snippets
    $children = array_filter($children, "filterHidden");
    $numChildren = count($children);

    if (is_array($children) && !empty($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'];
          $itsEmpty = ($isFolder && ($child['template'] == '0'));
        $itm = "";

                // if menutitle is blank fall back to pagetitle for menu link
                $textOfLinks = (empty($child['menutitle'])) ? 'pagetitle' : "$textOfLinks";

          // If at the top level
        if (!$inside)
        {
          $itm .= ((!$selfAsLink && ($child['id'] == $modx->documentIdentifier)) || ($itsEmpty && $useCategoryFolders)) ?
                  $pre.$child[$textOfLinks].$post . (($debugMode) ? ' self|cat' : '') :
                  '<a href="[~'.$child['id'].'~]" title="'.$child[$titleOfLinks].'">'.$pre.$child[$textOfLinks].$post.'</a>';
          $itm .= ($debugMode) ? ' top' : '';
        }

        // it's a folder and it's below the top level
        elseif ($isFolder && $inside)
        {

          $itm .= ($itsEmpty && $useCategoryFolders) ?
                  $pre.$child[$textOfLinks].$post . (($debugMode) ? 'subfolder T': '') :
                  '<a href="[~'.$child['id'].'~]" title="'.$child[$titleOfLinks].'">'.$pre.$child[$textOfLinks].$post.'</a>'. (($debugMode) ? ' subfolder F' :'');
        }

        // it's a document inside a folder
        else
        {
          $itm .= ($child['alias'] > '0' && !$selfAsLink && ($child['id'] == $modx->documentIdentifier)) ? $child[$textOfLinks] : '<a href="[~'.$child['id'].'~]" title="'.$child[$titleOfLinks].'">'.$child[$textOfLinks].'</a>';
          $itm .= ($debugMode) ? ' doc' : '';
        }
        $itm .= ($debugMode)? "$useCategoryFolders $isFolder $itsEmpty" : '';

        // BEGIN HACK: activeTreeOnly
        // loop back through if the doc is a folder and has not reached the max levels
        if ($isFolder && (($maxLevels == 0) || ($maxLevels > $listLevel +1))) {
          // activeTreeOnly TRUE
          if ($activeTreeOnly)
          {
          $makeMapYes = FALSE;
            if (is_array($activeLinkIDs))
            {
              if ($child['id'] == $modx->documentIdentifier || in_array($child['id'], $activeLinkIDs))
              {
              $makeMapYes = TRUE;
              }
            }
          }
          // activeTreeOnly FALSE or child is in active tree
          if (!$activeTreeOnly || $makeMapYes)
          {
            $itm .= MakeMap($modx, $child['id'], $listLevel +1, $description, $titleOfLinks, $maxLevels, true, $pre, $post, $selfAsLink, $ie, $activeLinkIDs, $topdiv, $topdivClass, $topnavClass, $subdiv, $subdivClass, $subnavClass, $hereClass, $useCategoryFolders, $categoryClass, $showDescription, $descriptionField, $textOfLinks, $orderBy, $orderDesc, $activeTreeOnly, $debugMode);
          }
        }
        // END HACK: activeTreeOnly

        if ($itm && !$selfAsLink && ($child['id'] == $modx->documentIdentifier)) {
          $output .= "    <li class=\"$hereClass". ($numChildren == 0 ? ' last' : '')."\">$itm</li>$ie";
        }
        elseif ($itm) {
          // Added by Remon
          // define it here:
          $class = '';
          if ($numChildren == 0) {
            $class = 'last';
          }
          if (is_array($activeLinkIDs)) {
            if (in_array($child['id'], $activeLinkIDs)) {
              $class .= ($class ? ' ' : '').$hereClass;
            }
          }
          // it's an empty folder and using Category Folders
          if ($useCategoryFolders && $itsEmpty) {
            $class .= ($class ? ' ' : '').$categoryClass;
          }
          if ($class) {
            $class = ' class="'.$class.'"';
          }

          // TO DO: set description to the first non-empty of an array of options
          if ($showDescription && (!empty($child['$descriptionField']))) {
              $desc = " &ndash; ".$child['$descriptionField'];
          } elseif ($showDescription && (!empty($child['description']))) {
              $desc = ' &ndash; ' . $child['description'];
          } elseif ($showDescription && (!empty($child['introtext']))) {
              $desc = ' &ndash; ' . $child['introtext'];
          } elseif ($showDescription && (!empty($child['longtitle']))) {
              $desc = ' &ndash; ' . $child['longtitle'];
          } else {
              $desc = '';
          }

          $output .= "<li$class>$itm$desc</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;
  }
}

if ($phMode) {
    // output to a [+placeholder+]
    $modx->setPlaceholder($phName, MakeMap($modx, $siteMapRoot, 0, $showDescription, $titleOfLinks, $maxLevels, false, $pre, $post, $selfAsLink, $ie, $activeLinkIDs, $topdiv, $topdivClass, $topnavClass, $subdiv, $subdivClass, $subnavClass, $hereClass, $useCategoryFolders, $categoryClass, $showDescription, $descriptionField, $textOfLinks, $orderBy, $orderDesc, $activeTreeOnly, $debugMode));

} else {
    // return the output a "usual"
    return MakeMap($modx, $siteMapRoot, 0, $showDescription, $titleOfLinks, $maxLevels, false, $pre, $post, $selfAsLink, $ie, $activeLinkIDs, $topdiv, $topdivClass, $topnavClass, $subdiv, $subdivClass, $subnavClass, $hereClass, $useCategoryFolders, $categoryClass, $showDescription, $descriptionField, $textOfLinks, $orderBy, $orderDesc, $activeTreeOnly, $debugMode);

}



« Last Edit: Jun 09, 2006, 08:49 AM by Lammikko » Logged

orz
Jr. Member
*
Posts: 44


« Reply #1 on: Apr 16, 2006, 03:50 AM »

Great Work!!!!!!!!!!!!!
Thank you!!
Logged
Dr. Scotty Delicious
Coding Team
*
Posts: 1,172


Dr. of Fine Pirate Arts


WWW
« Reply #2 on: Apr 16, 2006, 01:16 PM »

If I were going to count the number of users requesting this feature on my fingers, I would need about a bazillion hands  Grin!  You are a god dude!

-sD-
Logged

We pillage, we plunder, we rifle and loot. Drink up me 'earties, Yo Ho!
We kidnap and ravage and don't give a hoot. Drink up me 'earties, Yo Ho!
Yo Ho, Yo Ho! A pirate's life for me.
0ad
Full Member
***
Posts: 100


« Reply #3 on: May 30, 2006, 08:49 AM »

Amazing!!!!

Thank you!!!
Logged

Please consider the research and evidence of the Scholars for 9/11 Truth at http://www.st911.org
cino
Jr. Member
*
Posts: 35


« Reply #4 on: Jun 07, 2006, 03:36 AM »

That's very, very useful! Thank you.

I tried to integrate it with this hack (that displays "here" class just on the current menu item, not on the whole parent tree), but without any success.

Do you have any idea how to get the same result with your mod?
Logged
cino
Jr. Member
*
Posts: 35


« Reply #5 on: Jun 15, 2006, 10:06 AM »

Try this hack. It fixes and enhances DropMenu and incorporates your hack. It also fixes it making a category folder open even if activeTreeOnly option is true.
Logged
Lammikko
Full Member
***
Posts: 157



WWW
« Reply #6 on: Jun 15, 2006, 01:04 PM »

Try this hack.
Great work cino. Thanks!
Logged

asfahaan
Jr. Member
*
Posts: 3


« Reply #7 on: Jul 11, 2008, 12:16 AM »

Hi there!

I am another newbie trying to incorporate a drop down menu in my web template.

Can you give me some basic steps of how to use this snippet?

I presume:
I need to create a new snippet in the modx manager and copy paste the code and call it within the template?

Do I need to do any changes or not for my style sheet?

Please help me out.

Thanks
Logged
sottwell
Documentation Team
*
Posts: 8,170



WWW
« Reply #8 on: Jul 11, 2008, 01:10 AM »

DropMenu has been deprecated for some time; the Wayfinder snippet is used now.

A full set of documentation and examples can be found here: http://www.muddydogpaws.com/development/wayfinder/features.html
Logged

sottwell.com has moved to a lovely Solaris 10 server!
Log in username guest, password guestuser.
Templates are now becoming available at http://sottwell.com/templates.html
asfahaan
Jr. Member
*
Posts: 3


« Reply #9 on: Jul 11, 2008, 03:16 AM »

Hi,

Thanks for directing me in the right direction. Smiley

I used the below snippet set call in the navigation tag:
CSSplay Menu - Dropdown
Snippet Call:
Code:
<!-- navigation -->
<div  id="menu">
[[Wayfinder? &startId=`0` &level=`3` &parentClass=`hide` &parentRowTpl=`cssplay_parentRow` &outerTpl=`cssplay_outer` &innerTpl=`cssplay_inner` &rowTpl=`cssplay_row` &outerClass=`menu` &cssTpl=`cssplay_dropdown`]]
</div>

I got this code from: http://www.muddydogpaws.com/development/wayfinder/examples/example-1.html

I have the "Way Finder" in my Resources list in ModX manager:
Wayfinder - 2.0 Completely template-driven menu builder that's simple and fast to configure.

Do I need to specify anything in the style sheets? or snippets?

You can view the template I am building on "http://modx.tasmanit.com"

My aim is to create a free templates for MODX community. But I just wanted to learn how to do top navigation menus before I release a series of eye catching templates for all the MODX community.

Thanks heaps in advance,
Asfahaan
Logged
asfahaan
Jr. Member
*
Posts: 3


« Reply #10 on: Jul 11, 2008, 03:25 AM »

I also created the below chucks which are just copy paste from the website.

cssplay_basicdd - cssplay_basicdd - Menu
cssplay_dropdown - cssplay_dropdown
cssplay_inner - cssplay_inner - Menu
cssplay_outer - cssplay_outer - Menu
cssplay_parentRow - cssplay_parentRow - Menu
cssplay_row - cssplay_row - Menu

Is that what I was suppose to do?

Thanks
Asfahaan
Logged
Pages: [1]   Go Up
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP

Copyright © 2005-2008 MODxCMS, All rights reserved. Contact Us
Styles by ziworks.com

Powered by SMF 1.1.4 | SMF © 2005, Simple Machines LLC

Valid XHTML 1.0! Valid CSS!