Теми оформлення =============== Теми оформлення є традиційним способом налаштувати зовнішній вигляд сторінок веб-додатку. Застосувавши нову тему, ми можемо змінити зовнішній вигляд всього додатка за лічені секунди. В Yii кожна тема представлена ​​як папка, що містить файли представлень, макетів та інших необхідних файлів, таких, як CSS, JavaScript та ін. Назва папки відповідно визначає назву теми. Всі теми зберігаються у папці `WebRoot/themes`, при цьому бути активною, тобто використовуватися у поточний момент, може тільки одна з тем. > Tip|Підказка: Папку, де за замовчуванням зберігаються теми — `WebRoot/themes` — можна легко змінити шляхом встановлення властивостей [basePath|CThemeManager::basePath] та [baseUrl|CThemeManager::baseUrl] компонента [themeManager|CWebApplication::themeManager] на бажані. Використання теми ----------------- Для активації теми потрібно встановити значення [theme|CWebApplication::theme] рівним імені відповідної теми. Це можна проробити шляхом [конфігурації додатку](/doc/guide/basics.application#application-configuration) або прямо під час виконання у діях контролера. > Note|Примітка: Імʼя теми чутливо до регістру, і, якщо спробувати активувати неіснуючу тему, властивість `Yii::app()->theme` поверне `null`. Створення теми -------------- Вміст папки з темами повинен бути організований точно так само, як і вміст [базової директорії додатку](/doc/guide/basics.application#application-base-directory), тобто, всі файли представлень повинні знаходитися у папці `views`, макети представлень у папці `views/layouts`, а файли системних представлень у папці `views/system`. Наприклад, якщо необхідно замінити представлення `create` контролера `PostController` на представлення теми `classic`, потрібно зберегти новий файл представлення як `WebRoot/themes/classic/views/post/create.php`. Для представлень контролерів у [модулях](/doc/guide/basics.module), відповідні файли оформлених представлень потрібно також помістити у папку `views`. Наприклад, якщо згаданий вище контролер `PostController` входить у модуль `forum`, необхідно зберегти файл представлення `create` як `WebRoot/themes/classic/views/forum/post/create.php`. Якщо модуль `forum` є складовою частиною іншого модуля `support`, то файл представлення повинен бути збережений як `WebRoot/themes/classic/views/support/forum/post/create.php`. > Note|Примітка: Папка `views` може містити чутливі дані, з точки зору безпеки, тому необхідно обмежити доступ до папки ззовні сервера. У момент виклику методу [render|CController::render] або [renderPartial|CController::renderPartial] для відображення представлення відбувається звернення до відповідних файлів представлень і макетів активної теми. Якщо файли знайдені, почнеться формування сторінки, у противному випадку, будуть використовуватися файли оформлення за замовчуванням, місце розташування яких встановлюється властивостями [viewPath|CController::viewPath] та [layoutPath|CWebApplication::layoutPath]. > Tip|Підказка: Часто у представленнях теми доводиться посилатися на інші файли теми, наприклад, для відображення картинки, що знаходиться у папці теми `images`. Використовуючи властивість [baseUrl|CTheme::baseUrl] активної теми, можна сформувати коректне посилання на зображення наступним чином: > ~~~ > [php] > 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 ~~~ У налаштуваннях додатку, якщо ми будемо використовувати: ~~~ [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`. Глобальне налаштування віджетів ------------------------------- > Note|Примітка: дана можливість доступна з версії 1.1.3. При використанні віджета, як стандартного, так і стороннього, часто потрібно його налаштування. Наприклад, може знадобитися змінити значення [CLinkPager::maxButtonCount] з 10 (за замовчуванням) на 5. Ми можемо зробити це, передавши початкові значення при виклику [CBaseController::widget] для створення віджета. Проте, робити це скрізь, де ми використовуємо [CLinkPager] досить незручно. ~~~ [php] $this->widget('CLinkPager', array( 'pages'=>$pagination, 'maxButtonCount'=>5, 'cssFile'=>false, )); ~~~ При використанні глобального налаштування, необхідно вказати початкові значення лише у одному місці — у файлі конфігурації додатка. Для цього налаштовуємо [widgetFactory|CWebApplication::widgetFactory] наступним чином: ~~~ [php] return array( 'components'=>array( 'widgetFactory'=>array( 'widgets'=>array( 'CLinkPager'=>array( 'maxButtonCount'=>5, 'cssFile'=>false, ), 'CJuiDatePicker'=>array( 'language'=>'ru', ), ), ), ), ); ~~~ Вище ми вказали глобальні налаштування віджетів [CLinkPager] та [CJuiDatePicker] за допомогою відповідних властивостей [CWidgetFactory::widgets]. Варто відзначити, що глобальні налаштування вказуються у вигляді пар ключ-масив значень, де ключ відповідає класу віджета, а масив значень задає початкові значення властивостей цього класу. Тепер кожного разу, коли ми використовуємо віджет [CLinkPager] у представленні, його властивостям будуть присвоєні зазначені вище початкові значення. Таким чином, щоб використовувати віджет буде достатньо наступного коду: ~~~ [php] $this->widget('CLinkPager', array( 'pages'=>$pagination, )); ~~~ Ми можемо перевизначити початкові значення, якщо у цьому є необхідність. Приміром, якщо у якомусь представленні ми хочемо задати `maxButtonCount` рівним 2, можна зробити наступне: ~~~ [php] $this->widget('CLinkPager', array( 'pages'=>$pagination, 'maxButtonCount'=>2, )); ~~~ Скіни ----- У той час, як при використанні теми ми можемо швидко змінювати вигляд представлень, ми також можемо використовувати скіни для налаштування вигляду [віджетів](/doc/guide/basics.view#widget), що використовуються у представленнях. Скін — це масив пар імʼя-значення, який може використовуватися для ініціалізації властивостей віджету. Скін належить до класу віджета, а клас віджета може мати кілька скінів, ідентифікованих іменем. Наприклад, у нас може бути скін `classic` для віджета [CLinkPager]. Для використання даної можливості нам, в першу чергу, необхідно змінити файл конфігурації додатку, виставивши властивість [CWidgetFactory::enableSkin] компонента `widgetFactory` у true: ~~~ [php] return array( 'components'=>array( 'widgetFactory'=>array( 'enableSkin'=>true, ), ), ); ~~~ У версіях Yii до 1.1.3 необхідно використовувати наступну конфігурацію: ~~~ [php] return array( 'components'=>array( 'widgetFactory'=>array( 'class'=>'CWidgetFactory', ), ), ); ~~~ Потім ми створюємо необхідні скіни. Скіни, що належать одному класу віджета, зберігаються у одному файлі PHP, імʼя якого збігається із назвою класу віджету. Всі файли скінів за замовчуванням зберігаються у директорії `protected/views/skins`. Для зміни директорії необхідно налаштувати властивість `skinPath` компонента `widgetFactory`. Наприклад, ми можемо створити у директорії `protected/views/skins` файл `CLinkPager.php`, код якого поданий нижче: ~~~ [php] array( 'nextPageLabel'=>'next', 'prevPageLabel'=>'prev', ), 'classic'=>array( 'header'=>'', 'maxButtonCount'=>5, ), ); ~~~ У коді вище ми створюємо для віджету [CLinkPager] два скіни: `default` та `classic`. Перший скін буде застосовуватися до будь-якого віджету [CLinkPager], у якого явно не вказана властивість `skin`, а другий — до віджету, властивість `skin` якого має значення `classic`. Наприклад, у наступному коді представлення першим віджет буде використовувати скін `default`, а другий — скін `classic`: ~~~ [php] widget('CLinkPager'); ?> widget('CLinkPager', array('skin'=>'classic')); ?> ~~~ Якщо ми створюємо віджет з набором первинних значень, вони будуть мати пріоритет і будуть обʼєднані з будь-якими застосовуваними скінами. Наприклад, наступний код представлення створить посторінкову розбивку, чиї початкові значення — це масив `array('header'=>'', 'maxButtonCount'=>6, 'cssFile'=>false)`, який є результатом злиття первинних значень, зазначених у представленні, і скіна `classic`. ~~~ [php] widget('CLinkPager', array( 'skin'=>'classic', 'maxButtonCount'=>6, 'cssFile'=>false, )); ?> ~~~ Зауважимо, що скінізація НЕ вимагає використання теми. Однак, якщо тема активна, Yii також буде шукати скіни у директорії `skins` представлень теми (наприклад, `WebRoot/themes/classic/views/skins`). У випадку, якщо скін з таким же імʼям існує і у директорії представлення теми і у основній директорії представлення додатку, скін теми буде мати пріоритет. Якщо віджет використовує неіснуючий скін, Yii як і раніше буде створювати віджет як звичайно, без будь-яких помилок. > Info|Інформація: Використання скіна може привести до зниження продуктивності, оскільки Yii повинен знайти файл скіна, коли віджет створюється вперше. Використання скінів дуже схоже на глобальну конфігурацію віджетів. Головні відмінності наступні: - Скіни більшою мірою відносяться до зміни властивостей, що відповідають за зовнішній вигляд віджету; - У віджета може бути кілька скінів; - Скін можна темізувати; - Використання скінів більш затратно, ніж використання глобальної конфігурації.