Одной из наиболее мощных возможностей фреймворка Yii является генерация кода. Она позволяет сразу после создания таблицы в базе данных получить файлы модели, контроллера и представлений. Т.е. весь необходимый код для выполнения CRUD операций.
Но, естественно, код формируется по стандартному шаблону, дизайн которого вам, возможно, захочется изменить.
Взгляните на обычную страницу управления записями, сформированную с помощью компонента CGridView.
Такая страница доступна по адресу
sitename.domen?r=controller/admin
Она состоит из трех частей.
1) Строки с номерами показанных записей и их количеством (summary
).
2) Таблицы с данными (items
).
3) Листалки (pager
). Если записей в таблице меньше, чем отображается на странице, этот элемент показан не будет.
Теперь взгляните на код, который создает такую таблицу.
<?php $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'cities-grid', 'dataProvider'=>$model->search(), 'filter'=>$model, 'columns'=>array( 'id', 'city', 'country', array( 'class'=>'CButtonColumn', ), ), )); ?>
Источником данных служит объект CActiveDataProvider
, который создается в контроллере. Но сейчас речь не о данных.
Попробуем изменить порядок вывода основных элементов.
CGridView
имеет параметр template
, который позволяет управлять выводом основных элементов страницы. Этот параметр принимает строку, в которой нужно перечислить необходимые элементы страницы.
Например, следующий код покажет листалку сверху и снизу страницы.
<?php $this->widget('zii.widgets.grid.CGridView', array( …, 'template'=>'{summary} {pager} {items} {pager}', 'columns'=>array( …, ), )); ?>
В шаблон можно вставлять произвольный текст и теги, но это не очень удобный вариант изменения разметки страницы. Лучше менять разметку внутри самих элементов и/или использовать CSS стили.
Если нужно изменить дизайн, то я бы рекомендовал делать в следующей последовательности.
1) Попытаться добиться результата, не меняя разметку, с помощью CSS стилей. Разметка, которую создаёт фреймворк, достаточна простая и соответствует стандартам.
2) Если необходимо, изменить разметку.
Рассмотрим первый вариант – использование своих CSS стилей.
По-умолчанию, для оформления CGridView
используются следующие CSS файлы:
1) Для оформления таблицы framework/zii/widgets/assets/gridview/styles.css
(он автоматически копируется в папку DOCUMENT_ROOT/accets/номер/gridview/styles.css
).
2) Для оформления листалки framework/web/widgets/pagers/pager.css
(он копируется в assets/номер/pager.css
).
Допустим, ваши стили находятся в файлах gridview-styles.css
и pager-styles.css
, которые расположены в папке DOCUMENT_ROOT/css
.
Подключаем файл со стилями таблицы, для этого передаем ссылку на файл в параметре cssFile
.
<?php $this->widget('zii.widgets.grid.CGridView', array( …, 'cssFile'=>Yii::app()->getBaseUrl(true).'/css/admin-styles.css', 'columns'=>array( …, ), )); ?>
В результате, фреймворк будет загружать ваш файл вместо стандартного.
Кроме того, есть несколько параметров (itemsCssClass
, rowCssClass
, summaryCssClass
и др.), которые позволяют указать ваши имена CSS классов. Но, вы можете использовать и стандартные имена классов, например, взять стандартный файл со стилями и переделывать его под свой дизайн.
Установка стилей для листалки (pager
) немного отличается.
Из CGridView
нужно получить доступ к атрибуту pager и устанавливать параметры для него.
<?php $this->widget('zii.widgets.grid.CGridView', array( …, 'pager'=>array('cssFile'=>Yii::app()->getBaseUrl(true).'/css/pager-styles.css'), 'columns'=>array( …, ), )); ?>
Код похожий, но параметр cssFile
передается в массиве и присваивается атрибуту pager
.
Тут возникает интересный вопрос: «Какие еще параметры мы можем передать в этом массиве?»
Любые атрибуты класса CBasePager
, а также его потомков, в том числе и имя класса-потомка, который используется для создания листалки.
В дистрибутив входит два таких класса CLinkPager
(создает список ссылок с номерами страниц, используется по-умолчанию) и CListPager
(создает выпадающий список с номерами страниц).
Заменить CLinkPager
на CListPager
можно так.
… 'pager'=>array('class'=>'CListPager'), …
Тут мы подходим к вопросу изменения разметки.
Допустим, нам нужно создать листалку в которой элементы страниц будут находиться внутри тегов span
, а не li
, как выводит CLinkPager
.
Можно, конечно, создать класс, производный от CBasePager
, но в данном случае будет удобнее наследовать CLinkPager
.
У меня получился такой код (файл protected/components /SpanLinkPager.php
).
class SpanLinkPager extends CLinkPager { public function run() { $buttons=$this->createPageButtons(); if(empty($buttons)) return; $this->registerClientScript(); echo $this->header; echo CHtml::tag('div',$this->htmlOptions,implode("\n",$buttons)); echo $this->footer; } protected function createPageButton($label,$page,$class,$hidden,$selected) { if($hidden || $selected) $class.=' '.($hidden ? self::CSS_HIDDEN_PAGE : self::CSS_SELECTED_PAGE); return '<span class="'.$class.'">'.CHtml::link($label,$this->createPageUrl($page)).'</span>'; } }
Я просто нашел в CLinkPager
методы, в который формируется разметка и переопределил их. Т.е. код остался тот же, просто ul
заменил на div
(строка 12), а li
— на span
(строка 20).
Используя такой же подход можно переопределить класс CGridView
и изменить разметку необходимым вам образом. Вот список основных методов, которые формируют разметку CGridView
:
renderItems
(находится в
renderTableHeader
renderTableFooter
renderTableBody
renderEmptyText
renderFilter
renderTableRow
renderSummaryCBaseListView
, который является предком CGridView
)
На этом мы остановимся. Конечно, в этой статье рассмотрены далеко не все нюансы использования компонента CGridView
. Например, он позволяет управлять выводом данных, а также использовать скины, но об этом как-нибудь в другой раз 🙂
Если у вас возникли вопросы или есть замечания, пишите, постараюсь ответить.
До встречи!