понедельник, 16 мая 2011 г.

Создание меню пользователя (zii.widgets.CMenu)

Теперь необходимо добавить меню для пользователя. Конечно, хочется чего ни будь необычного, с выбором по свойствам товара, с сортировкой и прочим, но этого я еще не умею :) Начну с простого меню, где пользователь может выбирать, из какой категории товар ему показывать. Буду использовать правую колонку (где сейчас показывается меню администратора). За представление правой колонки отвечает файл:
Z:\home\catalog.loc\www\protected\views\layouts\column2.php

В том месте, где выводится меню администратора добавлю else и укажу, что делать, если пользователь просто гость:
if(!Yii::app()->user->isGuest)
{
$this->beginWidget('zii.widgets.CPortlet', array(
'title'=>'Operations',
));
$this->widget('zii.widgets.CMenu', array(
'items'=>$this->menu,
'htmlOptions'=>array('class'=>'operations'),
));
$this->endWidget();
}
else
{
echo "
"; $this->beginWidget('zii.widgets.CPortlet', array( 'title'=>'Category', )); $this->widget('zii.widgets.CMenu', array( 'items'=>Category::All_shown(), 'htmlOptions'=>array('class'=>'operations' ), )); $this->endWidget(); echo "
"; }
Использую виджет CMenu, который находится в виджите CPortlet (это просто для красоты)
В этом меню пункты генерируются методом Category::All_shown(), который еще не описан. Опишу его в файле
Z:\home\catalog.loc\www\protected\models\Category.php
Там уже есть функция Category::All(), она выводит все пункты меню и используется для генерации выпадающего списка. All_shown() создаю по её подобию:
public static function All_shown()
{
//это первый пункт меню Показать всё. 
$r[] =   array('label'=>'Show all', 
'url'=>array('/assortiment/index','category'=>''));      
$models = Category::model()->findAll(
array('order' => 'name',
'condition' => 'shown = "yes"',
)
);
foreach($models as $val)
{
//дополняю массив элементами меню
$r[] =   array('label'=>$val->name, 
'url'=>array('/assortiment/index','category'=>$val->id));
}
//Возвращаю массив с элементами меню 
return $r;
}
Теперь надо научить контроллер обрабатывать передаваемую переменную category :
В файле контроллера Z:\home\catalog.loc\www\protected\controllers\AssortimentController.php
Подправлю действие index
public function actionIndex()
{
if(!empty($_GET['category']))
//Пришла переменная category, то есть пользователь 
//выбрал какую-то категорию из меню
{
$criteria=new CDbCriteria(array(
'condition'=>
'category_id=:id and
t.shown=1 and
category.shown=1',
'params' => array(':id'=>(int)$_GET['category']),
'with' => array('category'),
));
}         
else
{ //Пользователь ничего не выбрал из меню
$criteria=new CDbCriteria(array(
'condition'=>'t.shown=1 and category.shown=1',
'with' => array('category'),                              
));   
}
               
$dataProvider=new CActiveDataProvider('Assortiment',array(
'criteria'=>$criteria));
$this->render('index',array(
'dataProvider'=>$dataProvider,
));
}

Теперь меню заработало!
Осталось сделать так, чтобы выбранное меню подсвечивалось. Тут я немного застопорился, в мануале сказано, что это происходит автоматически, когда URL пункта меню совпадает с URL в браузере пользователя, но у меня ничего не подсвечивалось. Умный человек подсказал подправить стили CSS! Я так и сделал: во первых назначил меню id=usermenu и изменил его стиль в файле
Z:\home\catalog.loc\www\css\main.css добавил:
********************
    #usermenu
{
background:white url(bg.gif) repeat-x left top;
}

#usermenu ul
{
padding:6px 20px 5px 20px;
margin:0px;
}

#usermenu ul li
{
display: inline;
}

#usermenu ul li a
{
color:#6399cd;
background-color:transparent;
font-size:12px;
font-weight:bold;
text-decoration:none;
padding:5px 8px;
}

#usermenu ul li a:hover
{
color: #6399cd;
background-color:#E2EAF5;
text-decoration:none;
}
#usermenu ul li.active a
{
color: #EFF4FA;
background-color:#6399cd;
text-decoration:none;
}

********************
Вообще внешним видом я еще не занимался, это оставлю на последнее. А еще хотелось бы сделать это меню действующим без перезагрузки страницы то есть с помощью Ajax.
Продолжение следует.

10 комментариев:

  1. Я тоже начал изучать Yii и с трудом постигаю его возможности. Случайно наткнулся на ваш блог, довольно не плохо у вас получается разжевывать особенно для новичков как я. Не останавливайтесь на достигнутом.

    P.S.
    Еще бы вот была бы подсветка синтаксиса..

    ОтветитьУдалить
  2. Спасибо, рад стараться!
    Я сам новичек как в Yii, так и в ведении блога. Нахрапом поставить подсветку кода мне не удалось, когда найду как это сделать - обязательно поставлю. Интересно было узнать о ваших успехах в Yii

    ОтветитьУдалить
  3. "Назначили class usermenu", а в стилях пишете #.
    # - для id-шников.
    Класс же обозначается через .myClass{код css}
    Разве не так?

    ОтветитьУдалить
  4. Егор, вы правы, я обрамил меню пользователя тегом div id="usermenu"
    (исправил в посте) Спасибо!

    ОтветитьУдалить
  5. Хм, странно у меня не выводит товары в этой категории,как были все товары так и остались :(

    ОтветитьУдалить
    Ответы
    1. А переменная передается? адрес url меняется?

      Удалить
  6. вообще в правом меню класс "active" на выбранном елементе, достаточно строку добавить в таблицу стилей
    li.active
    {
    background: #FFFFFF;
    }

    ОтветитьУдалить
  7. И спасибо за ваш блог, очень хорошая идея посетила вас)

    ОтветитьУдалить
  8. а в каком файле и где надо прописать id = usermenu ? надо ли создавать для этого новый блок div, и где?

    ОтветитьУдалить
    Ответы
    1. Это в файле Z:\home\catalog.loc\www\protected\views\layouts\column2.php
      Да, добавлен div:

      ..
      .........
      else
      {
      echo "<div id=\"usermenu\">";
      $this->beginWidget('zii.widgets.CPortlet', array(
      'title'=>Yii::t('main-ui', 'Category'),
      ));
      $this->widget('zii.widgets.CMenu', array(
      'items'=>Category::All_shown(),
      'htmlOptions'=>array('class'=>'iconized' ),

      ));
      $this->endWidget();

      echo "</div><!-- usermenu-->";
      }
      ...

      Удалить