Commits

Christoffer Niska  committed 2236347

rewrote the menu implementation

  • Participants
  • Parent commits d5a583b
  • Branches 1.0.0-wip

Comments (0)

Files changed (6)

File components/Bootstrap.php

  * @author Christoffer Niska <ChristofferNiska@gmail.com>
  * @copyright Copyright &copy; Christoffer Niska 2011-
  * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
- * @version 0.10.0
+ * @version 1.0.0
  */
 
 /**
 			return $this->_assetsUrl = $assetsUrl;
 		}
 	}
+
+    /**
+     * Returns the version number.
+     * @return string the version
+     */
+    public function getVersion()
+    {
+        return '1.0.0';
+    }
 }

File demo/protected/views/layouts/main.php

 		</p>
 
 		<p class="copy">
-			&copy; Christoffer Niska 2011
+			&copy; Christoffer Niska <?php echo date('Y'); ?>
 		</p>
 
 	</footer>

File demo/protected/views/site/index.php

 ");
 ?>
 
-<section id="bootAlert">
+<section id="tbAlert">
 
 	<h2>Alerts</h2>
 
 
 </section>
 
-<section id="bootBreadcrumbs">
+<section id="tbBreadcrumbs">
 
 	<h2>Breadcrumbs</h2>
 
 
 </section>
 
-<section id="bootNavbar">
+<section id="tbNavbar">
 
 	<h2>Navbar</h2>
 
 
 </section>
 
-<section id="bootMenu">
+<section id="tbMenu">
 
 	<h2>Menus</h2>
 
 
 </section>
 
-<section id="bootTabbable">
+<section id="tbTabbable">
 
 	<h2>Tabbable</h2>
 
 
 </section>
 
-<section id="bootDetailView">
+<section id="tbDetailView">
 
 	<h2>Detail views</h2>
 
 
 </section>
 
-<section id="bootGridView">
+<section id="tbGridView">
 
 	<h2>Grid views</h2>
 
 
 </section>
 
-<section id="bootThumbnails">
+<section id="tbThumbnails">
 
 	<h2>Thumbnails</h2>
 
 
 </section>
 
-<section id="bootTooltip">
+<section id="tbTooltip">
 
 	<h2>Tooltips</h2>
 
 
 </section>
 
-<section id="bootPopover">
+<section id="tbPopover">
 
 	<h2>Popovers</h2>
 
 
 </section>
 
-<section id="bootModal">
+<section id="tbModal">
 
 	<h2>Modals</h2>
 
 
 </section>
 
-<section id="bootActiveForm">
+<section id="tbActiveForm">
 
 	<h2>Forms</h2>
 
 	<?php echo $form->textFieldRow($model, 'textField', array('class'=>'span3')); ?>
 	<?php echo $form->passwordFieldRow($model, 'password', array('class'=>'span3')); ?>
 	<?php echo $form->checkboxRow($model, 'checkbox'); ?>
-	<?php $this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'icon'=>'ok', 'label'=>'Submit')); ?>
+	<?php $this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'label'=>'Login')); ?>
 
 	<?php $this->endWidget(); ?>
 
 <?php echo \$form->textFieldRow(\$model, 'textField', array('class'=>'span3')); ?>
 <?php echo \$form->passwordFieldRow(\$model, 'password', array('class'=>'span3')); ?>
 <?php echo \$form->checkboxRow(\$model, 'checkbox'); ?>
-<?php \$this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'icon'=>'ok', 'label'=>'Submit')); ?>
+<?php \$this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'label'=>'Login')); ?>
 
 <?php \$this->endWidget(); ?>"); ?>
 
 		'htmlOptions'=>array('class'=>'well'),
 	)); ?>
 
-	<?php echo $form->textFieldRow($model, 'textField', array('class'=>'input-medium')); ?>
-	<?php $this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'icon'=>'search', 'label'=>'Search')); ?>
+	<?php echo $form->textFieldRow($model, 'textField', array('class'=>'input-medium', 'prepend'=>'<i class="icon-search"></i>')); ?>
+	<?php $this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'label'=>'Go')); ?>
 
 	<?php $this->endWidget(); ?>
 
 	'htmlOptions'=>array('class'=>'well'),
 )); ?>
 
