Оглавление

Начало Основы Работа с формами Работа с БД Кэширование Расширение Yii Тестирование Специальные темы
Зачем реклама?

Темы оформления

Темы оформления являются традиционным способом настроить внешний вид страниц веб-приложения. Применив новую тему, мы можем изменить внешний вид всего приложения за считанные секунды.

В Yii каждая тема представлена как папка, содержащая файлы представлений, макетов и прочих необходимых файлов, таких, как CSS, JavaScript и пр. Название папки соответственно определяет название темы. Все темы хранятся в папке WebRoot/themes, при этом быть активной, т.е. использоваться в текущий момент, может только одна из тем.

Подсказка: Папку, где по умолчанию хранятся темы — WebRoot/themes — можно легко изменить путем установки свойств basePath и baseUrl компонента themeManager на желаемые.

Использование темы #

Для активации темы нужно установить значение theme равным имени соответствующей темы. Это можно проделать путем конфигурации приложения или прямо в ходе выполнения в действиях контроллера.

Примечание: Имя темы чувствительно к регистру, и, если попытаться активировать несуществующую тему, свойство Yii::app()->theme вернет null.

Создание темы #

Содержимое папки с темами должно быть организовано точно так же, как и содержимое базовой директории приложения, то есть, все файлы представлений должны находиться в папке views, макеты представлений в папке views/layouts, а файлы системных представлений в папке views/system. Например, если необходимо заменить представление create контроллера PostController на представление темы classic, нужно сохранить новый файл представления как WebRoot/themes/classic/views/post/create.php.

Для представлений контроллеров в модулях, соответствующие файлы оформленных представлений нужно также поместить в папку views. Например, если упомянутый выше контроллер PostController входит в модуль forum, необходимо сохранить файл представления create как WebRoot/themes/classic/views/forum/post/create.php. Если модуль forum является составной частью другого модуля support, то файл представления должен быть сохранен как WebRoot/themes/classic/views/support/forum/post/create.php.

Примечание: Папка views может содержать данные чувствительные с точки зрения безопасности, поэтому необходимо ограничить доступ к папке извне сервера.

В момент вызова метода render или renderPartial для отображения представления происходит обращение к соответствующим файлам представлений и макетов активной темы. Если файлы найдены, начнется формирование странички, в противном случае, будут использоваться файлы оформления по умолчанию, месторасположение которых устанавливается свойствами viewPath и layoutPath.

Подсказка: Часто в представлениях темы приходится ссылаться на прочие файлы темы, например, для отображения картинки, находящейся в подпапке темы images. Используя свойство baseUrl активной темы, можно сформировать корректную ссылку на картинку следующим образом:

Yii::app()->theme->baseUrl '/images/FileName.gif'

Ниже приведён пример организации директорий приложения с двумя темами basic и fancy:

WebRoot/
	assets
	protected/
		.htaccess
		components/
		controllers/
		models/
		views/
			layouts/
				main.php
			site/
				index.php
	themes/
		basic/
			views/
				.htaccess
				layouts/
					main.php
				site/
					index.php
		fancy/
			views/
				.htaccess
				layouts/
					main.php
				site/
					index.php

В настройках приложения, если мы будем использовать:

return array(
    
'theme'=>'basic',
    

);

то будет применяться тема basic. То есть главный макет (layout) будет браться из themes/basic/views/layouts, а представление index — из themes/basic/views/site. Если файл представления не найден в теме, будет использован файл из protected/views.

Темизация виджетов #

Начиная с версии 1.1.5, отображения, используемые в виджетах, можно темизировать. При вызове CWidget::render() для вывода отображения, Yii сделает попытку найти его в темах перед тем, как загрузить из директории виджета.

Для темизации отображения xyz виджета с именем класса Foo, необходимо создать директорию Foo (с тем же именем, что и у класса) внутри директории с отображениями активной темы. Если класс виджета находится в пространстве имён (начиная с PHP 5.3.0), таком как \app\widgets\Foo, то необходимо создать директорию app_widgets_Foo. В имени мы заменяем разделители пространства имён на подчёркивание.

После этого создаём файл отображения xyz.php в только что добавленной директории. К этому моменту мы имеем файл themes/basic/views/Foo/xyz.php, который и будет использоваться виджетом вместо его собственного отображения, если активная тема — basic.

Глобальная настройка виджетов #

Примечание: данная возможность доступна с версии 1.1.3.

При использовании виджета, как стандартного, так и стороннего, часто требуется его настройка. К примеру, может понадобиться изменить значение CLinkPager::maxButtonCount с 10 (по умолчанию) на 5. Мы можем сделать это, передав начальные значения при вызове CBaseController::widget для создания виджета. Тем не менее, делать это везде, где мы используем CLinkPager довольно неудобно.

$this->widget('CLinkPager', array(
    
'pages'=>$pagination,
    
'maxButtonCount'=>5,
    
'cssFile'=>false,
));

