sidebar легко, используем CClipWidget

Обсуждение документации. Переводы Cookbook и авторские рецепты.
Аватара пользователя
slavcodev
Сообщения: 3133
Зарегистрирован: 2009.04.02, 21:42
Откуда: Altea, Spain
Контактная информация:

sidebar легко, используем CClipWidget

Сообщение slavcodev » 2010.12.27, 13:13

Принимаю идею как назвать рецепт, потому как мой вариант мне не нравится, но другого нет.

Sidebar или узкая колонка на сайте (слева, справа, где угодно :)), используется очень часто.
Но как вы, удобнее всего это реализуете? Ведь на разных страницах эта панель может отличаться.
Я перепробовал несколько вариантов:
- компонент приложения в который добавлял виджеты

Код: Выделить всё

Yii::app()->sidebar->addWidget($name,$data); 
- несколько layout'ов унаследованные друг от друга

Код: Выделить всё

$this->beginContent('layout-2');
$this->endContent(); 
И все не то, искал более удобного способа. Конечно же удобноДляМеня != удобноДляВсех, поэтому расскажу свой метод, в надежде что поделитесь своим.
И жили они долго и счастливо :D (У меня хорошее настроение, праздничное)

Начну. Метод заключается в использовании виджета CClipWidget, или точнее CController::$clips, что практически тоже самое.
Пишем свой шаблон views\layouts\main.php

Код: Выделить всё

<?php
// head, body - пропустил
echo CHtml::opentTag('div',array('id'=>'page'));
  echo $content;
echo CHtml::closeTag('div');

echo CHtml::opentTag('div',array('id'=>'sidebar'));
  // проверять существование не нужно, проверка происходит CMap::itemAt(), зачем лишний раз проверять?
  echo $this->clips['sidebar'];
echo CHtml::closeTag('div'); 
Теперь в наших представлениях views\default\index.php

Код: Выделить всё

/*начинаем записывать клип*/
$this->beginClip('sidebar');
  echo CHtml::tag('h1',array(),'Наш sidebar');
  /*вывели календарь*/
  $this->widget('calendarPortlet');
  /*вывели облако тегов*/
  $this->widget('tagsPortlet');
$this->endClip();
/*закончили с панелью*/

/*дальше контент*/
echo CHtml::tag('h1',array(),'Главная страница'); 
UPDATE#1 (добавлено 2011-03-19)
Можно воспользоваться магией геттеров и сеттеров Yii:

Код: Выделить всё

/*начинаем записывать клип*/
$this->clips['sidebar'].=CHtml::tag('h1',array(),'Наш sidebar');
/*вывели календарь*/
$this->clips['sidebar'].=$this->widget('calendarPortlet',array(),true);
/*вывели облако тегов*/
$this->clips['sidebar'].=$this->widget('tagsPortlet',array(),true);
/*закончили с панелью*/

/*дальше контент*/
echo CHtml::tag('h1',array(),'Главная страница'); 
Вроде все. А вы как делаете панели?
Жду Yii 3!

Аватара пользователя
Svyatov
Сообщения: 459
Зарегистрирован: 2010.08.12, 14:50
Откуда: Санкт-Петербург
Контактная информация:

Re: sidebar легко, используем CClipWidget

Сообщение Svyatov » 2010.12.27, 16:32

Как вариант интересно, но по-моему не очень гибко. Получается для добавления нового элемента в сайдбар надо править все представления. Имхо, сайдбар сам должен быть вынесен в виджет, в котором будет сосредоточена логика на какой странице что показывать, чтобы добавлять/удалять элементы можно было в одном месте.

Аватара пользователя
slavcodev
Сообщения: 3133
Зарегистрирован: 2009.04.02, 21:42
Откуда: Altea, Spain
Контактная информация:

Re: sidebar легко, используем CClipWidget

Сообщение slavcodev » 2010.12.27, 16:41

