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

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

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

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

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

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

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

2. Создание темы

Содержимое папки с темами должно быть организовано точно так же, как и содержимое базовой директории приложения, то есть, все файлы представлений должны находиться в папке 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.

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

Начиная с версии 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.

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

Примечание: данная возможность доступна с версии 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,
));

5. Скины

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

Скин — это массив пар имя-значение, который может использоваться для инициализации свойств виджета. Скин принадлежит классу виджета, а класс виджета может иметь несколько скинов, идентифицируемых по имени. Например, у нас может быть скин 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 должен найти файл скина, когда виджет создается впервые.

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

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

Be the first person to leave a comment

Please to leave your comment.