Темы оформления являются традиционным способом настроить внешний вид страниц веб-приложения. Применив новую тему, мы можем изменить внешний вид всего приложения за считанные секунды.
В 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
, код которого представлен ниже:
return array( 'default'=>array( 'nextPageLabel'=>'next', 'prevPageLabel'=>'prev', ), 'classic'=>array( 'header'=>'', 'maxButtonCount'=>5, ), );
В коде выше мы создаём для виджета CLinkPager два скина: default
и
classic
. Первый скин будет применяться к любому виджету CLinkPager, в
котором явно не указано свойство skin
, а второй — к виджету, свойство skin
которого имеет значение classic
. Например, в следующем коде представления
первым виджет будет использовать скин default
, а второй — скин classic
:
$this->widget('CLinkPager'); $this->widget('CLinkPager', array('skin'=>'classic'));
Если мы создаём виджет с набором первоначальных значений, они будут
иметь приоритет и будут объединены с любыми применяемыми скинами. Например,
следующий код представления создаст постраничную разбивку, чьи первоначальные значения —
это массив array('header'=>'', 'maxButtonCount'=>6, 'cssFile'=>false)
,
который является результатом слияния первоначальных значений,
указанных в представлении, и скина classic
.
$this->widget('CLinkPager', array( 'skin'=>'classic', 'maxButtonCount'=>6, 'cssFile'=>false, ));
Заметим, что скинизация НЕ требует использования темы. Однако, если тема
активна, Yii также будет искать скины в директории skins
представлений темы
(например, WebRoot/themes/classic/views/skins
). В случае, если скин с таким
же именем существует и в директории представления темы и в основной директории
представления приложения, скин темы будет иметь приоритет.
Если виджет использует несуществующий скин, Yii по-прежнему будет создавать виджет как обычно, без каких-либо ошибок.
Информация: Использование скина может привести к снижению производительности, поскольку Yii должен найти файл скина, когда виджет создается впервые.
Использование скинов очень похоже на глобальную конфигурацию виджетов. Главные отличия следующие:
Found a typo or you think this page needs improvement?
Edit it on github !
Signup or Login in order to comment.