Ооо, мне кажется мы замучаемся следить в виджете какая страница открыта, учитывая что их может очень много. Я считаю наоборот гибче делать это в представлении. Не так часто меняется представление, как добавляется новая страница. Честно не ивжу большой разницы, лезть каждый раз в виджет чтоб что-то поменять в сайдбаре или в представление.
Жду Yii 3!

Аватара пользователя
Svyatov
Сообщения: 459
Зарегистрирован: 2010.08.12, 14:50
Откуда: Санкт-Петербург
Контактная информация:

Re: sidebar легко, используем CClipWidget

Сообщение Svyatov » 2010.12.27, 17:03

В общем нужно отталкиваться от конкретного случая. Если страниц много, но там почти одно и то же, то лучше сделать 1 виджет. Если сайдбар очень сильно разный везде, то лучше определять это в представлении.

Аватара пользователя
slavcodev
Сообщения: 3133
Зарегистрирован: 2009.04.02, 21:42
Откуда: Altea, Spain
Контактная информация:

Re: sidebar легко, используем CClipWidget

Сообщение slavcodev » 2010.12.27, 17:08

Ну это да. суть рецепта была показать как можно в шаблоне использовать больше переменных кроме $content )
Потому что знаю по себе, многие возможности фреймворка просто забываются.
Жду Yii 3!

Аватара пользователя
Svyatov
Сообщения: 459
Зарегистрирован: 2010.08.12, 14:50
Откуда: Санкт-Петербург
Контактная информация:

Re: sidebar легко, используем CClipWidget

Сообщение Svyatov » 2010.12.27, 17:12

Согласен. За рецепт спасибо.

Аватара пользователя
Svyatov
Сообщения: 459
Зарегистрирован: 2010.08.12, 14:50
Откуда: Санкт-Петербург
Контактная информация:

Re: sidebar легко, используем CClipWidget

Сообщение Svyatov » 2011.01.18, 11:03

mc-bear писал(а):Еще можно вот это почитать
Что за рекурсия? :)

Аватара пользователя
slavcodev
Сообщения: 3133
Зарегистрирован: 2009.04.02, 21:42
Откуда: Altea, Spain
Контактная информация:

Re: sidebar легко, используем CClipWidget

Сообщение slavcodev » 2011.01.18, 11:36

Svyatov писал(а):
mc-bear писал(а):Еще можно вот это почитать
Что за рекурсия? :)
:lol: перепутал темы
Жду Yii 3!

Аватара пользователя
SowenoK
Сообщения: 43
Зарегистрирован: 2011.03.17, 18:09
Откуда: Россия, Краснодар
Контактная информация:

Re: sidebar легко, используем CClipWidget

Сообщение SowenoK » 2011.03.18, 11:44

Спасибо, очень полезная и нужная тема.
Самурай без меча - это тоже, что самурай с мечом, но только без меча.

Аватара пользователя
SowenoK
Сообщения: 43
Зарегистрирован: 2011.03.17, 18:09
Откуда: Россия, Краснодар
Контактная информация:

Re: sidebar легко, используем CClipWidget

Сообщение SowenoK » 2011.03.18, 13:55

А можно поинтересоваться зачем тэги писать таким образом?

Код: Выделить всё

echo CHtml::opentTag('div',array('id'=>'page'));
  echo $content;
echo CHtml::closeTag('div'); 
В этом есть какое-то преимущество перед стандартным написанием?
Самурай без меча - это тоже, что самурай с мечом, но только без меча.

Аватара пользователя
slavcodev
Сообщения: 3133
Зарегистрирован: 2009.04.02, 21:42
Откуда: Altea, Spain
Контактная информация:

Re: sidebar легко, используем CClipWidget

Сообщение slavcodev » 2011.03.18, 14:15

Нет, просто мне не нравятся смешивать html и php.
Поэтому где можно я этого не делаю.
Плюс атрибуты дива, ведь можно передавать в виде переменной.

Код: Выделить всё

