Одной из наиболее мощных возможностей фреймворка 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. Например, он позволяет управлять выводом данных, а также использовать скины, но об этом как-нибудь в другой раз 🙂
Если у вас возникли вопросы или есть замечания, пишите, постараюсь ответить.
До встречи!


