Как правильно писать "usr.theme" или "cfg.defaulttheme"

Настоящая статья систематизирует знания о механизмах темизации Cotonti и даёт однозначный ответ на поставленный вопрос. Материал рассчитан как на начинающих разработчиков, так и на опытных специалистов

0 Опубликована Опубликовано в: Cotonti Siena CMF > Cotonti - чтиво. Документация.

Как правильно: Cot::$usr['theme'] или Cot::$cfg['defaulttheme']?

Содержание

  1. Введение
  2. Назначение файла .rc.php в архитектуре Cotonti
    1. Определение
    2. Место в архитектуре CMF
    3. Подключение файла движком
    4. Условия подключения
    5. Позиция в последовательности выполнения
  3. Переменные $usr['theme'] и $cfg['defaulttheme']
    1. Переменная $cfg['defaulttheme']
    2. Переменная $usr['theme']
    3. Возможные значения $usr['theme']
    4. Связь между переменными
  4. Механизм подключения .rc.php движком
    1. Пошаговый разбор
    2. Что доступно внутри .rc.php
    3. Что гарантировано
  5. Взаимосвязь и приоритет переменных
    1. Отсутствие приоритета
    2. Правило выбора
    3. Обоснование
    4. Официальная позиция Cotonti
  6. Практические сценарии эксплуатации
    1. Сценарий A. Единственная тема, форсирование включено
    2. Сценарий B. Единственная тема, форсирование выключено
    3. Сценарий C. Несколько тем, пользовательские предпочтения
    4. Сценарий D. Изменение defaulttheme
    5. Сценарий E. Тема-заглушка (fallback)
    6. Сводная таблица сценариев
  7. Правила оформления файла .rc.php
    1. Общие требования
    2. Рекомендации по структуре
    3. Рекомендации по порядку ресурсов
    4. Рекомендации по размещению
    5. Шаблон файла
  8. Справочник по классу Resources
    1. Публичные методы
    2. Предопределённые алиасы
    3. Механизм scope
    4. Механизм order
    5. Консолидация и минификация
  9. Типичные ошибки и способы их устранения
    1. Использование $cfg['defaulttheme'] для путей к ресурсам темы
    2. Использование переменной $theme
    3. Дублирование ресурсов
    4. Размещение CSS в футере
    5. Размещение всех JS в head
    6. Игнорирование исключения addFile
    7. Изменение $theme_reload
    8. Использование устаревших обёрток
    9. Некорректный order
    10. Обращение к базе данных
  10. Диагностика и отладка
    1. Проверка значения переменных
    2. Проверка подключения файла
    3. Проверка реестра ресурсов
    4. Проверка консолидации
    5. Проверка исключений
    6. Включение режима отладки
  11. Заключение

1. Введение

При разработке темы для Cotonti CMF разработчик сталкивается с необходимостью подключения CSS и JavaScript ресурсов в файле .rc.php. Возникает закономерный вопрос: какую переменную использовать для построения путей к ресурсам темы — Cot::$usr['theme'] или Cot::$cfg['defaulttheme']?

На первый взгляд, разница между этими переменными минимальна, и многие готовые темы используют Cot::$cfg['defaulttheme']. Однако такой подход работает лишь в ограниченном наборе конфигураций. В общем случае он приводит к поломке путей, исключениям в Resources::addFile() и падению фронтальной части сайта.

Настоящая статья систематизирует знания о механизмах темизации Cotonti и даёт однозначный ответ на поставленный вопрос. Материал рассчитан как на начинающих разработчиков, так и на опытных специалистов, знакомых с внутренним устройством CMF.

2. Назначение файла .rc.php в архитектуре Cotonti

2.1. Определение

Файл .rc.php (от англ. resource control) — это вспомогательный файл темы Cotonti, который регистрирует CSS и JavaScript ресурсы в статическом реестре класса Resources. Движок затем выводит эти ресурсы в <head> страницы и в футер.

Файл не является ни плагином, ни модулем, ни самостоятельной темой. Он относится к категории вспомогательных файлов темы наряду с {theme}.php (файл переопределения языковых и ресурсных строк) и {theme}.tpl (шаблоны).

2.2. Место в архитектуре CMF

Регистрация и вывод ресурсов выполняются классом Resources, который расположен в файле system/resources.php. Класс хранит следующие статические структуры:

  • $registry — реестр ресурсов <head> при включённой консолидации;
  • $headerRc — реестр ресурсов <head> без консолидации;
  • $footerRc — реестр ресурсов футера;
  • $addedFiles — карта уже добавленных файлов (для дедупликации);
  • $alias — карта предопределённых алиасов (@jQuery, @bootstrap, @select2 и другие);
  • флаги $cacheOn, $consolidate, $minify, $isAdmin, $headerComplete, $htmlCleanupEnabled.

Инициализация класса выполняется методом Resources::__init(), который вызывается в конце файла resources.php. Метод читает настройки из массива $cfg:

  • cache — глобальный флаг кэширования;
  • headrc_consolidate — флаг консолидации ресурсов;
  • headrc_minify — флаг минификации;
  • html_cleanup — флаг очистки HTML от лишних пробелов;
  • cache_dir — директория кэша;
  • dir_perms — права на создаваемые директории.