echo CHtml::opentTag('div',$pageDivAttr); 
и вообще такие просты конструкции можно так писать

Код: Выделить всё

echo CHtml::tag('div',array('id'=>'page'),$content); 
согласись красивее чем html вписывать.
Жду Yii 3!

Аватара пользователя
SowenoK
Сообщения: 43
Зарегистрирован: 2011.03.17, 18:09
Откуда: Россия, Краснодар
Контактная информация:

Re: sidebar легко, используем CClipWidget

Сообщение SowenoK » 2011.03.18, 15:03

Да, действительно, красивее и лаконичнее получилось.
Самурай без меча - это тоже, что самурай с мечом, но только без меча.

mrix
Сообщения: 125
Зарегистрирован: 2010.08.30, 11:48
Откуда: Россия, Новосибирск

Re: sidebar легко, используем CClipWidget

Сообщение mrix » 2011.03.19, 08:04

mc-bear писал(а):Нет, просто мне не нравятся смешивать html и php.
Поэтому где можно я этого не делаю.
Плюс атрибуты дива, ведь можно передавать в виде переменной.

Код: Выделить всё

echo CHtml::opentTag('div',$pageDivAttr); 
и вообще такие просты конструкции можно так писать

Код: Выделить всё

echo CHtml::tag('div',array('id'=>'page'),$content); 
согласись красивее чем html вписывать.
Красивее, но очень медленно. Сделайте в цикле 1000 и уже заметите.

Аватара пользователя
slavcodev
Сообщения: 3133
Зарегистрирован: 2009.04.02, 21:42
Откуда: Altea, Spain
Контактная информация:

Re: sidebar легко, используем CClipWidget

Сообщение slavcodev » 2011.03.19, 13:32

mrix, завидую твой чувствительности

Код: Выделить всё

<?php$content='Lorem ipsum dolor sit amet lorem pulvinar dolor aliquet vel enim elit rhoncus cum rhoncus. Rhoncus mus adipiscing rhoncus proin odio nascetur rhoncus magna sagittis nec. Scelerisque aliquet integer purus ut integer pulvinar nisi cras, placerat hac. Quis cum rhoncus nunc nunc non odio! Aliquet ut! Etiam nec adipiscing porta pulvinar.';
$count=1000;
Yii::beginProfile('php');
for($i=0;$i<$count;$i++)
{
    echo CHtml::tag('div',array('class'=>'test'),$content);
}
Yii::endProfile('php');
Yii::beginProfile('html');
for($i=0;$i<$count;$i++)
{
    ?>
    <div class="test"><?php echo $content;?></div>
    <?php
}
Yii::endProfile('html');
Итого
php: 12:27:07.716133-12:27:07.724899=8766
html: 12:27:07.724905-12:27:07.725461=556
Увеличив количество $count=10000
php: 12:25:08.204972-12:25:08.299206=204.972
html: 12:25:08.299217-12:25:08.334821=35.604
Разница меньше секунды, стоит ли замарачиватся на этом?
Незабываем что есть кеширование контента.
Жду Yii 3!

Аватара пользователя
slavcodev
Сообщения: 3133
Зарегистрирован: 2009.04.02, 21:42
Откуда: Altea, Spain
Контактная информация:

Re: sidebar легко, используем CClipWidget

Сообщение slavcodev » 2011.03.19, 16:51

Обновил рецепт, смотрите первый пост.
Жду Yii 3!

Аватара пользователя
SowenoK
Сообщения: 43
Зарегистрирован: 2011.03.17, 18:09
Откуда: Россия, Краснодар
Контактная информация:

Re: sidebar легко, используем CClipWidget

Сообщение SowenoK » 2011.03.23, 13:21

Подскажите, как передать переменную из контроллера в layout? у меня получается только во вьюв, который я рэндерю.
Самурай без меча - это тоже, что самурай с мечом, но только без меча.