-<?php echo \$form->textFieldRow(\$model, 'textField', array('class'=>'input-medium')); ?>
-<?php \$this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'icon'=>'search', 'label'=>'Search')); ?>
+<?php echo \$form->textFieldRow(\$model, 'textField', array('class'=>'input-medium', 'prepend'=>'<i class=\"icon-search\"></i>')); ?>
+<?php \$this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'label'=>'Go')); ?>
 
 <?php \$this->endWidget(); ?>"); ?>
 
 
 	<?php echo $form->textFieldRow($model, 'textField', array('class'=>'input-small')); ?>
 	<?php echo $form->passwordFieldRow($model, 'password', array('class'=>'input-small')); ?>
-	<?php $this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'icon'=>'arrow-right', 'label'=>'Log in')); ?>
+	<?php $this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'label'=>'Log in')); ?>
 
 	<?php $this->endWidget(); ?>
 
 
 <?php echo \$form->textFieldRow(\$model, 'textField', array('class'=>'input-small')); ?>
 <?php echo \$form->passwordFieldRow(\$model, 'password', array('class'=>'input-small')); ?>
-<?php \$this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'icon'=>'arrow-right', 'label'=>'Log in')); ?>
+<?php \$this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'label'=>'Log in')); ?>
 
 <?php \$this->endWidget(); ?>"); ?>
 
 
 </section>
 
-<section id="bootButton">
+<section id="tbButton">
 
 	<h2>Buttons</h2>
 
 
 </section>
 
-<section id="bootHero">
+<section id="tbHero">
 
 	<h2>Hero unit</h2>
 
 
 </section>
 
-<section id="bootCarousel">
+<section id="tbCarousel">
 
 	<h2>Carousel</h2>
 
 
 </section>
 
-<section id="bootProgress">
+<section id="tbProgress">
 
 	<h2>Progress bars</h2>
 
 
 </section>
 
-<section id="bootTypeahead">
+<section id="tbTypeahead">
 
 	<h2>Typeahead</h2>
 
 
 </section>
 
-<section id="bootLabel">
+<section id="tbLabel">
 
 	<h2>Labels</h2>
 
 
 </section>
 
-<section id="bootBadge">
+<section id="tbBadge">
 
 	<h2>Badges</h2>
 
 		'scrollspy'=>array('spy'=>'.subnav', 'offset'=>50),
 		'items'=>array(
 			array('label'=>'WIDGETS'),
-			array('label'=>'Alert', 'url'=>'#bootAlert'),
-			array('label'=>'Breadcrumb', 'url'=>'#bootBreadcrumbs'),
-			array('label'=>'Navbar', 'url'=>'#bootNavbar'),
-			array('label'=>'Menu', 'url'=>'#bootMenu'),
-			array('label'=>'Tabbable', 'url'=>'#bootTabbable'),
-			array('label'=>'Detail view', 'url'=>'#bootDetailView'),
-			array('label'=>'Grid view', 'url'=>'#bootGridView'),
-			array('label'=>'Thumbnail', 'url'=>'#bootThumbnails'),
-			array('label'=>'Tooltip', 'url'=>'#bootTooltip'),
-			array('label'=>'Popover', 'url'=>'#bootPopover'),
-			array('label'=>'Modal', 'url'=>'#bootModal'),
-			array('label'=>'Forms', 'url'=>'#bootActiveForm'),
-			array('label'=>'Buttons', 'url'=>'#bootButton'),
-			array('label'=>'Hero', 'url'=>'#bootHero'),
-			array('label'=>'Carousel', 'url'=>'#bootCarousel'),
-			array('label'=>'Progress', 'url'=>'#bootProgress'),
-			array('label'=>'Typeahead', 'url'=>'#bootTypeahead'),
-			array('label'=>'Labels', 'url'=>'#bootLabel'),
-			array('label'=>'Badges', 'url'=>'#bootBadge'),
+			array('label'=>'Alert', 'url'=>'#tbAlert'),
+			array('label'=>'Breadcrumb', 'url'=>'#tbBreadcrumbs'),
+			array('label'=>'Navbar', 'url'=>'#tbNavbar'),
+			array('label'=>'Menu', 'url'=>'#tbMenu'),
+			array('label'=>'Tabbable', 'url'=>'#tbTabbable'),
+			array('label'=>'Detail view', 'url'=>'#tbDetailView'),
+			array('label'=>'Grid view', 'url'=>'#tbGridView'),
+			array('label'=>'Thumbnail', 'url'=>'#tbThumbnails'),
+			array('label'=>'Tooltip', 'url'=>'#tbTooltip'),
+			array('label'=>'Popover', 'url'=>'#tbPopover'),
+			array('label'=>'Modal', 'url'=>'#tbModal'),
+			array('label'=>'Forms', 'url'=>'#tbActiveForm'),
+			array('label'=>'Buttons', 'url'=>'#tbButton'),
+			array('label'=>'Hero', 'url'=>'#tbHero'),
+			array('label'=>'Carousel', 'url'=>'#tbCarousel'),
+			array('label'=>'Progress', 'url'=>'#tbProgress'),
+			array('label'=>'Typeahead', 'url'=>'#tbTypeahead'),
+			array('label'=>'Labels', 'url'=>'#tbLabel'),
+			array('label'=>'Badges', 'url'=>'#tbBadge'),
 		),
 	)); ?>
 