При использовании глобальной настройки, необходимо указать начальные значения лишь в одном месте — в файле конфигурации приложения. Для этого настраиваем widgetFactory следующим образом:

return array(
    
'components'=>array(
        
'widgetFactory'=>array(
            
'widgets'=>array(
                
'CLinkPager'=>array(
                    
'maxButtonCount'=>5,
                    
'cssFile'=>false,
                ),
                
'CJuiDatePicker'=>array(
                    
'language'=>'ru',
                ),
            ),
        ),
    ),
);

Выше мы указали глобальные настройки виджетов CLinkPager и CJuiDatePicker при помощи соответствующих свойств CWidgetFactory::widgets. Стоит отметить, что глобальные настройки указываются в виде пар ключ-массив значений, где ключ соответствует классу виджета, а массив значений задаёт начальные значения свойств этого класса.

Теперь всякий раз, когда мы используем виджет CLinkPager в отображении, его свойствам будут присвоены указанные выше начальные значения. Таким образом, чтобы использовать виджет будет достаточно следующего кода:

$this->widget('CLinkPager', array(
    
'pages'=>$pagination,
));

Мы можем переопределить начальные значения, если в этом есть необходимость. К примеру, если в каком-нибудь отображении мы хотим задать maxButtonCount равным 2, можно сделать следующее:

$this->widget('CLinkPager', array(
    
'pages'=>$pagination,
    
'maxButtonCount'=>2,
));

Скины #

В то время, как при использовании темы мы можем быстро менять вид представлений, мы также можем использовать скины для настройки вида виджетов, используемых в представлениях.

Скин — это массив пар имя-значение, который может использоваться для инициализации свойств виджета. Скин принадлежит классу виджета, а класс виджета может иметь несколько скинов, идентифицируемых по имени. Например, у нас может быть скин classic для виджета CLinkPager.

Для использования данной возможности нам, в первую очередь, необходимо изменить файл конфигурации приложения, выставив свойство CWidgetFactory::enableSkin компонента widgetFactory в true:

return array(
    
'components'=>array(
        
'widgetFactory'=>array(
            
'enableSkin'=>true,
        ),
    ),
);

В версиях Yii до 1.1.3 необходимо использовать следующую конфигурацию:

return array(
    
'components'=>array(
        
'widgetFactory'=>array(
            
'class'=>'CWidgetFactory',
        ),
    ),
);

Затем мы создаём необходимые скины. Скины, принадлежащие одному классу виджета, хранятся в одном файле PHP, имя которого совпадает с названием класса виджета. Все файлы скинов по умолчанию хранятся в директории protected/views/skins. Для изменения директории надо настроить свойство skinPath компонента widgetFactory. Например, мы можем создать в директории protected/views/skins файл CLinkPager.php, код которого представлен ниже:

<?php
return array(
    
'default'=>array(
        
'nextPageLabel'=>'next',
        
'prevPageLabel'=>'prev',
    ),
    
'classic'=>array(
        
'header'=>'',
        
'maxButtonCount'=>5,
    ),
);

В коде выше мы создаём для виджета CLinkPager два скина: default и classic. Первый скин будет применяться к любому виджету CLinkPager, в котором явно не указано свойство skin, а второй — к виджету, свойство skin которого имеет значение classic. Например, в следующем коде представления первым виджет будет использовать скин default, а второй — скин classic:

<?php $this->widget('CLinkPager'); ?>

<?php $this->widget('CLinkPager', array('skin'=>'classic')); ?>

Если мы создаём виджет с набором первоначальных значений, они будут иметь приоритет и будут объединены с любыми применяемыми скинами. Например, следующий код представления создаст постраничную разбивку, чьи первоначальные значения — это массив array('header'=>'', 'maxButtonCount'=>6, 'cssFile'=>false), который является результатом слияния первоначальных значений, указанных в представлении, и скина classic.

<?php $this->widget('CLinkPager', array(
    
'skin'=>'classic',
    
'maxButtonCount'=>6,
    
'cssFile'=>false,
)); 
?>

Заметим, что скинизация НЕ требует использования темы. Однако, если тема активна, Yii также будет искать скины в директории skins представлений темы (например, WebRoot/themes/classic/views/skins). В случае, если скин с таким же именем существует и в директории представления темы и в основной директории представления приложения, скин темы будет иметь приоритет.

Если виджет использует несуществующий скин, Yii по-прежнему будет создавать виджет как обычно, без каких-либо ошибок.

Информация: Использование скина может привести к снижению производительности, поскольку Yii должен найти файл скина, когда виджет создается впервые.

Использование скинов очень похоже на глобальную конфигурацию виджетов. Главные отличия следующие:

  • Скины в большей степени относятся к изменению свойств, отвечающих за внешний вид виджета;
  • У виджета может быть несколько скинов;
  • Скин можно темизировать;
  • Использование скинов более затратно, чем использование глобальной конфигурации.

Зачем реклама?