Флаг $isAdmin устанавливается по значению константы COT_ADMIN. Для фронтальной части сайта $isAdmin === false, что разрешает работу консолидации и минификации при условии, что они включены в конфигурации.

2.3. Подключение файла движком

Файл .rc.php подключается движком в секции Head Resources файла system/common.php:

if (!defined('COT_ADMIN')) {
    if (file_exists("{$cfg['themes_dir']}/{$usr['theme']}/{$usr['theme']}.rc.php")) {
        include "{$cfg['themes_dir']}/{$usr['theme']}/{$usr['theme']}.rc.php";
    }
}

Анализ этого фрагмента даёт три ключевых факта:

  1. Проверяется существование файла по пути themes/{$usr['theme']}/{$usr['theme']}.rc.php.
  2. Если файл существует — он подключается оператором include.
  3. Имя темы берётся из переменной $usr['theme'], а не из $cfg['defaulttheme'].

Из этого следует фундаментальный вывод: в момент выполнения файла .rc.php переменная $usr['theme'] гарантированно равна имени текущей темы. Если бы это было не так, файл не был бы подключён.

2.4. Условия подключения

Файл .rc.php подключается при соблюдении следующих условий:

  • константа COT_ADMIN не определена (фронтальная часть сайта);
  • файл физически существует по пути themes/{$usr['theme']}/{$usr['theme']}.rc.php;
  • метод Resources::__init() уже выполнен;
  • функция cot_rc_add_standard() уже подключила стандартные ресурсы (jQuery, js/base.js, js/ajax_on.js).

2.5. Позиция в последовательности выполнения

Файл .rc.php выполняется в следующей последовательности common.php:

  1. Инициализация окружения (загрузка конфигурации, подключение к БД, Cot::init()).
  2. Загрузка конфигурации из базы данных.
  3. Определение пользователя и вычисление $usr['theme'].
  4. Проверка существования themes/{$usr['theme']}/header.tpl с fallback на $cfg['defaulttheme'].
  5. Вызов cot_rc_add_standard().
  6. Выполнение хука rc.
  7. Подключение .rc.php темы.

3. Переменные $usr['theme'] и $cfg['defaulttheme']

3.1. Переменная $cfg['defaulttheme']

$cfg['defaulttheme'] — это глобальная настройка сайта, определяющая тему оформления по умолчанию. Значение загружается из таблицы конфигурации базы данных при инициализации движка и не зависит от того, какой пользователь обратился к сайту.

Характеристики переменной:

  • Тип значения: строка, содержащая код темы (например, index36).
  • Источник: таблица cot_config, параметр defaulttheme.
  • Область видимости: глобальная для всего сайта.
  • Роль в вычислениях: входная величина.

3.2. Переменная $usr['theme']

$usr['theme'] — это тема, применяемая к текущему пользователю. Значение вычисляется в common.php на основе нескольких параметров.

Для авторизованного пользователя:

$usr['theme'] = $cfg['forcedefaulttheme'] ? $cfg['defaulttheme'] : $row['user_theme'];

Для гостя используется значение по умолчанию из инициализации массива $usr:

'theme' => $cfg['defaulttheme'],

После вычисления выполняется проверка на существование шаблона:

$mtheme = "{$cfg['themes_dir']}/{$usr['theme']}/header.tpl";
if (!file_exists($mtheme)) {
    $usr['theme'] = $cfg['defaulttheme'];
    $mtheme = "{$cfg['themes_dir']}/{$usr['theme']}/header.tpl";
    if (!file_exists($mtheme)) {
        cot_diefatal($L['com_defthemefail']);
    }
}

Характеристики переменной:

  • Тип значения: строка, содержащая код темы.
  • Источник: результат вычисления на основе $cfg['forcedefaulttheme'] и $row['user_theme'].
  • Область видимости: текущий пользователь (в рамках запроса).
  • Роль в вычислениях: результат.

3.3. Возможные значения $usr['theme']

Переменная может принимать одно из следующих значений:

  • $cfg['defaulttheme'] — если флаг forcedefaulttheme включён, или если пользователь сам выбрал дефолтную тему;
  • $row['user_theme'] — если флаг forcedefaulttheme выключен, и пользователь выбрал собственную тему;
  • $cfg['defaulttheme'] — как fallback, если папка выбранной темы отсутствует.

3.4. Связь между переменными

Переменная $usr['theme'] вычисляется на основе $cfg['defaulttheme'], но обратной зависимости не существует. Это означает:

  • $cfg['defaulttheme'] — входная величина;
  • $usr['theme'] — выходная (результирующая) величина.

Для файла .rc.php корректной является результирующая величина, поскольку файл физически подключён из папки именно этой темы.

4. Механизм подключения .rc.php движком

4.1. Пошаговый разбор

Рассмотрим последовательность действий движка более детально.

Шаг 1. Инициализация конфигурации.

Движок загружает $cfg из базы данных и файла datas/config.php. На этом этапе становятся доступны значения defaulttheme, forcedefaulttheme, themes_dir и другие.