rak
Сообщения: 2021
Зарегистрирован: 2010.11.02, 23:40
Контактная информация:

Re: sidebar легко, используем CClipWidget

Сообщение rak » 2011.03.23, 14:32

можно добавить свойство в контроллер
public $property;
а в лайауте использовать
$this->property

Аватара пользователя
SowenoK
Сообщения: 43
Зарегистрирован: 2011.03.17, 18:09
Откуда: Россия, Краснодар
Контактная информация:

Re: sidebar легко, используем CClipWidget

Сообщение SowenoK » 2011.03.23, 15:32

присвоение переменной происходит в функции, почему-то переменная не передаётся...

Код: Выделить всё

<?php
class SiteController extends Controller
{
public $username;
public function actionIndex()
    {
        $username = 'Иван Иванович';
        // renders the view file 'protected/views/site/index.php'
        // using the default layout 'protected/views/layouts/main.php'
        $this->render('index');
    }
}
 
Самурай без меча - это тоже, что самурай с мечом, но только без меча.

Аватара пользователя
slavcodev
Сообщения: 3133
Зарегистрирован: 2009.04.02, 21:42
Откуда: Altea, Spain
Контактная информация:

Re: sidebar легко, используем CClipWidget

Сообщение slavcodev » 2011.03.23, 16:36

Код: Выделить всё

$this->username = 'Иван Иванович'; 
Вопросы в другом разделе форума. Заканчиваем флудить.
Жду Yii 3!

dostoevskiy.spb
Сообщения: 5
Зарегистрирован: 2012.06.20, 00:41

Re: sidebar легко, используем CClipWidget

Сообщение dostoevskiy.spb » 2012.07.10, 21:28

В Yii я новенький, тесно стало мне на Kohana. Сталкивался со случаем, когда мне надо было в заисимости от раздела загружать разные сайдбары. Таких разных было 4 штуки, и одна страница без сайдбара вообще. Когда делал, с Yii занком не был, но сейчас, как оказалось использовал похожий, но немного отличающийся подход. Делюсь:
Было сделано 2 layout. Один с сайдбаром, один без.
С сайдбаром:

Код: Выделить всё

<div id='sidebar'>
<?=$sidebar?>
</div>
<div id=''content''>
<?=$content?>
</div>
Без:

Код: Выделить всё

<div id=''content''>
<?=$content?>
</div>
Далее я создал свой конфиг для приложения, в котором сделал так:

Код: Выделить всё

return array(
    'news' => array(
        'per_page' => 6,
        'aside'    => 'news',
        'slider'   => 6
    ),
    'home'     => array(
        'aside'    => FALSE,
        'per_page' => FALSE,
    ),
    'shop'     => array(
        'aside'    => 'shop',
        'per_page' => 6,
    ),
    'blog'     => array(
        'aside'    => 'news',
        'per_page' => 6,
    ),
    'video'    => array(
        'aside'    => 'shop',
        'per_page' => 6,
    ),
    'training' => array(
        'aside'    => 'shop',
        'per_page' => 6,
    ),
    'profile'  => array(
        'aside' => array(
            'login'    => FALSE,
            'register' => FALSE,
            'index'    => 'profile',
            'profile'  => 'profile'
        ),
    ),
);
 
.
Как видите, по ключам можно получить имя файла представления, используемого для рендеринга сайдбара в соответствии с выбранным разделом.
Вывел это все в автоматику в свой абстрактный контроллер-прародитель всех контроллеров, обладающий базовыми функциями, ну и в зависимости от текущего раздела подгружающий макет с сайдбаром или без, а так же генерирующий при надобности нужный сайдбар. Очень удобно. Потом занимался только тем, что генерировал правильный $Content. Пеимущество в том, что можно все отредактировать только одном файле и для всех разделов сразу. Если заметите, то в конфиге у меня еще есть переменная $per_page указывающая количество записей на странице для пагинатора. Фидбэк и обмен мнениями приветствуется.

Ответить