Which is correct: Cot::$usr['theme'] or Cot::$cfg['defaulttheme']?
Table of Contents
- Introduction
- Purpose of the .rc.php file in the Cotonti architecture
- The $usr['theme'] and $cfg['defaulttheme'] variables
- The mechanism of .rc.php inclusion by the engine
- Relationship and priority of the variables
- Practical operational scenarios
- Rules for structuring the .rc.php file
- Reference of the Resources class
- Common errors and how to fix them
- Diagnostics and debugging
- Conclusion
1. Introduction
When developing a theme for Cotonti CMF, a developer encounters the need to include CSS and JavaScript resources in the .rc.php file. A natural question arises: which variable should be used to build paths to the theme resources — Cot::$usr['theme'] or Cot::$cfg['defaulttheme']?
At first glance, the difference between these variables is minimal, and many ready-made themes use Cot::$cfg['defaulttheme']. However, this approach works only within a limited set of configurations. In the general case, it leads to broken paths, exceptions in Resources::addFile(), and a crash of the front-end part of the site.
This article systematises knowledge about Cotonti theming mechanisms and provides an unambiguous answer to the question posed. The material is intended both for beginner developers and for experienced specialists familiar with the internal structure of the CMF.
2. Purpose of the .rc.php file in the Cotonti architecture
2.1. Definition
The .rc.php file (from English resource control) is an auxiliary file of a Cotonti theme that registers CSS and JavaScript resources in the static registry of the Resources class. The engine then outputs these resources into the <head> of the page and into the footer.
The file is neither a plugin, nor a module, nor a standalone theme. It belongs to the category of auxiliary theme files alongside {theme}.php (the file that overrides language and resource strings) and {theme}.tpl (templates).
2.2. Place in the CMF architecture
Registration and output of resources are performed by the Resources class, which is located in the file system/resources.php. The class stores the following static structures:
$registry— registry of<head>resources when consolidation is enabled;$headerRc— registry of<head>resources without consolidation;$footerRc— registry of footer resources;$addedFiles— map of already added files (for deduplication);$alias— map of predefined aliases (@jQuery,@bootstrap,@select2, and others);- flags
$cacheOn,$consolidate,$minify,$isAdmin,$headerComplete,$htmlCleanupEnabled.
Initialisation of the class is performed by the Resources::__init() method, which is called at the end of the file resources.php. The method reads settings from the $cfg array:
cache— global caching flag;headrc_consolidate— resource consolidation flag;headrc_minify— minification flag;html_cleanup— flag for cleaning HTML from unnecessary whitespace;cache_dir— cache directory;dir_perms— permissions for created directories.
The $isAdmin flag is set according to the value of the COT_ADMIN constant. For the front-end part of the site, $isAdmin === false, which permits consolidation and minification to operate provided they are enabled in the configuration.
2.3. How the engine includes the file
The .rc.php file is included by the engine in the Head Resources section of the file 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";
}
}Analysis of this fragment yields three key facts:
- The existence of the file at the path
themes/{$usr['theme']}/{$usr['theme']}.rc.phpis checked. - If the file exists, it is included using the
includeoperator. - The theme name is taken from the
$usr['theme']variable, not from$cfg['defaulttheme'].
From this follows a fundamental conclusion: at the moment the .rc.php file is executed, the $usr['theme'] variable is guaranteed to be equal to the name of the current theme. If this were not the case, the file would not have been included.
2.4. Loading conditions
The .rc.php file is included when the following conditions are met:
- the
COT_ADMINconstant is not defined (front-end part of the site); - the file physically exists at the path
themes/{$usr['theme']}/{$usr['theme']}.rc.php; - the
Resources::__init()method has already been executed; - the
cot_rc_add_standard()function has already included the standard resources (jQuery,js/base.js,js/ajax_on.js).
2.5. Position in the execution sequence
The .rc.php file is executed in the following sequence of common.php:
- Environment initialisation (configuration loading, database connection,
Cot::init()). - Configuration loading from the database.
- User determination and computation of
$usr['theme']. - Checking the existence of
themes/{$usr['theme']}/header.tplwith fallback to$cfg['defaulttheme']. - Calling
cot_rc_add_standard(). - Execution of the
rchook. - Inclusion of the theme's
.rc.php.
3. The $usr['theme'] and $cfg['defaulttheme'] variables
3.1. The $cfg['defaulttheme'] variable
$cfg['defaulttheme'] is a global site setting that determines the default theme. The value is loaded from the configuration table of the database during engine initialisation and does not depend on which user accessed the site.
Characteristics of the variable:
- Value type: a string containing the theme code (for example,
index36). - Source: the
cot_configtable, thedefaultthemeparameter. - Scope: global for the entire site.
- Role in computation: input value.
3.2. The $usr['theme'] variable
$usr['theme'] is the theme applied to the current user. The value is computed in common.php based on several parameters.
For an authorised user:
$usr['theme'] = $cfg['forcedefaulttheme'] ? $cfg['defaulttheme'] : $row['user_theme'];For a guest, the default value from the initialisation of the $usr array is used:
'theme' => $cfg['defaulttheme'],After the computation, a check for the existence of the template is performed:
$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']);
}
}Characteristics of the variable:
- Value type: a string containing the theme code.
- Source: the result of computation based on
$cfg['forcedefaulttheme']and$row['user_theme']. - Scope: the current user (within the request).
- Role in computation: result.
3.3. Possible values of $usr['theme']
The variable may take one of the following values:
$cfg['defaulttheme']— if theforcedefaultthemeflag is enabled, or if the user has personally chosen the default theme;$row['user_theme']— if theforcedefaultthemeflag is disabled and the user has chosen their own theme;$cfg['defaulttheme']— as a fallback if the folder of the chosen theme is missing.
3.4. Relationship between the variables
The $usr['theme'] variable is computed based on $cfg['defaulttheme'], but no reverse dependency exists. This means:
$cfg['defaulttheme']— input value;$usr['theme']— output (resulting) value.
For the .rc.php file, the correct value is the resulting one, since the file is physically included from the folder of that very theme.
4. The mechanism of .rc.php inclusion by the engine
4.1. Step-by-step breakdown
Let us examine the sequence of engine actions in more detail.
Step 1. Configuration initialisation.
The engine loads $cfg from the database and the file datas/config.php. At this stage the values defaulttheme, forcedefaulttheme, themes_dir, and others become available.
Step 2. User determination.
A query to the cot_users table is executed to obtain the current user's data. If the user is authorised, the values from $row are placed into the $usr array.
Step 3. Computation of $usr['theme'].
Based on $cfg['forcedefaulttheme'] and $row['user_theme'], the value of $usr['theme'] is computed.
Step 4. Checking the existence of the template.
The engine checks for the presence of the file themes/{$usr['theme']}/header.tpl. If the file is missing, the value of $usr['theme'] is forcibly changed to $cfg['defaulttheme'].
Step 5. Resource initialisation.
cot_rc_add_standard() is called, which registers the standard resources: jQuery (if the option is enabled), js/jqModal.min.js, js/base.min.js, js/ajax_on.js (if AJAX is enabled).
Step 6. Execution of the rc hook.
Plugins registered on the rc hook have the opportunity to add their own resources.
Step 7. Inclusion of the theme's .rc.php.
Provided the conditions are met (see section 2.4), the engine executes:
include "{$cfg['themes_dir']}/{$usr['theme']}/{$usr['theme']}.rc.php";4.2. What is available inside .rc.php
At the moment the .rc.php file is executed, the following variables and objects are available:
Cot::$cfg— the full configuration array;Cot::$usr— the current user's data, includingtheme;Cot::$sys— system variables (abs_url,site_uri,scheme,now);Cot::$db— the database object;$L— language strings;$R— resource strings;$theme— not defined (it is assigned later in the Theme / color scheme block).
4.3. What is guaranteed
At the moment .rc.php is executed, the following is guaranteed:
$usr['theme']contains the name of the current theme;- the file
themes/{$usr['theme']}/header.tplexists; Resources::__init()has been executed, and theResourcesclass is ready for use;- standard resources have already been registered.
5. Relationship and priority of the variables
5.1. Absence of priority
The phrasing "priority of variables" is incorrect. $usr['theme'] and $cfg['defaulttheme'] are quantities of a different nature that solve different tasks.
| Variable | Role | Type |
|---|---|---|
$cfg['defaulttheme'] | Default site theme | Input |
$usr['theme'] | Theme applied to the user | Result |
5.2. Rule of choice
For the .rc.php file, the correct value is the result ($usr['theme']), since the file is physically included from the folder of that theme.
5.3. Rationale
The .rc.php file is included by the engine at the path themes/{$usr['theme']}/{$usr['theme']}.rc.php. This means that all resources registered inside the file pertain precisely to that folder. Using $cfg['defaulttheme'] for assembling paths inside the file is permissible only in the case where $cfg['defaulttheme'] coincides with $usr['theme'], which is not a general case.
5.4. Official Cotonti position
In official Cotonti theme development guides and in discussions on the developer forum, it is recommended to use $usr['theme'] for links to theme resources. This is confirmed by the engine's architecture: .rc.php is included from the folder of the user's theme, and all resources inside the file must pertain to that very theme.
6. Practical operational scenarios
6.1. Scenario A. Single theme, forced mode enabled
Parameters:
defaulttheme = index36forcedefaulttheme = true
Behaviour: $usr['theme'] is always equal to index36. Both variants ($usr['theme'] and $cfg['defaulttheme']) produce an identical path. The application works correctly.
Conclusion: the scenario is not indicative for analysis.
6.2. Scenario B. Single theme, forced mode disabled
Parameters:
defaulttheme = index36forcedefaulttheme = false- All users have
user_theme = index36
Behaviour: $usr['theme'] is equal to index36. Both variants produce an identical path. The application works correctly.
Conclusion: this scenario is also not indicative.
6.3. Scenario C. Multiple themes, user preferences
Parameters:
defaulttheme = index36forcedefaulttheme = false- The user has
user_theme = mytheme
Behaviour: the engine includes themes/mytheme/mytheme.rc.php. Inside the file:
- when using
$usr['theme'], the path is formed asthemes/mytheme/assets/...— correct; - when using
$cfg['defaulttheme'], the path is formed asthemes/index36/assets/...— incorrect.
Files at the second path do not exist. Resources::addFile() throws an Exception. The front-end part of the site crashes.
Conclusion: using $cfg['defaulttheme'] leads to a critical error.
6.4. Scenario D. Change of defaulttheme
Parameters:
defaulttheme = newtheme(changed by the administrator)forcedefaulttheme = false- The user has
user_theme = index36
Behaviour: the engine includes themes/index36/index36.rc.php. Inside the file:
- when using
$usr['theme'], the path is formed asthemes/index36/assets/...— correct; - when using
$cfg['defaulttheme'], the path is formed asthemes/newtheme/assets/...— incorrect.
Files are missing. Exception. The front-end crashes.
Conclusion: changing defaulttheme without disabling user themes breaks themes that use $cfg['defaulttheme'] in .rc.php.
6.5. Scenario E. Fallback theme
Parameters:
defaulttheme = broken- The folder
themes/broken/is missing forcedefaulttheme = true
Behaviour: the engine detects the absence of themes/broken/header.tpl and performs a fallback check. If the folder is missing and the fallback does not help, cot_diefatal($L['com_defthemefail']) is called. The .rc.php file is not included.
Conclusion: the scenario is an emergency one; .rc.php is not executed.
6.6. Summary table of scenarios
| Scenario | defaulttheme | forcedefaulttheme | user_theme | Result |
|---|---|---|---|---|
| A | index36 | true | — | Works |
| B | index36 | false | index36 | Works |
| C | index36 | false | mytheme | Breaks |
| D | newtheme | false | index36 | Breaks |
| E | broken | true | — | Emergency |
7. Rules for structuring the .rc.php file
7.1. General requirements
The file begins with the mandatory construct:
<?php defined('COT_CODE') or die('Wrong URL.');- Any output to the standard output stream (
echo,print,var_dump) is prohibited. The file is included at the moment when some of the headers have already been sent. - Use exclusively the public static methods of the
Resourcesclass. Direct access to the protected and private fields of the class is not allowed. - Local files are specified as a path from the site root without a leading slash. The
Resourcesclass performs afile_exists()check and throws anExceptionif the file is missing. - External resources are specified with a full URL (
http://,https://,//). For them, thefile_exists()check is not performed. - CSS files are placed in
<head>viaResources::addFile()orResources::linkFile(). - JavaScript files are placed in the footer via
Resources::linkFileFooter(), with the exception of scripts critical for rendering. - The
$orderis set explicitly for all files except for the default value of 50. - Manual invocation of
Resources::render()andResources::renderFooter()is prohibited. These methods are called by the engine. - The use of deprecated wrappers
cot_rc_add_file(),cot_rc_add_embed(),cot_rc_link_file()is prohibited. They are marked as deprecated. - The file must be idempotent: repeated execution must not change the registry configuration.
- Database access is not allowed:
.rc.phpis executed on every request. - Overriding
$Land$Ris prohibited — the file{theme}.phpis intended for that.
7.2. Recommendations on structure
It is recommended to define a variable for the theme's root path:
$themeDir = Cot::$cfg['themes_dir'] . '/' . Cot::$usr['theme'];This ensures uniformity and reduces the risk of typos.
7.3. Recommendations on resource order
The order of resource inclusion (the $order values):
- 10–20 — base libraries (jQuery);
- 20–40 — frameworks (Bootstrap);
- 40–70 — plugins (Select2, Fancybox, Perfect Scrollbar);
- 100–150 — theme scripts;
- 800–900 — theme overrides.
7.4. Recommendations on placement
CSS resources:
- base libraries — in
<head>; - plugins — in
<head>; - theme styles — in
<head>; - overrides — in
<head>with a high$order.
JavaScript resources:
- jQuery — in
<head>; - Bootstrap bundle — in
<head>(with consolidation) or in the footer; - plugins — in the footer;
- theme scripts — in the footer;
- initialisation scripts — in the footer with the maximum
$order.
7.5. File template
<?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> (critical)
Resources::addFile($themeDir . '/js/header.first.js', 'js', 40);
// JS — footer
Resources::linkFileFooter('lib/bootstrap/js/bootstrap.bundle.min.js', 'js', 30);
Resources::linkFileFooter($themeDir . '/js/theme.js', 'js', 100);8. Reference of the Resources class
8.1. Public methods
Resources::addFile($path, $type = '', $order = 50, $scope = 'global')
Registers a file in the <head> registry. When consolidation is enabled, the file may be concatenated with others into a single asset.
Parameters:
$path— path to the file, full URL, or alias;$type—'js'or'css'; if empty, it is determined by extension;$order— output order (default 50);$scope— visibility scope (global,guest,user,group_{id}).
Returns true on success, false on duplicate file. Throws an Exception if the local file is not found.
Resources::linkFile($path, $type = '', $order = 50)
Adds a file to <head> without consolidation. The HTML is generated immediately.
Resources::linkFileFooter($path, $type = '', $order = 50)
Adds a file to the footer. The HTML is generated immediately.
Resources::addEmbed($code, $type = 'js', $order = 50, $scope = 'global', $identifier = '')
Registers embedded code in <head>. When consolidation and minification are enabled, the code is saved to a file in the cache_dir/assets/ directory.
Resources::embed($code, $type = 'js', $order = 50, $attr = '')
Immediate insertion of code into <head>.
Resources::embedFooter($code, $type = 'js', $order = 50, $attr = '')
Immediate insertion of code into the footer.
Resources::setAlias($alias, $path, $canReWrite = false)
Registers or overrides an alias. By default, rewriting is prohibited.
Resources::getAlias($alias)
Returns the path for the alias, or null.
Resources::isFileAdded($fileName)
Checks whether the specified file or alias has been previously added.
Resources::minify($code, $type)
Performs minification of JavaScript (via lib/jsmin.php) or CSS (via lib/cssmin.php).
8.2. Predefined aliases
The Resources class contains the following predefined aliases:
@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
Class constants:
Resources::JQUERYResources::BOOTSTRAPResources::CKEDITORResources::SELECT2
8.3. The scope mechanism
The $scope parameter determines the resource's visibility scope:
global— the resource is always included;guest— only for guests ($usr['id'] === 0);user— only for authorised users ($usr['id'] > 0);group_{id}— only for users whosemaingrpequals{id}.
The visibility scope is applied during output in Resources::render().
8.4. The order mechanism
The $order parameter determines the output order. A smaller value corresponds to earlier output. The default is 50.
8.5. Consolidation and minification
Under the condition $cfg['cache'] && $cfg['headrc_consolidate'] && !$isAdmin, the Resources class performs consolidation of resources of the same type and visibility scope into a single file:
cache_dir/assets/{scope}.{theme}.{type}— the resulting file;cache_dir/assets/{scope}.{theme}.{type}.idx— the file index;cache_dir/assets/{scope}.{theme}.{type}.gz— the gzip version.
The consolidated file is served via the URL rc.php?rc={scope}.{theme}.{type}&nc={mtime}.
9. Common errors and how to fix them
9.1. Using $cfg['defaulttheme'] for theme resource paths
Symptom: when the default theme is changed or multiple themes are present, the front-end part crashes with an Exception error.
Cause: inside .rc.php, a path is formed via Cot::$cfg['themes_dir'] . '/' . Cot::$cfg['defaulttheme'], which does not correspond to the folder from which the file was included.
Solution: use Cot::$usr['theme'].
9.2. Using the $theme variable
Symptom: the warning Undefined variable $theme or an incorrect path.
Cause: the $theme variable is assigned in common.php later, in the Theme / color scheme block.
Solution: use Cot::$usr['theme'].
9.3. Duplicate resources
Symptom: the source HTML contains duplicate <script> and <link> tags for jQuery, Bootstrap, or other libraries.
Cause: re-registration of resources already included via cot_rc_add_standard().
Solution: do not add jQuery, jqModal, base.js, ajax_on.js again.
9.4. Placing CSS in the footer
Symptom: the <link rel="stylesheet"> tag is located at the end of <body>.
Cause: using Resources::linkFileFooter() for CSS files.
Solution: place CSS files in <head> via Resources::addFile() or Resources::linkFile().
9.5. Placing all JS in the head
Symptom: slow page loading, blocking of HTML parsing.
Cause: all JS files are registered via Resources::addFile() in <head>.
Solution: place non-critical JS in the footer via Resources::linkFileFooter(). In <head>, leave only jQuery and scripts critical for the initial render.
9.6. Ignoring the addFile exception
Symptom: the front-end part crashes when a file is missing.
Cause: Resources::addFile() throws an Exception if the local file is not found.
Solution: check the file's existence via file_exists() before registration if the file may be missing.
9.7. Modifying $theme_reload
Symptom: overrides of $L and $R do not work or work incorrectly.
Cause: manual interference with the $theme_reload array.
Solution: do not modify $theme_reload manually. Overrides are performed via $L and $R in the file {theme}.php.
9.8. Using deprecated wrappers
Symptom: the deprecated warning appears in the logs.
Cause: using cot_rc_add_file(), cot_rc_add_embed(), cot_rc_link_file().
Solution: use the methods of the Resources class.
9.9. Incorrect order
Symptom: theme styles are overridden by plugin or library styles.
Cause: insufficiently high $order value for theme styles.
Solution: set the $order for theme styles in the range 800–900.
9.10. Database access
Symptom: slowdown of page loading.
Cause: execution of SQL queries inside .rc.php.
Solution: move the logic to the controller or module.
10. Diagnostics and debugging
10.1. Checking variable values
For diagnostics, you may temporarily add the following to the top of .rc.php:
error_log('usr theme: ' . Cot::$usr['theme']);
error_log('default theme: ' . Cot::$cfg['defaulttheme']);
error_log('themes dir: ' . Cot::$cfg['themes_dir']);The records will go to the web server's error log.
10.2. Checking file inclusion
To verify that .rc.php is actually included:
error_log('rc.php loaded from: ' . __FILE__);10.3. Checking the resource registry
To view the registered resources:
error_log('headerRc: ' . print_r(Resources::$headerRc ?? null, true));Accessing the protected fields of the class requires caution and is used only for debugging purposes.
10.4. Checking consolidation
To verify the consolidation status:
error_log('consolidate: ' . (int) Cot::$cfg['headrc_consolidate']);
error_log('cache: ' . (int) Cot::$cfg['cache']);10.5. Checking exceptions
Wrapping Resources::addFile() calls in try/catch:
try {
Resources::addFile($themeDir . '/css/theme.css', 'css', 800);
} catch (Exception $e) {
error_log('Resource error: ' . $e->getMessage());
}This approach allows isolating the problem without crashing the page.
10.6. Enabling the debug mode
When Cot::$cfg['debug_mode'] === true, the engine outputs additional information. The check can be performed via:
error_log('debug_mode: ' . (int) Cot::$cfg['debug_mode']);11. Conclusion
The choice between Cot::$usr['theme'] and Cot::$cfg['defaulttheme'] in the .rc.php file is determined by the architecture of the Cotonti engine.
The .rc.php file is included by the engine from the folder themes/{$usr['theme']}/. This means that the $usr['theme'] variable at the moment of file execution is guaranteed to contain the name of the current theme. All resources registered inside the file pertain precisely to that folder.
The $cfg['defaulttheme'] variable contains the default site setting. It coincides with $usr['theme'] only when a number of conditions are met:
- the
forcedefaultthemeflag is enabled; - all users'
user_themecoincides withdefaulttheme; defaultthemehas not been changed.
In the general case there is no coincidence, and using $cfg['defaulttheme'] leads to the formation of incorrect paths. The Resources class throws an Exception, and the front-end part of the site crashes.
Rule: to build paths to theme resources inside .rc.php, use Cot::$usr['theme'].
Rationale: the file is included from the folder themes/{$usr['theme']}/, therefore the resources belong to that very theme. Using $cfg['defaulttheme'] violates this correspondence.
This rule applies to all theme resources: CSS, JavaScript, images, fonts, and any other files located inside the theme folder.
Reference table: when to use $cfg['defaulttheme'] and when to use Cot::$usr['theme']
Below is a table constructed exclusively on the basis of an analysis of the Cotonti source code (system/common.php, system/functions.php, system/resources.php, system/admin/admin.functions.php). Each row is a real usage case taken from the engine.
Table 1. Legitimate cases of using $cfg['defaulttheme']
| No. | File / place in code | Task | Why specifically $cfg['defaulttheme'] | Example from the source |
|---|---|---|---|---|
| 1 | system/common.php, initialisation of the $usr array | Set a default value before the user is determined | At the moment the user data array is created, the user does not yet exist. Some starting value is needed. For a guest, this is the default site theme | 'theme' => $cfg['defaulttheme'], |
| 2 | system/common.php, computation of $usr['theme'] for an authorised user | Force the theme for all users | If the administrator has enabled forcedefaulttheme, the engine is obliged to take the global theme rather than the user's personal preferences | $usr['theme'] = $cfg['forcedefaulttheme'] ? $cfg['defaulttheme'] : $row['user_theme']; |
| 3 | system/common.php, checking the existence of the header | Substitute the missing theme with the default one | The user's theme is physically missing. The only reasonable fallback is the default site theme | $usr['theme'] = $cfg['defaulttheme']; (after if (!file_exists($mtheme))) |
| 4 | system/common.php, final fallback error | Acknowledge a complete failure of theming | Even the default theme is unavailable. Only an emergency termination remains | if (!file_exists($mtheme)) { cot_diefatal($L['com_defthemefail']); } |
| 5 | system/functions.php, the cot_schemeFile() function | Return the path to the CSS file of the colour scheme | The function may be called before $usr is initialised. If $usr['theme'] has not yet been set, the default value is taken | $theme = isset($usr['theme']) ? $usr['theme'] : $cfg['defaulttheme']; |
Conclusion on Table 1: $cfg['defaulttheme'] is used only in three roles:
- starting value (initialisation);
- forced value (
forcedefaulttheme = true); - emergency fallback (theme unavailable).
In all other cases, it is not the right source.
Table 2. Places where $cfg['defaulttheme'] must not be used, and where Cot::$usr['theme'] is required
| No. | File / place in code | Task | Why Cot::$usr['theme'] | Example from the source |
|---|---|---|---|---|
| 1 | system/common.php, inclusion of the theme's .rc.php | Locate the resource file of the current theme | The file is physically included from the folder {$usr['theme']}. Hence, inside the file as well, $usr['theme'] = the name of this theme | include "{$cfg['themes_dir']}/{$usr['theme']}/{$usr['theme']}.rc.php"; |
| 2 | system/common.php, inclusion of {theme}.php | The file that overrides $L/$R | It is tied to the folder of the current theme, not to the global setting | $sys['theme_resources'] = "{$cfg['themes_dir']}/{$usr['theme']}/{$usr['theme']}.php"; |
| 3 | system/common.php, the theme's language file | Load translations of the current theme | The user's theme may differ from defaulttheme | $usr['theme_lang'] = "{$cfg['themes_dir']}/{$usr['theme']}/{$usr['theme']}.{$usr['lang']}.lang.php"; |
| 4 | system/common.php, the header template | Locate header.tpl | It is tied to the folder of the current theme | $mtheme = "{$cfg['themes_dir']}/{$usr['theme']}/header.tpl"; |
| 5 | system/functions.php, cot_tplfile() | Locate any .tpl of the current theme | All front-end templates are located in the folder $usr['theme'] | $theme = !empty($usr['theme']) ? $usr['theme'] : ''; |
| 6 | system/common.php, the theme's .rc.php (internal logic) | Paths to the theme's assets | The file is included from the folder of that very theme | $themeDir = Cot::$cfg['themes_dir'] . '/' . Cot::$usr['theme']; |
| 7 | system/resources.php, additionalFiles() for @select2 | Searching for the Select2 i18n file for the user's language | It is tied to the language, and the theme is irrelevant here — but the example shows that theme resources are tied to the user's context | $select2i18n = 'lib/select2/js/i18n/' . Cot::$usr['lang'] . '.js'; |
Conclusion on Table 2: everything related to files inside the theme folder (CSS, JS, templates, languages, .rc.php, .php) must use Cot::$usr['theme'].
Table 3. Admin context: where $cfg['defaulttheme'] and $usr['theme'] do not work, and a third source is needed
| No. | File / place in code | Task | Which variable to use | Example from the source |
|---|---|---|---|---|
| 1 | system/common.php, the admin theme's language file | Load translations of the admin theme | $cfg['admintheme'] | $usr['def_theme_lang'] = "{$cfg['themes_dir']}/admin/{$cfg['admintheme']}/{$cfg['admintheme']}.en.lang.php"; |
| 2 | system/common.php, the admin theme's resource file | Include {admintheme}.php | $cfg['admintheme'] | $sys['theme_resources'] = "{$cfg['themes_dir']}/admin/{$cfg['admintheme']}/{$cfg['admintheme']}.php"; |
| 3 | system/common.php, the path to the admin templates | Locate the admin theme's .tpl | $cfg['admintheme'] | Used in cot_tplfile() via the variable $adminTheme |
| 4 | system/admin/admin.functions.php | Resource inclusion | Cot::$cfg['admintheme'] | Resources::addFile(Cot::$cfg['themes_dir'] . '/admin/' . Cot::$cfg['admintheme'] . '/assets/...'); |
| 5 | system/common.php, the icon pack | Icons for the interface | $cfg['defaulticons'] (fallback), $usr['icons'] (primary) | if (empty($usr['icons'])) { $usr['icons'] = $cfg['defaulticons']; } |
Conclusion on Table 3: in the admin context, a third variable is used — $cfg['admintheme']. Neither defaulttheme nor usr['theme'] is suitable for admin templates.
Table 4. Summary matrix: which variable to use in which context
| Context | Correct variable | Rationale |
|---|---|---|
| Paths to the front-end theme's CSS/JS | Cot::$usr['theme'] | The files are physically located in themes/{usr['theme']}/ |
Paths to the front-end theme's .tpl | Cot::$usr['theme'] | All front-end templates are tied to the user's theme folder |
Paths to the front-end theme's .php (.rc.php, {theme}.php, {theme}.lang.php) | Cot::$usr['theme'] | These files are included precisely from the usr['theme'] folder |
| Emergency fallback when the theme is missing | $cfg['defaulttheme'] | The only reasonable source in case of failure |
Initialisation of the $usr array before the user is determined | $cfg['defaulttheme'] | Starting value |
Forced theme (forcedefaulttheme = true) | $cfg['defaulttheme'] | Direct purpose of the flag |
| Paths to the admin theme's CSS/JS | $cfg['admintheme'] | The admin panel uses a separate theme |
Paths to the admin theme's .tpl | $cfg['admintheme'] | Similarly |
| Language files of the admin theme | $cfg['admintheme'] | Similarly |
| Emergency termination when the default theme is missing | $cfg['defaulttheme'] | Only for the cot_diefatal() check |
Table 5. Practical substitutions: what to write in a specific file
| File | What to write | Why |
|---|---|---|
themes/{theme}/{theme}.rc.php | Cot::$cfg['themes_dir'] . '/' . Cot::$usr['theme'] . '/...' | The file is included by the engine from the current theme's folder |
themes/{theme}/{theme}.php | $L[...], $R[...] (without paths) | String overrides; they are not tied to a folder |
themes/admin/{admintheme}/{admintheme}.rc.php | Cot::$cfg['themes_dir'] . '/admin/' . Cot::$cfg['admintheme'] . '/...' | The admin theme is set separately |
themes/admin/{admintheme}/{admintheme}.php | $L[...], $R[...] (without paths) | Admin string overrides |
system/functions.php, helpers | $usr['theme'] ?? $cfg['defaulttheme'] | Fallback in case $usr['theme'] is missing |
system/common.php, initial initialisation | $cfg['defaulttheme'] | The user is not yet determined |
system/common.php, computation of $usr['theme'] | $cfg['forcedefaulttheme'] ? $cfg['defaulttheme'] : $row['user_theme'] | Forcing or personal choice |
system/common.php, fallback | $cfg['defaulttheme'] | The only reasonable source in case of failure |
Table 6. Antipatterns: where $cfg['defaulttheme'] must not be used and why
| No. | What is written incorrectly | Why this is an error | What it should be |
|---|---|---|---|
| 1 | Inside {theme}.rc.php: Cot::$cfg['themes_dir'] . '/' . Cot::$cfg['defaulttheme'] . '/assets/...' | The file is included from the usr['theme'] folder. The path leads to another folder when they diverge | Cot::$cfg['themes_dir'] . '/' . Cot::$usr['theme'] . '/assets/...' |
| 2 | Inside {theme}.rc.php: Cot::$cfg['themes_dir'] . '/' . Cot::$cfg['defaulttheme'] . '/js/...' | Similarly | Cot::$cfg['themes_dir'] . '/' . Cot::$usr['theme'] . '/js/...' |
| 3 | Inside {theme}.php: links to theme files via defaulttheme | The file pertains to the current theme, not to the global setting | $usr['theme'] |
| 4 | In theme templates: {PHP.cfg.defaulttheme} for asset paths | In a template, one can use {PHP.usr.theme} — then the path is always correct | {PHP.usr.theme} |
| 5 | In the admin theme: Cot::$cfg['defaulttheme'] for admin asset paths | The admin panel uses a separate theme set in $cfg['admintheme'] | Cot::$cfg['admintheme'] |
| 6 | In the admin theme: Cot::$usr['theme'] for admin asset paths | The front-end user theme has no relation to the admin interface | Cot::$cfg['admintheme'] |
Table 7. Quick cheat sheet "what to take in a given situation"
| Situation | Source |
|---|---|
The front-end theme's .rc.php file is included by the engine | Cot::$usr['theme'] |
The front-end theme's .php file (overrides of $L/$R) | No paths — only $L/$R |
The admin theme's .rc.php file is included by the engine | Cot::$cfg['admintheme'] |
The admin theme's .php file (overrides of $L/$R) | No paths — only $L/$R |
A global function that may be called before $usr | $usr['theme'] ?? $cfg['defaulttheme'] |
Initialisation of $usr for a guest | $cfg['defaulttheme'] |
| Forcing the theme for all users | $cfg['defaulttheme'] |
| Emergency fallback when the theme is missing | $cfg['defaulttheme'] |
Paths to front-end templates (cot_tplfile()) | Cot::$usr['theme'] |
Paths to admin templates (cot_tplfile()) | Cot::$cfg['admintheme'] |
Key rules based on the results of the tables
$cfg['defaulttheme']— only three roles: initialisation, forcing, emergency fallback.Cot::$usr['theme']— all paths to files inside the current front-end theme folder.$cfg['admintheme']— all paths to files inside the admin theme folder.$usr['theme'] ?? $cfg['defaulttheme']— a compromise for global functions with an undefined context.- Neither in
.rc.php, nor in{theme}.php, nor in front-end templates may one substitute$cfg['defaulttheme']for paths to the current theme's assets.