css list-menu helper

By Florian Kraemer (burzum)
A helper (method) to create a css formatable list-menu.
I was looking for a good way to creating css formated list-menus that allows me to make an menu-element active. I found this solution http://www.thinkingphp.org/2007/07/08/macgyver-menu-for-cakephp-whats-the-active-menu-item/
But i think it's not that good if you want to reuse it. So i have improved the code. Thanks to gwoo for some suggestions.

Here's my custom helper using the htmlhelper:

Helper Class:

Download code <?php 
class CommunityHelper extends AppHelper
{
    var 
$helpers = array('Html');
    
    function 
menu($links = array(),$htmlAttributes = array(),$type 'ul')
    {      
        
$this->tags['ul'] = '<ul%s>%s</ul>';
        
$this->tags['ol'] = '<ol%s>%s</ol>';
        
$this->tags['li'] = '<li%s>%s</li>';
        
$out = array();        
        foreach (
$links as $title => $link)
        {
            if(
$this->url($link) == substr($this->here,0,-1))
            {
                
$out[] = sprintf($this->tags['li'],' class="active"',$this->Html->link($title$link));
            }
            else
            {
                
$out[] = sprintf($this->tags['li'],'',$this->Html->link($title$link));
            }
        }
        
$tmp join("\n"$out);
        return 
$this->output(sprintf($this->tags[$type],$this->_parseAttributes($htmlAttributes), $tmp));
    }
}
?>

View Template:

Download code
<?php
echo $community->menu(array(
    
'Home' => array('controller' => ''),
    
'Posts' => array('controller' => 'posts'),
    
'New Post' => array('controller' => 'posts''action' => 'new'),
    
'My Profile' => array('controller' => 'users''action' => 'myprofile',=> 'settings')),
    array(
'class' => 'submenu')
    );
?>

And here's the pending ticket https://trac.cakephp.org/ticket/3144 I hope it's going to make its way into cake soon.

Note: I've tested it only in cakephp 1.2.

I hope this helps not only me :)

 

Comments 514

CakePHP Team Comments Author Comments
 

Comment

1 Nice component but...

we have a multilingual app and we need multilingual interface, you can add in line 14 inside the foreach
$title = __($title,true);
And now, you have a multilingual css menĂº
Posted Mar 11, 2008 by David Bolufer
 

Comment

2 CSS Image Rollovers

I've used this helper with great success, but needed a little more from it. I've integrated the above multilingual addition, and also allowed for CSS Rollover image menus using lists by adding SPAN tags around the title in the link, allowing you to set the CSS "display:none;" property for it. Here's my code:

Helper Class:

<?php 
/* Example Usage:
    echo $csslistmenu->create(array( 
        'Home' => array('controller' => 'pages', 'home'), 
        'Posts' => array('controller' => 'posts'), 
        'New Post' => array('controller' => 'posts', 'action' => 'new'), 
        'My Profile' => array('controller' => 'users', 'action' => 'myprofile',0 => 'settings')), 
        array('class' => 'submenu') 
        ); 
    
    http://bakery.cakephp.org/articles/view/ul-ol-menu-method-for-helpers
    
    - Alterations made following comments to allow different languages
    - Alterations made to add an ID to the <li> element and span tags around the text $title for css image rollover type menus
*/
class CssListMenuHelper extends AppHelper 

    var 
$helpers = array('Html'); 
     
    function 
create($links = array(),$htmlAttributes = array(),$type 'ul'
    {       
        
$this->tags['ul'] = '<ul%s>%s</ul>'
        
$this->tags['ol'] = '<ol%s>%s</ol>'
        
$this->tags['li'] = '<li%s>%s</li>';
        
$out = array();         
        foreach (
$links as $title => $link
        { 
            
$title __($title,true); // multilingual addition
            
$linkTitle "<span>" $title "</span>"// additional SPAN tags to allow for hiding of text in CSS
            
if($this->url($link) == $this->here
            { 
                
$out[] = sprintf($this->tags['li'],' id="' strtolower(str_replace(" ""-",$title)) . '" class="active"',$this->Html->link($linkTitle$link,null,null,false)); 
            } 
            else 
            { 
                
$out[] = sprintf($this->tags['li'],' id="' strtolower(str_replace(" ""-",$title)) . '"',$this->Html->link($linkTitle$link,null,null,false)); 
            } 
        } 
        
$tmp join("\n"$out); 
        return 
$this->output(sprintf($this->tags[$type],$this->_parseAttributes($htmlAttributes), $tmp)); 
    } 
}
?>
Posted Mar 30, 2008 by Rich Milns
 

Comment

3 CSS Examples for the above

I'd forgotten to post some CSS examples to go with the above:


ul.myMenu li {
    height: 39px;
    float: left;
    background: transparent 0 -39px no-repeat;
    margin:0;
}

/* the id of the menu item is created automatically from the $title variable in the helper */
/* the home.gif image has the 'out state' and 'over state' of the rollover effect in one image: the over state is positioned above the out, so in this example, the canvas size would be 60px wide by 78px (double the height of the menu) */
ul.myMenu li#home {
    background-image:url(/img/menu/home.gif);
    width:60px;
}

/* this CSS handles the rollover effect */
ul.myMenu li:hover, ul.myMenu li.active {
    background-position:0 0;
}

/* hide the text, leaving the A tag */
ul.myMenu li a span {
    display:none;
}

ul.myMenu li a {
    display:block;
    height:100%;
    width:100%;
}

Also, to actually use the helper, you would do the following:

Controller Class:

<?php 
    
var $helpers = array('Csslistmenu');
?>

And finally in your view or layout:

View Template:


// output the menu
echo $csslistmenu->create(
array( 
    'Home' => array('controller' => 'pages', 'home'), 
    'Property Search' => array('controller' => 'properties'), 
    'FAQs' => array('controller' => 'faqs', 'action' => 'view'), 
    'Contact' => array('controller' => 'pages', 'contact')
    ),
array('class' => 'myMenu')  
); 
Posted Mar 30, 2008 by Rich Milns