В этой части мы поговорим о том, какие средства предоставляет Yii для создания виджетов. Если верить википедии, виджет (widget) – это «контент модуль, который встраивается в веб-страницу или браузер» (вообще, это не совсем точно, в википедии есть несколько определений).
Правда здесь может возникнуть небольшая путаница в терминологии. Дело в том, что некоторые CMS (WordPress, например) используют термин виджет для обозначения особых плагинов, которые предназначены для отображения блоков с информацией в сайдбаре. Но сейчас нас интересует Yii PHP framework, поэтому мы будем считать виджетами объекты, которые наследуют класс CWidget.
Обычно виджеты используют для отображения какого-нибудь контента, который не зависит от основного содержимого страницы. Например, это может быть форма входа, перечень жанров игр, блок со случайными скриншотами, ссылки на страницы архива и т.п.
Для нас важно, что CWidget
имеет особенность. Он является потомком класса CComponent
, и, следовательно, является компонентом.
Рассмотрим, как создаются компоненты в фреймворке Yii.
Шаг 1. В папке protected/components
создаём файл с классом компонента. Этот класс выполняет инициализацию компонента и подготовку данных (например, чтение из БД).
Шаг 2. В папке protected/components/views
создаём файл с представлением компонента. По-сути это шаблон, который используется для отображения содержимого компонента.
Шаг 3. Добавляем компонент в макет (layout) нужных страниц сайта. Макеты находятся в папке protected/views/layouts
.
Теперь рассмотрим конкретный пример. Создадим виджет, содержащий ссылки на страницы жанров игр.
Назовём класс TypesMenu
.
Создаём файл protected/components/TypesMenu.php
.
class TypesMenu extends CWidget { public function run() { $types = Types::model()->findAll(); $this->render('typesMenu',array('types'=>$types)); } }
Как видите, класс содержит один метод (run
), который будет вызван фреймворком при создании виджета.
В этом методе мы получаем список всех жанров игр (строка 3) и результат передаём представлению (строка 5).
Создаём представление (файл protected/components/views/typesMenu.php
).
<h2>Жанры</h2> <ul> <?php foreach ($types as $type) { //каждый пункт списка - ссылка на страницу с играми данного жанра //жанр указывается с помощью параметра в get запросе - type_id echo '<li>'.CHtml::link($type->t_name, array('games/list', 'type_id'=>$type->t_id)).'</li>'; } ?> </ul>
Обратите внимание, у нас доступна переменная $types
. (её название мы указали при загрузке представления, метод render
).
Сами ссылки создаём с помощью метода CHtml::link
. В первом параметре указываем текст ссылки, а во втором – массив с параметрами. В данном случае будут созданы url вида
http://yiigame.domen/index.php?r=games/list&type_id=1
где type_id
– id соответствующего жанра.
Вставляем виджет в макет страницы. Для этого в файл protected/views/layouts/main.php
добавляем следующий код.
<div class="menu"> <?php $this->widget('application.components.TypesMenu'); ?> </div><!-- menu -->
Посмотрите, как указано имя виджета. Перед названием файла виджета (без расширения) мы добавляем application.components
, проще говоря, указываем путь к виджету.
Всё, мы получили работающий виджет, правда, самый примитивный. Давайте рассмотрим вариант немного посложнее.
На некоторых страницах сайта нам нужно выводить список с самыми популярными записями.
Популярность игры мы можем определить, используя поле g_rate
(таблица ygs_games
), т.е. нам нужно будет при поиске игр в базе просто отсортировать их по этому полю.
Показывать виджет нам нужно на страницах с общим перечнем игр и страницах отдельных жанров. И те, и другие страницы формирует метод actionList
(класс GamesController
). Но на страницах жанров мы будем показывать топ игр, которые относятся к данному жанру, а не все подряд, т.е. в наш запрос нужно будет добавить дополнительное условие.
Если задача ясна, приступаем.
Создаём файл виджета protected/components/TopGames.php
.
class TopGames extends CWidget { public $title = 'Популярные игры'; public $showOn = array(); public $count = 10; public function run() { //определяем название контроллера и метода (action) $controller = Yii::app()->controller->id; $action = Yii::app()->controller->action->id; //проверяем нужно ли показывать виджет if (!in_array($controller.'/'.$action, $this->showOn)) { return; } //проверяем, нужно ли выводить игры только данного жанра if (isset($_GET['type_id'])) { $id = $_GET['type_id']; $params = array('limit'=>$this->count,'order'=>'g_rate DESC' ,'condition'=>'t_id=:id' ,'params'=>array(':id'=>$id)); //ищем игры $games = Games::model()->getTopGames($params)->published()->with('ygs_types')->findAll(); } else { $params = array('limit'=>$this->count,'order'=>'g_rate DESC'); //ищем игры $games = Games::model()->getTopGames($params)->published()->findAll(); } //заполняем массивы с жанрами игр для каждой найденной игры //для этого раскодируем поле g_type foreach ($games as $key=>$game) { $games[$key]->g_types = Yii::app()->controller->_decodeTypes($game->g_type); } //показываем виджет $this->render('topGames' , array('title'=>$this->title, 'games'=>$games)); } }
Прежде всего, обратите внимание на три свойства класса $title
, $showOn
и $count
. Фреймворк позволяет указывать значения для всех отрытых (public) свойств виджета при его создании, т.е. в макете (layout) мы можем задать значения для этих свойств. Таким образом, появляется возможность изменять вид виджета, не трогая его код.
В данном случае в свойстве $title
мы указываем заголовок виджета, в свойстве $showOn
– массив с перечнем страниц, на которых он должен отображаться, а в свойстве $count
– количество игр.
Рассмотрим метод run
.
Прежде всего, определяем название контроллера и метода (action) (строки 9, 10). И проверяем, нужно ли показывать виджет. Страницы, на которых нужно отображать виджет указываются в формате «название_контроллера/название_метода». Если массив $showOn
не содержит подходящего элемента, мы завершаем работу виджета.
В противном случае, мы:
1) Проверяем, является ли эта страница, страницей жанра (получен параметр $_GET['type_id']
или нет). Если получен, формируем запрос, при этом в его параметрах мы указываем, что нам нужны игры только текущего жанра.
2) Если мы находимся на странице с общим перечнем игр, то просто получаем игры, отсортированные по полю g_rate
.
Обратите внимание на метод getTopGames($params)
. Он объявлен в модели (Games
) и нужен только для того, чтобы немного сократить запись запроса.
public function getTopGames($params) { $this->getDbCriteria()->mergeWith($params); return $this; }
Примечание. Использовать его не обязательно. Можно было просто создать объект CDbCriteria
, как мы и делали в предыдущих частях, но я хотел попробовать разные варианты работы.
3) Расшифровываем поле с перечнем жанров (эту операцию мы рассматривали в предыдущих частях).
4) Показываем представление при этом передаём ему заголовок виджета и данные игр.
Само представление выглядит так (файл protected/components/view/topGames.php
).
<h1><?php echo $title; ?></h1> <?php $i = 0; foreach($games as $n=>$model) { //шаблон для вывода игры находится в views/games/_short_desc.php $this->controller->renderPartial('_short_desc', array('game'=>$model)); if ($i % 2 !== 0) { echo '<div class="clear"></div>'; } $i++; } ?>
Как видите, для вывода игры мы использовали представление, которое относится к контроллеру Games
(views/games/_short_desc.php
).
Последний шаг – подключение шаблона в макете (файл protected/views/layouts/main.php
)
<div id="top_games" class="grid_9"> <?php $this->widget('application.components.TopGames' , array('title'=>'Популярные игры' ,'showOn'=>array('games/list','types/show') ,'count'=>4)); ?> </div><!-- top_games -->
Тут стоит отметить передачу параметров виджету. Они должны быть записаны в виде массива. При этом, ключ элемента должен совпадать с именем соответствующего свойства класса.
На этом мы остановимся. Думаю, общее представление о виджетах у вас появилось. Но в этой статье рассмотрены далеко не все их возможности, поэтому очень советую почитать соответствующий раздел справки.
Продолжение следует 😉
Все разделы цикла.
- Yii PHP framework: создаём игровой сайт. Часть 1. Постановка задачи.
- Yii PHP framework: создаём игровой сайт. Часть 2. База данных и установка фреймворка.
- Yii PHP framework: создаём игровой сайт. Часть 3. Аутентификация.
- Yii PHP framework: создаём игровой сайт. Часть 4. Работа с жанрами игр.
- Yii PHP framework: создаём игровой сайт. Часть 5. Импорт игр.
- Yii PHP framework: создаём игровой сайт. Часть 6. Формируем страницы игр и жанров.
- Yii PHP framework: создаём игровой сайт. Часть 7. Работа с JavaScript и страницы игр.
- Yii PHP framework: создаём игровой сайт. Часть 8. Создаём виджеты.
- Yii PHP framework: создаём игровой сайт. Часть 9. Поиск ошибок.
- Yii PHP framework: создаём игровой сайт. Часть 10. Панель управления.
- Yii PHP framework: создаём игровой сайт. Часть 11. Человекопонятные URL.
- Архив с исходниками