Шаг 2. Определение пользователя.

Выполняется запрос к таблице cot_users для получения данных текущего пользователя. Если пользователь авторизован, в массив $usr попадают значения из $row.

Шаг 3. Вычисление $usr['theme'].

На основе $cfg['forcedefaulttheme'] и $row['user_theme'] вычисляется значение $usr['theme'].

Шаг 4. Проверка существования шаблона.

Движок проверяет наличие файла themes/{$usr['theme']}/header.tpl. Если файл отсутствует, значение $usr['theme'] принудительно меняется на $cfg['defaulttheme'].

Шаг 5. Инициализация ресурсов.

Вызывается cot_rc_add_standard(), который регистрирует стандартные ресурсы: jQuery (при включённой опции), js/jqModal.min.js, js/base.min.js, js/ajax_on.js (при включённом AJAX).

Шаг 6. Выполнение хука rc.

Плагины, зарегистрированные на хук rc, имеют возможность добавить свои ресурсы.

Шаг 7. Подключение .rc.php темы.

При соблюдении условий (см. раздел 2.4) движок выполняет:

include "{$cfg['themes_dir']}/{$usr['theme']}/{$usr['theme']}.rc.php";

4.2. Что доступно внутри .rc.php

К моменту выполнения файла .rc.php доступны следующие переменные и объекты:

  • Cot::$cfg — полный массив конфигурации;
  • Cot::$usr — данные текущего пользователя, включая theme;
  • Cot::$sys — системные переменные (abs_url, site_uri, scheme, now);
  • Cot::$db — объект базы данных;
  • $L — языковые строки;
  • $R — ресурсные строки;
  • $theme — не определена (назначается позже в блоке Theme / color scheme).

4.3. Что гарантировано

В момент выполнения .rc.php гарантировано следующее:

  • $usr['theme'] содержит имя текущей темы;
  • файл themes/{$usr['theme']}/header.tpl существует;
  • Resources::__init() выполнен, класс Resources готов к использованию;
  • стандартные ресурсы уже зарегистрированы.

5. Взаимосвязь и приоритет переменных

5.1. Отсутствие приоритета

Формулировка «приоритет переменных» некорректна. $usr['theme'] и $cfg['defaulttheme'] — это величины разной природы, решающие разные задачи.

ПеременнаяРольТип
$cfg['defaulttheme']Тема сайта по умолчаниюВход
$usr['theme']Тема, применяемая к пользователюРезультат

5.2. Правило выбора

Для файла .rc.php правильной величиной является результат ($usr['theme']), поскольку файл физически подключён из папки этой темы.

5.3. Обоснование

Файл .rc.php подключается движком по пути themes/{$usr['theme']}/{$usr['theme']}.rc.php. Это означает, что все ресурсы, регистрируемые внутри файла, относятся именно к этой папке. Использование $cfg['defaulttheme'] для склейки путей внутри файла допустимо только в том случае, если $cfg['defaulttheme'] совпадает с $usr['theme'], что не является общим случаем.

5.4. Официальная позиция Cotonti

В официальных руководствах по разработке тем Cotonti и в обсуждениях на форуме разработчиков рекомендуется использовать $usr['theme'] для ссылок на ресурсы темы. Это подтверждается архитектурой движка: .rc.php подключается из папки пользовательской темы, и все ресурсы внутри файла должны относиться к этой же теме.

6. Практические сценарии эксплуатации

6.1. Сценарий A. Единственная тема, форсирование включено

Параметры:

  • defaulttheme = index36
  • forcedefaulttheme = true

Поведение: $usr['theme'] всегда равен index36. Оба варианта ($usr['theme'] и $cfg['defaulttheme']) дают идентичный путь. Приложение работает корректно.

Вывод: сценарий не показателен для анализа.

6.2. Сценарий B. Единственная тема, форсирование выключено

Параметры:

  • defaulttheme = index36
  • forcedefaulttheme = false
  • Все пользователи имеют user_theme = index36

Поведение: $usr['theme'] равен index36. Оба варианта дают идентичный путь. Приложение работает корректно.

Вывод: сценарий также не показателен.

6.3. Сценарий C. Несколько тем, пользовательские предпочтения

Параметры:

  • defaulttheme = index36
  • forcedefaulttheme = false
  • Пользователь имеет user_theme = mytheme

Поведение: движок подключает themes/mytheme/mytheme.rc.php. Внутри файла:

  • при использовании $usr['theme'] путь формируется как themes/mytheme/assets/... — корректно;
  • при использовании $cfg['defaulttheme'] путь формируется как themes/index36/assets/... — некорректно.

Файлы по второму пути отсутствуют. Resources::addFile() бросает Exception. Фронтальная часть сайта падает.

Вывод: использование $cfg['defaulttheme'] приводит к критической ошибке.

6.4. Сценарий D. Изменение defaulttheme

Параметры:

  • defaulttheme = newtheme (изменён администратором)
  • forcedefaulttheme = false
  • Пользователь имеет user_theme = index36