File widgets/TbBaseMenu.php

 <?php
 /**
- * BootBaseMenu class file.
+ * TbBaseMenu class file.
  * @author Christoffer Niska <ChristofferNiska@gmail.com>
- * @copyright Copyright &copy; Christoffer Niska 2011-
+ * @copyright Copyright &copy; Christoffer Niska 2012-
  * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
  * @package bootstrap.widgets
  */
 
-abstract class TbBaseMenu extends CWidget
+Yii::import('zii.widgets.CMenu');
+
+abstract class TbBaseMenu extends CMenu
 {
-	/**
-	 * @var array the menu items.
-	 */
-	public $items = array();
-	/**
-	 * @var string the item template.
-	 */
-	public $itemTemplate;
-	/**
-	 * @var boolean whether to encode item labels.
-	 */
-	public $encodeLabel = true;
-	/**
-	 * @var array the HTML attributes for the widget container.
-	 */
-	public $htmlOptions = array();
+    /**
+     * Returns the divider css class.
+     * @return string the class name
+     */
+    abstract public function getDividerCssClass();
 
-	/**
-	 * Initializes the widget.
-	 */
-	public function init()
-	{
-		$this->htmlOptions['id'] = $this->getId();
-	}
+    /**
+     * Renders the menu items.
+     * @param array $items menu items. Each menu item will be an array with at least two elements: 'label' and 'active'.
+     * It may have three other optional elements: 'items', 'linkOptions' and 'itemOptions'.
+     */
+    protected function renderMenu($items)
+    {
+        $n = count($items);
 
-	/**
-	 * Runs the widget.
-	 */
-	public function run()
-	{
-		echo CHtml::openTag('ul', $this->htmlOptions);
-		$this->renderItems($this->items);
-		echo '</ul>';
-	}
+        if($n > 0)
+        {
+            echo CHtml::openTag('ul', $this->htmlOptions);
 
-	/**
-	 * Renders a single item in the menu.
-	 * @param array $item the item configuration
-	 * @return string the rendered item
-	 */
-	protected function renderItem($item)
-	{
-		if (!isset($item['linkOptions']))
-			$item['linkOptions'] = array();
+            $count = 0;
+            foreach ($items as $item)
+            {
+                $count++;
 
-		if (isset($item['icon']))
-		{
-			if (strpos($item['icon'], 'icon') === false)
-			{
-				$pieces = explode(' ', $item['icon']);
+                if (isset($item['divider']))
+                    echo '<li class="'.$this->getDividerCssClass().'"></li>';
+                else
+                {
+                    $options = isset($item['itemOptions']) ? $item['itemOptions'] : array();
+                    $classes = array();
+
+                    if ($item['active'] && $this->activeCssClass != '')
+                        $classes[] = $this->activeCssClass;
+
+                    if ($count === 1 && $this->firstItemCssClass !== null)
+                        $classes[] = $this->firstItemCssClass;
+
+                    if ($count === $n && $this->lastItemCssClass !== null)
+                        $classes[] = $this->lastItemCssClass;
+
+                    if ($this->itemCssClass !== null)
+                        $classes[] = $this->itemCssClass;
+
+                    if ($classes !== array())
+                    {
+                        $classes = implode(' ', $classes);
+                        if (!empty($options['class']))
+                            $options['class'] .= ' '.$classes;
+                        else
+                            $options['class'] = $classes;
+                    }
+
+                    echo CHtml::openTag('li', $options);
+
+                    $menu = $this->renderMenuItem($item);
+
+                    if (isset($this->itemTemplate) || isset($item['template']))
+                    {
+                        $template = isset($item['template']) ? $item['template'] : $this->itemTemplate;
+                        echo strtr($template, array('{menu}' => $menu));
+                    }
+                    else
+                        echo $menu;
+
+                    if (isset($item['items']) && count($item['items']))
+                    {
+                        $this->controller->widget('bootstrap.widgets.TbDropdown', array(
+                            'encodeLabel'=>$this->encodeLabel,
+                            'items'=>$item['items'],
+                            'htmlOptions'=>isset($item['submenuOptions']) ? $item['submenuOptions'] : $this->submenuHtmlOptions,
+                        ));
+                    }
+
+                    echo '</li>';
+                }
+            }
+
+            echo '</ul>';
+        }
+    }
+
+    /**
+     * Renders the content of a menu item.
+     * Note that the container and the sub-menus are not rendered here.
+     * @param array $item the menu item to be rendered. Please see {@link items} on what data might be in the item.
+     * @return string the rendered item
+     */
+    protected function renderMenuItem($item)
+    {
+        if (!isset($item['linkOptions']))
+            $item['linkOptions'] = array();
+
+        if (isset($item['icon']))
+        {
+            if (strpos($item['icon'], 'icon') === false)
+            {
+                $pieces = explode(' ', $item['icon']);
                 $item['icon'] = 'icon-'.implode(' icon-', $pieces);
-			}
+            }
 
-			$item['label'] = '<i class="'.$item['icon'].'"></i> '.$item['label'];
-		}
+            $item['label'] = '<i class="'.$item['icon'].'"></i> '.$item['label'];
+        }
 
-		if (!isset($item['header']) && !isset($item['url']))
-			$item['url'] = '#';
+        if (isset($item['items']) && !empty($item['items']))
+        {
+            $item['url'] = '#';
 
-		if (isset($item['url']))
-			return CHtml::link($item['label'], $item['url'], $item['linkOptions']);
-		else
-			return $item['label'];
-	}
+            if (isset($item['linkOptions']['class']))
+                $item['linkOptions']['class'] .= ' dropdown-toggle';
+            else
+                $item['linkOptions']['class'] = 'dropdown-toggle';
 
-	/**
-	 * Checks whether a menu item is active.
-	 * @param array $item the menu item to be checked
-	 * @param string $route the route of the current request
-	 * @return boolean the result
-	 */
-	protected function isItemActive($item, $route)
-	{
-		if (isset($item['url']) && is_array($item['url']) && !strcasecmp(trim($item['url'][0], '/'), $route))
-		{
-			if (count($item['url']) > 1)
-				foreach (array_splice($item['url'], 1) as $name=>$value)
-					if (!isset($_GET[$name]) || $_GET[$name] != $value)
-						return false;
+            $item['linkOptions']['data-toggle'] = 'dropdown';
+            $item['label'] .= ' <span class="caret"></span>';
+        }
 
-			return true;
-		}
+        if (isset($item['url']))
+            return CHtml::link($item['label'], $item['url'], $item['linkOptions']);
+        else
+            return $item['label'];
+    }
 
-		return false;
-	}
+    /**
+     * Normalizes the {@link items} property so that the 'active' state is properly identified for every menu item.
+     * @param array $items the items to be normalized.
+     * @param string $route the route of the current request.
+     * @param boolean $active whether there is an active child menu item.
+     * @return array the normalized menu items
+     */
+    protected function normalizeItems($items, $route, &$active)
+    {
+        foreach ($items as $i => $item)
+        {
+            if (!is_array($item))
+                $item = array('divider'=>true);
+            else
+            {
+                if (!isset($item['itemOptions']))
+                    $item['itemOptions'] = array();
 
-	/**
-	 * Renders the items in this menu.
-	 * @abstract
-	 * @param array $items the menu items
-	 */
-	abstract public function renderItems($items);
+                $classes = array();
+
+                if (!isset($item['url']) && $this->isVertical())
+                {
+                    $item['header'] = true;
+                    $classes[] = 'nav-header';
+                }
+
+                if (isset($item['items']))
+                    $classes[] = 'dropdown';
+
+                $classes = implode($classes, ' ');
+                if (isset($item['itemOptions']['class']))
+                    $item['itemOptions']['class'] .= ' '.$classes;
+                else
+                    $item['itemOptions']['class'] = $classes;
+            }
+
+            $items[$i] = $item;
+        }
+
+        return parent::normalizeItems($items, $route, $active);
+    }
+
+    /**
+     * Returns whether this is a vertical menu.
+     * @return boolean the result
+     */
+    protected function isVertical()
+    {
+        return $this instanceof TbDropdown || $this instanceof TbMenu && $this->type === TbMenu::TYPE_LIST;
+    }
 }

