Yii PHP фреймворк: оформление административных страниц

Владимир | | HTML, PHP, Web разработка, Yii.

yii grid view

Одной из наиболее мощных возможностей фреймворка Yii является генерация кода. Она позволяет сразу после создания таблицы в базе данных получить файлы модели, контроллера и представлений. Т.е. весь необходимый код для выполнения CRUD операций.

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

Взгляните на обычную страницу управления записями, сформированную с помощью компонента CGridView.

basic grid thumb

Такая страница доступна по адресу
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
renderSummary
(находится в CBaseListView, который является предком CGridView)

На этом мы остановимся. Конечно, в этой статье рассмотрены далеко не все нюансы использования компонента CGridView. Например, он позволяет управлять выводом данных, а также использовать скины, но об этом как-нибудь в другой раз 🙂

Если у вас возникли вопросы или есть замечания, пишите, постараюсь ответить.

До встречи!