Поведение: движок подключает themes/index36/index36.rc.php. Внутри файла:

  • при использовании $usr['theme'] путь формируется как themes/index36/assets/... — корректно;
  • при использовании $cfg['defaulttheme'] путь формируется как themes/newtheme/assets/... — некорректно.

Файлы отсутствуют. Exception. Фронт падает.

Вывод: изменение defaulttheme без выключения пользовательских тем ломает работу тем, использующих $cfg['defaulttheme'] в .rc.php.

6.5. Сценарий E. Тема-заглушка (fallback)

Параметры:

  • defaulttheme = broken
  • Папка themes/broken/ отсутствует
  • forcedefaulttheme = true

Поведение: движок обнаруживает отсутствие themes/broken/header.tpl и выполняет проверку fallback. Если папка отсутствует и fallback не помогает, вызывается cot_diefatal($L['com_defthemefail']). Файл .rc.php не подключается.

Вывод: сценарий аварийный, .rc.php не выполняется.

6.6. Сводная таблица сценариев

Сценарийdefaultthemeforcedefaultthemeuser_themeРезультат
Aindex36true—Работает
Bindex36falseindex36Работает
Cindex36falsemythemeЛомается
Dnewthemefalseindex36Ломается
Ebrokentrue—Аварийный

7. Правила оформления файла .rc.php