File widgets/TbDropdown.php

 <?php
 /**
- * BootDropdown class file.
+ * TbDropdown class file.
  * @author Christoffer Niska <ChristofferNiska@gmail.com>
- * @copyright Copyright &copy; Christoffer Niska 2011-
+ * @copyright Copyright &copy; Christoffer Niska 2012-
  * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
  * @package bootstrap.widgets
- * @since 0.9.10
  */
 
 Yii::import('bootstrap.widgets.TbBaseMenu');
 
-/**
- * Bootstrap dropdown menu widget.
- */
 class TbDropdown extends TbBaseMenu
 {
-	/**
-	 * Initializes the widget.
-	 */
-	public function init()
-	{
-		$route = $this->controller->getRoute();
-		$this->items = $this->normalizeItems($this->items, $route);
+    /**
+     * Initializes the widget.
+     */
+    public function init()
+    {
+        parent::init();
 
-		$classes = 'dropdown-menu';
-		if (isset($this->htmlOptions['class']))
-			$this->htmlOptions['class'] .= ' '.$classes;
-		else
-			$this->htmlOptions['class'] = $classes;
-	}
+        if (isset($this->htmlOptions['class']))
+            $this->htmlOptions['class'] .= ' dropdown-menu';
+        else
+            $this->htmlOptions['class'] = 'dropdown-menu';
+    }
 
-	/**
-	 * Renders the items in this menu.
-	 * @param array $items the menu items
-	 */
-	public function renderItems($items)
-	{
-		foreach ($items as $item)
-		{
-			if (!is_array($item))
-				echo '<li class="divider"></li>';
-			else
-			{
-				if (!isset($item['itemOptions']))
-					$item['itemOptions'] = array();
-
-				$classes = array();
-				if (!isset($item['url']))
-				{
-					$item['header'] = true;
-					$classes[] = 'nav-header';
-				}
-
-				if ($item['active'])
-					$classes[] = 'active';
-
-				$classes = implode(' ', $classes);
-				if(isset($item['itemOptions']['class']))
-					$item['itemOptions']['class'] .= ' '.$classes;
-				else
-					$item['itemOptions']['class'] = $classes;
-
-				echo CHtml::openTag('li', $item['itemOptions']);
-				$menu = $this->renderItem($item);
-
-				if (isset($this->itemTemplate) || isset($item['template']))
-				{
-					$template = isset($item['template']) ? $item['template'] : $this->itemTemplate;
-					echo strtr($template, array('{menu}'=>$menu));
-				}
-				else
-					echo $menu;
-
-				echo '</li>';
-			}
-		}
-	}
-
-	/**
-	 * Normalizes the items in this menu.
-	 * @param array $items the items to be normalized
-	 * @param string $route the route of the current request
-	 * @return array the normalized menu items
-	 */
-	protected function normalizeItems($items, $route)
-	{
-		foreach ($items as $i => $item)
-		{
-			if (!is_array($item))
-				continue;
-
-			if (isset($item['visible']) && !$item['visible'])
-			{
-				unset($items[$i]);
-				continue;
-			}
-
-			if (!is_array($item)) {
-				continue;
-			}
-
-			if (!isset($item['label']))
-				$item['label'] = '';
-
-			if (isset($item['encodeLabel']) && $item['encodeLabel'])
-				$items[$i]['label'] = CHtml::encode($item['label']);
-
-			if (($this->encodeLabel && !isset($item['encodeLabel']))
-					|| (isset($item['encodeLabel']) && $item['encodeLabel'] !== false))
-				$items[$i]['label'] = CHtml::encode($item['label']);
-
-			if (!isset($item['active']))
-				$items[$i]['active'] = $this->isItemActive($item, $route);
-		}
-
-		return array_values($items);
-	}
+    /**
+     * Returns the divider css class.
+     * @return string the class name
+     */
+    public function getDividerCssClass()
+    {
+        return 'divider';
+    }
 }

