Темизация в Yii2
Темизация — это способ заменить один набор представлений другим без переписывания кода, что замечательно подходит для изменения внешнего вида приложения.
Для того, чтобы начать использовать темизацию, настройте свойство [[yii\base\View::theme|theme]] компонента приложения view
. Конфигурация настраивает объект [[yii\base\Theme]], который отвечает за то, как именно заменяются файлы отображений. Главным образом, стоит настроить следующие свойства [[yii\base\Theme]]:
- [[yii\base\Theme::basePath]]: базовая директория, в которой размещены темизированные ресурсы (CSS, JS, изображения, и так далее).
- [[yii\base\Theme::baseUrl]]: базовый URL для доступа к темизированным ресурсам.
- [[yii\base\Theme::pathMap]]: правила замены файлов представлений. Подробно описаны далее.
Например, если вы вызываете $this->render('about')
в SiteController
, то будет использоваться файл отображения @app/views/site/about.php
. Тем не менее, если вы включите темизацию как показано ниже, то вместо него будет использоваться @app/themes/basic/site/about.php
.
return [
'components' => [
'view' => [
'theme' => [
'basePath' => '@app/themes/basic',
'baseUrl' => '@web/themes/basic',
'pathMap' => [
'@app/views' => '@app/themes/basic',
],
],
],
],
];
Info: При настройке тем поддерживаются псевдонимы пути. При замене отображений они преобразуются в реальные пути в файловой системе или URL.
Вы можете обратиться к объекту [[yii\base\Theme]] через свойство [[yii\base\View::theme]]. Например, в файле отображения, это будет выглядеть следующим образом (объект view доступен как $this
):
$theme = $this->theme;
// возвращает: $theme->baseUrl . '/img/logo.gif'
$url = $theme->getUrl('img/logo.gif');
// возвращает: $theme->basePath . '/img/logo.gif'
$file = $theme->getPath('img/logo.gif');
Свойство [[yii\base\Theme::pathMap]] определяет то, как заменяются файлы представлений. Свойство принимает массив пар ключ-значение, где ключи являются путями к оригинальным файлам, которые мы хотим заменить, а значения — соответствующие пути к файлам из темы. Замена основана на частичном совпадении: если путь к представлению начинается с любого из ключей массива [[yii\base\Theme::pathMap|pathMap]], то соответствующая ему часть будет заменена значением из того же массива. Для приведённой выше конфигурации @app/views/site/about.php
частично совпадает с ключом @app/views
и будет заменён на @app/themes/basic/site/about.php
.
Темизация модулей
Для того, чтобы темизировать модули, свойство [[yii\base\Theme::pathMap]] может быть настроено следующим образом:
'pathMap' => [
'@app/views' => '@app/themes/basic',
'@app/modules' => '@app/themes/basic/modules', // <-- !!!
],
Это позволит вам темизировать @app/modules/blog/views/comment/index.php
в @app/themes/basic/modules/blog/views/comment/index.php
.
Темизация виджетов
Для того, чтобы темизировать виджеты вы можете настроить свойство [[yii\base\Theme::pathMap]] следующим образом:
'pathMap' => [
'@app/views' => '@app/themes/basic',
'@app/widgets' => '@app/themes/basic/widgets', // <-- !!!
],
Это позволит вам темизировать @app/widgets/currency/views/index.php
в @app/themes/basic/widgets/currency/views/index.php
.
Наследование тем
Иногда требуется создать базовую тему, задающую общий вид приложения и далее изменять этот вид в зависимости, например, от сегодняшнего праздника. Добиться этого можно при помощи наследования тем. При этом один путь к файлу ставится в соответствие нескольким путям из темы:
'pathMap' => [
'@app/views' => [
'@app/themes/christmas',
'@app/themes/basic',
],
]
В этом случае представление @app/views/site/index.php
темизируется либо в @app/themes/christmas/site/index.php
, либо в @app/themes/basic/site/index.php
в зависимости от того, в какой из тем есть нужный файл. Если файлы присутствуют и там и там, используется первый из них. На практике большинство темизированных файлов будут расположены в @app/themes/basic
, а их версии для праздников в @app/themes/christmas
.
Заберите ссылку на статью к себе, чтобы потом легко её найти!
Раз уж досюда дочитали, то может может есть желание рассказать об этом месте своим друзьям, знакомым и просто мимо проходящим?
Не надо себя сдерживать! ;)