7.1. Общие требования

  1. Файл начинается с обязательной конструкции:

    <?php
    defined('COT_CODE') or die('Wrong URL.');
  2. Запрещён любой вывод в стандартный поток вывода (echo, print, var_dump). Файл подключается в момент, когда часть заголовков уже отправлена.
  3. Использовать исключительно публичные статические методы класса Resources. Прямой доступ к защищённым и приватным полям класса недопустим.
  4. Локальные файлы указываются путём от корня сайта без ведущего слэша. Класс Resources выполняет проверку file_exists() и бросает Exception при отсутствии файла.
  5. Внешние ресурсы указываются полным URL (http://, https://, //). Для них проверка file_exists() не выполняется.
  6. CSS-файлы размещаются в <head> через Resources::addFile() или Resources::linkFile().
  7. JavaScript-файлы размещаются в футере через Resources::linkFileFooter(), за исключением критичных для рендера скриптов.
  8. Порядок $order задаётся явно для всех файлов, кроме дефолтного значения 50.
  9. Запрещён ручной вызов Resources::render() и Resources::renderFooter(). Эти методы вызываются движком.
  10. Запрещено использование устаревших обёрток cot_rc_add_file(), cot_rc_add_embed(), cot_rc_link_file(). Они помечены как deprecated.
  11. Файл должен быть идемпотентным: повторное выполнение не должно изменять конфигурацию реестра.
  12. Обращение к базе данных недопустимо: .rc.php выполняется при каждом запросе.
  13. Переопределение $L и $R запрещено — для этого предназначен файл {theme}.php.

7.2. Рекомендации по структуре

Рекомендуется определить переменную для корневого пути темы:

$themeDir = Cot::$cfg['themes_dir'] . '/' . Cot::$usr['theme'];

Это обеспечивает единообразие и снижает риск опечаток.

7.3. Рекомендации по порядку ресурсов

Порядок подключения ресурсов (значения $order):

  • 10–20 — базовые библиотеки (jQuery);
  • 20–40 — фреймворки (Bootstrap);
  • 40–70 — плагины (Select2, Fancybox, Perfect Scrollbar);
  • 100–150 — скрипты темы;
  • 800–900 — оверрайды темы.

7.4. Рекомендации по размещению

CSS-ресурсы:

  • базовые библиотеки — в <head>;
  • плагины — в <head>;
  • стили темы — в <head>;
  • оверрайды — в <head> с высоким $order.

JavaScript-ресурсы:

  • jQuery — в <head>;
  • Bootstrap bundle — в <head> (при консолидации) или в футере;
  • плагины — в футере;
  • скрипты темы — в футере;
  • скрипты инициализации — в футере с максимальным $order.

7.5. Шаблон файла

<?php
/**
 * Theme resource loader
 *
 * @package    {theme}
 * @version    {version}
 * @author     {author}
 * @copyright  {copyright}
 * @license    {license}
 */

defined('COT_CODE') or die('Wrong URL.');

$themeDir = Cot::$cfg['themes_dir'] . '/' . Cot::$usr['theme'];

// CSS — <head>
Resources::addFile('lib/bootstrap/css/bootstrap.min.css', 'css', 10);
Resources::addFile($themeDir . '/css/theme.css', 'css', 800);

// JS — <head> (критичные)
Resources::addFile($themeDir . '/js/header.first.js', 'js', 40);

// JS — футер
Resources::linkFileFooter('lib/bootstrap/js/bootstrap.bundle.min.js', 'js', 30);
Resources::linkFileFooter($themeDir . '/js/theme.js', 'js', 100);

8. Справочник по классу Resources

8.1. Публичные методы

Resources::addFile($path, $type = '', $order = 50, $scope = 'global')

Регистрирует файл в реестре <head>. При включённой консолидации файл может быть склеен с другими в общий asset.

Параметры:

  • $path — путь к файлу, полный URL или алиас;
  • $type — 'js' или 'css'; при пустом значении определяется по расширению;
  • $order — порядок вывода (по умолчанию 50);
  • $scope — область видимости (global, guest, user, group_{id}).

Возвращает true при успехе, false при дублировании файла. Бросает Exception, если локальный файл не найден.

Resources::linkFile($path, $type = '', $order = 50)

Добавляет файл в <head> без консолидации. HTML формируется немедленно.

Resources::linkFileFooter($path, $type = '', $order = 50)

Добавляет файл в футер. HTML формируется немедленно.

Resources::addEmbed($code, $type = 'js', $order = 50, $scope = 'global', $identifier = '')

Регистрирует встроенный код в <head>. При включённой консолидации и минификации код сохраняется в файл в директории cache_dir/assets/.

Resources::embed($code, $type = 'js', $order = 50, $attr = '')

Немедленная вставка кода в <head>.

Resources::embedFooter($code, $type = 'js', $order = 50, $attr = '')

Немедленная вставка кода в футер.

Resources::setAlias($alias, $path, $canReWrite = false)

Регистрирует или переопределяет алиас. По умолчанию перезапись запрещена.

Resources::getAlias($alias)

Возвращает путь по алиасу или null.

Resources::isFileAdded($fileName)

Проверяет, добавлялся ли ранее указанный файл или алиас.

Resources::minify($code, $type)

Выполняет минификацию JavaScript (через lib/jsmin.php) или CSS (через lib/cssmin.php).

8.2. Предопределённые алиасы

Класс Resources содержит следующие предопределённые алиасы:

  • @jQuery → js/jquery.min.js
  • @ckeditor → plugins/ckeditor/lib/ckeditor.js
  • @ckeditorPreset.js → plugins/ckeditor/presets/ckeditor.default.set.js
  • @bootstrap → lib/bootstrap/js/bootstrap.bundle.min.js
  • @bootstrap.css → lib/bootstrap/css/bootstrap.min.css
  • @select2 → lib/select2/js/select2.full.min.js
  • @select2.css → lib/select2/css/select2.min.css

Константы класса:

  • Resources::JQUERY
  • Resources::BOOTSTRAP
  • Resources::CKEDITOR
  • Resources::SELECT2

8.3. Механизм scope

Параметр $scope определяет область видимости ресурса:

  • global — ресурс подключается всегда;
  • guest — только для гостей ($usr['id'] === 0);
  • user — только для авторизованных пользователей ($usr['id'] > 0);
  • group_{id} — только для пользователей с maingrp, равным {id}.

Область видимости применяется при выводе в Resources::render().

8.4. Механизм order

Параметр $order определяет порядок вывода. Меньшее значение соответствует более раннему выводу. По умолчанию — 50.

8.5. Консолидация и минификация

При условии $cfg['cache'] && $cfg['headrc_consolidate'] && !$isAdmin класс Resources выполняет консолидацию ресурсов одного типа и области видимости в единый файл:

  • cache_dir/assets/{scope}.{theme}.{type} — итоговый файл;
  • cache_dir/assets/{scope}.{theme}.{type}.idx — индекс файлов;
  • cache_dir/assets/{scope}.{theme}.{type}.gz — gzip-версия.

Консолидированный файл отдаётся через URL rc.php?rc={scope}.{theme}.{type}&nc={mtime}.

9. Типичные ошибки и способы их устранения

9.1. Использование $cfg['defaulttheme'] для путей к ресурсам темы

Симптом: при смене темы по умолчанию или при наличии нескольких тем фронтальная часть падает с ошибкой Exception.

Причина: внутри .rc.php формируется путь через Cot::$cfg['themes_dir'] . '/' . Cot::$cfg['defaulttheme'], что не соответствует папке, из которой подключён файл.

Решение: использовать Cot::$usr['theme'].

9.2. Использование переменной $theme

Симптом: предупреждение Undefined variable $theme или некорректный путь.

Причина: переменная $theme назначается в common.php позже, в блоке Theme / color scheme.

Решение: использовать Cot::$usr['theme'].

9.3. Дублирование ресурсов

Симптом: в исходном HTML присутствуют дублирующие теги <script> и <link> для jQuery, Bootstrap или других библиотек.

Причина: повторная регистрация ресурсов, уже подключённых через cot_rc_add_standard().

Решение: не добавлять jQuery, jqModal, base.js, ajax_on.js повторно.

Симптом: тег <link rel="stylesheet"> располагается в конце <body>.

Причина: использование Resources::linkFileFooter() для CSS-файлов.

Решение: CSS-файлы размещать в <head> через Resources::addFile() или Resources::linkFile().

9.5. Размещение всех JS в head

Симптом: медленная загрузка страницы, блокировка парсинга HTML.

Причина: все JS-файлы регистрируются через Resources::addFile() в <head>.

Решение: разместить не критичные JS в футере через Resources::linkFileFooter(). В <head> оставить только jQuery и скрипты, критичные для первичного рендера.

9.6. Игнорирование исключения addFile

Симптом: фронтальная часть падает при отсутствии файла.

Причина: Resources::addFile() бросает Exception, если локальный файл не найден.

Решение: проверять существование файла через file_exists() перед регистрацией, если файл может отсутствовать.

9.7. Изменение $theme_reload

Симптом: переопределения $L и $R не работают или работают некорректно.

Причина: ручное вмешательство в массив $theme_reload.

Решение: не изменять $theme_reload вручную. Переопределения выполняются через $L и $R в файле {theme}.php.

9.8. Использование устаревших обёрток

Симптом: предупреждение deprecated в логах.

Причина: использование cot_rc_add_file(), cot_rc_add_embed(), cot_rc_link_file().

Решение: использовать методы класса Resources.

9.9. Некорректный order

Симптом: стили темы перекрываются стилями плагинов или библиотек.

Причина: недостаточно высокое значение $order для стилей темы.

Решение: устанавливать $order для стилей темы в диапазоне 800–900.

9.10. Обращение к базе данных

Симптом: замедление загрузки страниц.

Причина: выполнение SQL-запросов внутри .rc.php.

Решение: перенести логику в контроллер или модуль.

10. Диагностика и отладка

10.1. Проверка значения переменных

Для диагностики можно временно добавить в начало .rc.php:

error_log('usr theme: ' . Cot::$usr['theme']);
error_log('default theme: ' . Cot::$cfg['defaulttheme']);
error_log('themes dir: ' . Cot::$cfg['themes_dir']);

Записи попадут в лог ошибок веб-сервера.

10.2. Проверка подключения файла

Для проверки факта подключения .rc.php:

error_log('rc.php loaded from: ' . __FILE__);

10.3. Проверка реестра ресурсов

Для просмотра зарегистрированных ресурсов:

error_log('headerRc: ' . print_r(Resources::$headerRc ?? null, true));

Обращение к защищённым полям класса требует осторожности и применяется только в отладочных целях.

10.4. Проверка консолидации

Для проверки факта консолидации:

error_log('consolidate: ' . (int) Cot::$cfg['headrc_consolidate']);
error_log('cache: ' . (int) Cot::$cfg['cache']);

10.5. Проверка исключений

Оборачивание вызовов Resources::addFile() в try/catch:

try {
    Resources::addFile($themeDir . '/css/theme.css', 'css', 800);
} catch (Exception $e) {
    error_log('Resource error: ' . $e->getMessage());
}

Такой подход позволяет изолировать проблему и не обрушить страницу.

10.6. Включение режима отладки

При значении Cot::$cfg['debug_mode'] === true движок выводит дополнительные сведения. Проверку можно выполнить через:

error_log('debug_mode: ' . (int) Cot::$cfg['debug_mode']);

11. Заключение

Выбор между Cot::$usr['theme'] и Cot::$cfg['defaulttheme'] в файле .rc.php определяется архитектурой движка Cotonti.

Файл .rc.php подключается движком из папки themes/{$usr['theme']}/. Это означает, что переменная $usr['theme'] в момент выполнения файла гарантированно содержит имя текущей темы. Все ресурсы, регистрируемые внутри файла, относятся именно к этой папке.

Переменная $cfg['defaulttheme'] содержит настройку сайта по умолчанию. Она совпадает с $usr['theme'] только при соблюдении ряда условий:

  • включён флаг forcedefaulttheme;
  • у всех пользователей user_theme совпадает с defaulttheme;
  • defaulttheme не был изменён.

В общем случае совпадения нет, и использование $cfg['defaulttheme'] приводит к формированию неверных путей. Класс Resources бросает Exception, и фронтальная часть сайта падает.

Правило: для построения путей к ресурсам темы внутри .rc.php использовать Cot::$usr['theme'].

Обоснование: файл подключён из папки themes/{$usr['theme']}/, поэтому ресурсы принадлежат именно этой теме. Использование $cfg['defaulttheme'] нарушает это соответствие.

Данное правило распространяется на все ресурсы темы: CSS, JavaScript, изображения, шрифты и любые другие файлы, расположенные внутри папки темы.


Справочная таблица: когда использовать $cfg['defaulttheme'], а когда Cot::$usr['theme']

Ниже — таблица, построенная исключительно на основе анализа исходного кода Cotonti (system/common.php, system/functions.php, system/resources.php, system/admin/admin.functions.php). Каждая строка — реальный случай использования, взятый из движка.


Таблица 1. Легитимные случаи использования $cfg['defaulttheme']

№Файл / место в кодеЗадачаПочему именно $cfg['defaulttheme']Пример из исходника
1system/common.php, инициализация массива $usrЗадать значение по умолчанию до того, как пользователь определёнНа момент создания массива данных пользователя ещё нет. Нужно какое-то стартовое значение. Для гостя это и есть тема сайта по умолчанию'theme' => $cfg['defaulttheme'],
2system/common.php, вычисление $usr['theme'] для авторизованногоФорсировать тему для всех пользователейЕсли администратор включил forcedefaulttheme, движок обязан взять глобальную тему, а не личные предпочтения пользователя$usr['theme'] = $cfg['forcedefaulttheme'] ? $cfg['defaulttheme'] : $row['user_theme'];
3system/common.php, проверка существования шапкиПодменить отсутствующую тему на дефолтнуюПользовательская тема физически отсутствует. Единственный разумный fallback — тема сайта по умолчанию$usr['theme'] = $cfg['defaulttheme']; (после if (!file_exists($mtheme)))
4system/common.php, финальная ошибка fallbackПризнать полный отказ темизацииДаже тема по умолчанию недоступна. Дальше только аварийное завершениеif (!file_exists($mtheme)) { cot_diefatal($L['com_defthemefail']); }
5system/functions.php, функция cot_schemeFile()Вернуть путь к CSS-файлу цветовой схемыФункция может быть вызвана до инициализации $usr. Если $usr['theme'] ещё не задан — берётся значение по умолчанию$theme = isset($usr['theme']) ? $usr['theme'] : $cfg['defaulttheme'];

Вывод по таблице 1: $cfg['defaulttheme'] применяется только в трёх ролях:

  • стартовое значение (инициализация);
  • форсированное значение (forcedefaulttheme = true);
  • аварийный fallback (тема недоступна).

Во всех остальных случаях — это не тот источник.


Таблица 2. Места, где $cfg['defaulttheme'] использовать нельзя, а нужно Cot::$usr['theme']

№Файл / место в кодеЗадачаПочему Cot::$usr['theme']Пример из исходника
1system/common.php, подключение .rc.php темыНайти файл ресурсов текущей темыФайл физически подключён из папки {$usr['theme']}. Значит, и внутри файла $usr['theme'] = имя этой темыinclude "{$cfg['themes_dir']}/{$usr['theme']}/{$usr['theme']}.rc.php";
2system/common.php, подключение {theme}.phpФайл переопределения $L/$RПривязан к папке текущей темы, а не к глобальной настройке$sys['theme_resources'] = "{$cfg['themes_dir']}/{$usr['theme']}/{$usr['theme']}.php";
3system/common.php, языковой файл темыЗагрузить переводы текущей темыТема пользователя может отличаться от defaulttheme$usr['theme_lang'] = "{$cfg['themes_dir']}/{$usr['theme']}/{$usr['theme']}.{$usr['lang']}.lang.php";
4system/common.php, шаблон шапкиНайти header.tplПривязан к папке текущей темы$mtheme = "{$cfg['themes_dir']}/{$usr['theme']}/header.tpl";
5system/functions.php, cot_tplfile()Найти любой .tpl текущей темыВсе шаблоны фронта лежат в папке $usr['theme']$theme = !empty($usr['theme']) ? $usr['theme'] : '';
6system/common.php, .rc.php темы (внутренняя логика)Пути к ассетам темыФайл подключён из папки именно этой темы$themeDir = Cot::$cfg['themes_dir'] . '/' . Cot::$usr['theme'];
7system/resources.php, additionalFiles() для @select2Поиск i18n-файла Select2 под язык пользователяПривязан к языку, а тема тут ни при чём — но пример показывает, что тематические ресурсы привязаны к контексту пользователя$select2i18n = 'lib/select2/js/i18n/' . Cot::$usr['lang'] . '.js';

Вывод по таблице 2: всё, что относится к файлам внутри папки темы (CSS, JS, шаблоны, языки, .rc.php, .php), обязано использовать Cot::$usr['theme'].


Таблица 3. Админский контекст: где $cfg['defaulttheme'] и $usr['theme']не работают и нужен третий источник

№Файл / место в кодеЗадачаКакую переменную использоватьПример из исходника
1system/common.php, языковой файл админ-темыЗагрузить переводы админ-темы$cfg['admintheme']$usr['def_theme_lang'] = "{$cfg['themes_dir']}/admin/{$cfg['admintheme']}/{$cfg['admintheme']}.en.lang.php";
2system/common.php, файл ресурсов админ-темыПодключить {admintheme}.php$cfg['admintheme']$sys['theme_resources'] = "{$cfg['themes_dir']}/admin/{$cfg['admintheme']}/{$cfg['admintheme']}.php";
3system/common.php, путь к шаблонам админкиНайти .tpl админ-темы$cfg['admintheme']Используется в cot_tplfile() через переменную $adminTheme
4system/admin/admin.functions.phpПодключение ресурсовCot::$cfg['admintheme']Resources::addFile(Cot::$cfg['themes_dir'] . '/admin/' . Cot::$cfg['admintheme'] . '/assets/...');
5system/common.php, иконпакИконки для интерфейса$cfg['defaulticons'] (fallback), $usr['icons'] (основное)if (empty($usr['icons'])) { $usr['icons'] = $cfg['defaulticons']; }

Вывод по таблице 3: в админском контексте используется третья переменная — $cfg['admintheme']. Ни defaulttheme, ни usr['theme'] для админских шаблонов не подходят.


Таблица 4. Сводная матрица: какой переменной пользоваться в каком контексте

КонтекстПравильная переменнаяОбоснование
Пути к CSS/JS темы фронтаCot::$usr['theme']Файлы физически лежат в themes/{usr['theme']}/
Пути к .tpl темы фронтаCot::$usr['theme']Все шаблоны фронта привязаны к папке темы пользователя
Пути к .php темы фронта (.rc.php, {theme}.php, {theme}.lang.php)Cot::$usr['theme']Эти файлы подключаются именно из папки usr['theme']
Аварийный fallback при отсутствии темы$cfg['defaulttheme']Единственный разумный источник при отказе
Инициализация массива $usr до определения пользователя$cfg['defaulttheme']Стартовое значение
Форсированная тема (forcedefaulttheme = true)$cfg['defaulttheme']Прямое назначение флага
Пути к CSS/JS админ-темы$cfg['admintheme']Админка использует отдельную тему
Пути к .tpl админ-темы$cfg['admintheme']Аналогично
Языковые файлы админ-темы$cfg['admintheme']Аналогично
Аварийное завершение при отсутствии темы по умолчанию$cfg['defaulttheme']Только для проверки cot_diefatal()

Таблица 5. Практические подстановки: что писать в конкретном файле

ФайлЧто писатьПочему
themes/{theme}/{theme}.rc.phpCot::$cfg['themes_dir'] . '/' . Cot::$usr['theme'] . '/...'Файл подключён движком из папки текущей темы
themes/{theme}/{theme}.php$L[...], $R[...] (без путей)Переопределения строк, не привязаны к папке
themes/admin/{admintheme}/{admintheme}.rc.phpCot::$cfg['themes_dir'] . '/admin/' . Cot::$cfg['admintheme'] . '/...'Админ-тема задаётся отдельно
themes/admin/{admintheme}/{admintheme}.php$L[...], $R[...] (без путей)Переопределения строк админки
system/functions.php, хелперы$usr['theme'] ?? $cfg['defaulttheme']Fallback на случай отсутствия $usr['theme']
system/common.php, начальная инициализация$cfg['defaulttheme']Пользователь ещё не определён
system/common.php, вычисление $usr['theme']$cfg['forcedefaulttheme'] ? $cfg['defaulttheme'] : $row['user_theme']Форсирование или личный выбор
system/common.php, fallback$cfg['defaulttheme']Единственный разумный источник при отказе

Таблица 6. Антипаттерны: где $cfg['defaulttheme'] использовать нельзя и почему

№Что пишут ошибочноПочему это ошибкаЧто должно быть
1Внутри {theme}.rc.php: Cot::$cfg['themes_dir'] . '/' . Cot::$cfg['defaulttheme'] . '/assets/...'Файл подключён из папки usr['theme']. Путь уводит в другую папку при расхожденииCot::$cfg['themes_dir'] . '/' . Cot::$usr['theme'] . '/assets/...'
2Внутри {theme}.rc.php: Cot::$cfg['themes_dir'] . '/' . Cot::$cfg['defaulttheme'] . '/js/...'АналогичноCot::$cfg['themes_dir'] . '/' . Cot::$usr['theme'] . '/js/...'
3Внутри {theme}.php: ссылки на файлы темы через defaultthemeФайл относится к текущей теме, а не к глобальной настройке$usr['theme']
4В шаблонах темы: {PHP.cfg.defaulttheme} для путей к ассетамВ шаблоне можно использовать {PHP.usr.theme} — тогда путь всегда корректен{PHP.usr.theme}
5В админ-теме: Cot::$cfg['defaulttheme'] для путей к админ-ассетамАдминка использует отдельную тему, заданную в $cfg['admintheme']Cot::$cfg['admintheme']
6В админ-теме: Cot::$usr['theme'] для путей к админ-ассетамПользовательская тема фронта не имеет отношения к админ-интерфейсуCot::$cfg['admintheme']

Таблица 7. Быстрая шпаргалка «что взять в данной ситуации»

СитуацияИсточник
Файл .rc.php темы фронта подключается движкомCot::$usr['theme']
Файл .php темы фронта (переопределения $L/$R)Без путей — только $L/$R
Файл .rc.php админ-темы подключается движкомCot::$cfg['admintheme']
Файл .php админ-темы (переопределения $L/$R)Без путей — только $L/$R
Глобальная функция, которая может быть вызвана до $usr$usr['theme'] ?? $cfg['defaulttheme']
Инициализация $usr для гостя$cfg['defaulttheme']
Форсирование темы для всех пользователей$cfg['defaulttheme']
Аварийный fallback при отсутствии темы$cfg['defaulttheme']
Пути к шаблонам фронта (cot_tplfile())Cot::$usr['theme']
Пути к шаблонам админки (cot_tplfile())Cot::$cfg['admintheme']

Ключевые правила по итогам таблиц

  1. $cfg['defaulttheme']— только три роли: инициализация, форсирование, аварийный fallback.
  2. Cot::$usr['theme']— все пути к файлам внутри папки текущей темы фронта.
  3. $cfg['admintheme']— все пути к файлам внутри папки админ-темы.
  4. $usr['theme'] ?? $cfg['defaulttheme']— компромисс для глобальных функций с неопределённым контекстом.
  5. Ни в .rc.php, ни в {theme}.php, ни в шаблонах фронта нельзя подставлять $cfg['defaulttheme'] для путей к ассетам текущей темы.
Комментарии отсутствуют
Добавление комментариев доступно только зарегистрированным пользователям