File widgets/TbMenu.php

 <?php
 /**
- * BootMenu class file.
+ * TbMenu class file.
  * @author Christoffer Niska <ChristofferNiska@gmail.com>
- * @copyright Copyright &copy; Christoffer Niska 2011-
+ * @copyright Copyright &copy; Christoffer Niska 2012-
  * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
  * @package bootstrap.widgets
  */
 
 Yii::import('bootstrap.widgets.TbBaseMenu');
 
-/**
- * Bootstrap menu widget.
- * Used for rendering of bootstrap menus with support dropdown sub-menus and scroll-spying.
- * @since 0.9.8
- */
 class TbMenu extends TbBaseMenu
 {
-	// Menu types.
-	const TYPE_UNSTYLED = '';
-	const TYPE_TABS = 'tabs';
-	const TYPE_PILLS = 'pills';
-	const TYPE_LIST = 'list';
+    // Menu types.
+    const TYPE_UNSTYLED = '';
+    const TYPE_TABS = 'tabs';
+    const TYPE_PILLS = 'pills';
+    const TYPE_LIST = 'list';
 
-	/**
-	 * @var string the menu type.
-	 * Valid values are '', 'tabs' and 'pills'. Defaults to ''.
-	 */
-	public $type;
-	/**
-	 * @var boolean whether to stack navigation items.
-	 */
-	public $stacked = false;
-	/**
-	 * @var array the scroll-spy configuration.
-	 */
-	public $scrollspy;
-	/**
-	 * @var array the HTML options for dropdown menus.
-	 */
-	public $dropdownOptions = array();
+    /**
+     * @var string the menu type.
+     * Valid values are '', 'tabs' and 'pills'. Defaults to ''.
+     */
+    public $type;
+    /**
+     * @var boolean whether to stack navigation items.
+     */
+    public $stacked = false;
+    /**
+     * @var array the scroll-spy configuration.
+     */
+    public $scrollspy;
 
-	/**
-	 * Initializes the widget.
-	 */
-	public function init()
-	{
-		$route = $this->controller->getRoute();
-		$this->items = $this->normalizeItems($this->items, $route);
+    /**
+     * Initializes the widget.
+     */
+    public function init()
+    {
+        parent::init();
 
-		$classes = array('nav');
+        $classes = array('nav');
 
-		$validTypes = array(self::TYPE_TABS, self::TYPE_PILLS, self::TYPE_LIST);
+        if (isset($this->type) && in_array($this->type, array(self::TYPE_TABS, self::TYPE_PILLS, self::TYPE_LIST)))
+            $classes[] = 'nav-'.$this->type;
 
-		if (isset($this->type) && in_array($this->type, $validTypes))
-			$classes[] = 'nav-'.$this->type;
+        if ($this->type !== self::TYPE_LIST && $this->stacked)
+            $classes[] = 'nav-stacked';
 
-		if ($this->type !== self::TYPE_LIST && $this->stacked)
-			$classes[] = 'nav-stacked';
+        $classes = implode(' ', $classes);
+        if (isset($this->htmlOptions['class']))
+            $this->htmlOptions['class'] .= ' '.$classes;
+        else
+            $this->htmlOptions['class'] = $classes;
 
-		$classes = implode(' ', $classes);
-		if (isset($this->htmlOptions['class']))
-			$this->htmlOptions['class'] .= ' '.$classes;
-		else
-			$this->htmlOptions['class'] = $classes;
+        if (isset($this->scrollspy) && is_array($this->scrollspy) && isset($this->scrollspy['spy']))
+        {
+            if (!isset($this->scrollspy['subject']))
+                $this->scrollspy['subject'] = 'body';
 
-		if (isset($this->scrollspy) && is_array($this->scrollspy) && isset($this->scrollspy['spy']))
-		{
-			if (!isset($this->scrollspy['subject']))
-				$this->scrollspy['subject'] = 'body';
+            if (!isset($this->scrollspy['offset']))
+                $this->scrollspy['offset'] = null;
 
-			if (!isset($this->scrollspy['offset']))
-				$this->scrollspy['offset'] = null;
+            Yii::app()->bootstrap->spyOn($this->scrollspy['subject'], $this->scrollspy['spy'], $this->scrollspy['offset']);
+        }
+    }
 
-			Yii::app()->bootstrap->spyOn($this->scrollspy['subject'], $this->scrollspy['spy'], $this->scrollspy['offset']);
-		}
-	}
-
-	/**
-	 * Renders the items in this menu.
-	 * @param array $items the menu items
-	 */
-	public function renderItems($items)
-	{
-		foreach ($items as $item)
-		{
-			if (!is_array($item))
-			{
-				$class = $this->type !== self::TYPE_LIST ? 'divider-vertical' : 'divider';
-				echo '<li class="'.$class.'"></li>';
-			}
-			else
-			{
-				if (!isset($item['itemOptions']))
-					$item['itemOptions'] = array();
-
-				$classes = array();
-
-				if ($item['active'] || (isset($item['items']) && $this->isChildActive($item['items'])))
-					$classes[] = 'active';
-
-				if ($this->type === self::TYPE_LIST && !isset($item['url']))
-				{
-					$item['header'] = true;
-					$classes[] = 'nav-header';
-				}
-
-				if (isset($item['items']))
-					$classes[] = 'dropdown';
-
-				$classes = implode(' ', $classes);
-				if(isset($item['itemOptions']['class']))
-					$item['itemOptions']['class'] .= ' '.$classes;
-				else
-					$item['itemOptions']['class'] = $classes;
-
-				echo CHtml::openTag('li', $item['itemOptions']);
-				$menu = $this->renderItem($item);
-
-				if (isset($this->itemTemplate) || isset($item['template']))
-				{
-					$template = isset($item['template']) ? $item['template'] : $this->itemTemplate;
-					echo strtr($template, array('{menu}'=>$menu));
-				}
-				else
-					echo $menu;
-
-				if(isset($item['items']) && !empty($item['items']))
-				{
-					$this->controller->widget('bootstrap.widgets.TbDropdown', array(
-						'encodeLabel'=>$this->encodeLabel,
-						'items'=>$item['items'],
-						'htmlOptions'=>isset($item['dropdownOptions']) ? $item['dropdownOptions'] : $this->dropdownOptions,
-					));
-				}
-
-				echo '</li>';
-			}
-		}
-	}
-
-	/**
-	 * Renders a single item in the menu.
-	 * @param array $item the item configuration
-	 * @return string the rendered item
-	 */
-	protected function renderItem($item)
-	{
-		if (!isset($item['linkOptions']))
-			$item['linkOptions'] = array();
-
-		if (isset($item['items']) && !empty($item['items']))
-		{
-			if (isset($item['linkOptions']['class']))
-				$item['linkOptions']['class'] .= ' dropdown-toggle';
-			else
-				$item['linkOptions']['class'] = 'dropdown-toggle';
-
-			$item['linkOptions']['data-toggle'] = 'dropdown';
-			$item['label'] .= ' <span class="caret"></span>';
-		}
-
-		return parent::renderItem($item);
-	}
-
-	/**
-	 * Normalizes the items in this menu.
-	 * @param array $items the items to be normalized
-	 * @param string $route the route of the current request
-	 * @return array the normalized menu items
-	 */
-	protected function normalizeItems($items, $route)
-	{
-		foreach ($items as $i => $item)
-		{
-			if (!is_array($item))
-				continue;
-
-			if (isset($item['visible']) && !$item['visible'])
-			{
-				unset($items[$i]);
-				continue;
-			}
-
-			if (!isset($item['label']))
-				$item['label'] = '';
-
-			if (isset($item['encodeLabel']) && $item['encodeLabel'])
-				$items[$i]['label'] = CHtml::encode($item['label']);
-
-			if (($this->encodeLabel && !isset($item['encodeLabel']))
-					|| (isset($item['encodeLabel']) && $item['encodeLabel'] !== false))
-				$items[$i]['label'] = CHtml::encode($item['label']);
-
-			if (!empty($item['items']) && is_array($item['items']))
-			{
-				$items[$i]['items'] = $this->normalizeItems($item['items'], $route);
-
-				if (empty($items[$i]['items']))
-					unset($items[$i]['items']);
-			}
-
-			if (!isset($item['active']))
-				$items[$i]['active'] = $this->isItemActive($item, $route);
-		}
-
-		return array_values($items);
-	}
-
-	/**
-	 * Returns whether a child item is active.
-	 * @param array $items the items to check
-	 * @return boolean the result
-	 */
-	protected function isChildActive($items)
-	{
-		foreach ($items as $item)
-			if (isset($item['active']) && $item['active'] === true)
-				return true;
-
-		return false;
-	}
+    /**
+     * Returns the divider css class.
+     * @return string the class name
+     */
+    public function getDividerCssClass()
+    {
+        return $this->type === self::TYPE_LIST ? 'divider' : 'divider-vertical';
+    }
 }