DefaultThemeResolver
in package
implements
ThemeResolverInterface
Table of Contents
Interfaces
Constants
- SKIN_COOKIE : mixed = 'cms_skin_override'
- Cookie remembering the color variant choice for later clicks.
- SKIN_QUERY_PARAM : mixed = '_skin'
- Query parameter that switches the color variant: `?_skin=modra` (`?_skin=off` switches back).
- SWITCH_COOKIE : mixed = 'cms_theme_override'
- Cookie remembering the switch for later clicks (session cookie, no expiry).
- SWITCH_QUERY_PARAM : mixed = '_theme'
- Query parameter that switches the front theme: `?_theme=template3` (`?_theme=off` switches back).
- SWITCH_RESET_VALUES : mixed = ['off', 'reset', 'default', 'none']
- `?_theme=...` values that cancel the switch and return to the theme from the settings.
Properties
- $availableThemesCache : array<string, array<int, string>>
- Per-request memo of {@see availableThemes()}.
- $deviceDetector : DeviceDetector
- $httpRequest : Request
- $httpResponse : Response
- $settingsSkinName : string|null
- Skin from the website settings, i.e. before the switch ({@see settingsSkinName()}).
- $settingsThemeName : string|null
- Theme name from the website settings, i.e. before the switch ({@see settingsThemeName()}).
- $theme : Theme|null
Methods
- __construct() : mixed
- activeSkinName() : string|null
- Returns the skin that is really rendered for this request; NULL is the base appearance.
- availableThemes() : array<int, string>
- Returns the theme directories one can switch to: only those with a `desktop/` variant (without it `formatLayoutTemplateFiles()` would not find a layout and the page would fail).
- formatTemplateFiles() : array<int, string>
- Returns the candidate action templates, in order of preference.
- frontendThemesDir() : string|null
- Returns the root of the front themes (`.../www/themes/frontend/`), or NULL outside the front branch (the resolver also passes the admin theme through it, see {@see applyLocalOverride()}).
- getTheme() : Theme|null
- isSkinSwitchingAllowed() : bool
- Returns whether URL/cookie may switch the skin.
- isSwitchingAllowed() : bool
- Returns whether URL/cookie may switch the theme.
- resolve() : T
- setTheme() : void
- settingsSkinName() : string|null
- Returns the skin set in the admin, i.e. what a visitor without their own choice sees.
- settingsThemeName() : string|null
- Returns the theme set in the admin, i.e. what a visitor without their own choice sees.
- applyLocalOverride() : void
- Switches the theme: the URL parameter `?_theme=<directory>` (remembered in a session cookie so the site can be browsed), or the environment variable `CMS_THEME_OVERRIDE` as the default theme of a server run.
- applySkinOverride() : void
- Picks the skin for this request: the website setting, or `?_skin=...`/cookie/env.
- formatTemplateFiles_inMainThemeFolder() : array<int, string>
- getNamePartsForThemePath() : array<int, string>
- isValidThemeName() : bool
- A directory name only: no `../`, no absolute path.
- rememberChoice() : void
- Remembers (or forgets) the choice in a session cookie, for both theme and skin.
- resolveOverride() : string|null
- Shared core of both switches; theme and skin are decided identically and differ only in the input names.
- resolveOverrideName() : string|null
- Returns the theme directory name that overrides the DB setting, or NULL (leave unchanged).
- resolveSkinOverrideName() : string|null
- Returns the skin name that overrides the setting, or NULL (keep the configured one).
- themeTemplateCandidate() : string|null
- Returns the path the template should have in the theme, whether or not it exists. Used only to name the missing file in the 404 message ({@see self::formatTemplateFiles()}).
Constants
SKIN_COOKIE
Cookie remembering the color variant choice for later clicks.
private
mixed
SKIN_COOKIE
= 'cms_skin_override'
SKIN_QUERY_PARAM
Query parameter that switches the color variant: `?_skin=modra` (`?_skin=off` switches back).
private
mixed
SKIN_QUERY_PARAM
= '_skin'
SWITCH_COOKIE
Cookie remembering the switch for later clicks (session cookie, no expiry).
private
mixed
SWITCH_COOKIE
= 'cms_theme_override'
SWITCH_QUERY_PARAM
Query parameter that switches the front theme: `?_theme=template3` (`?_theme=off` switches back).
private
mixed
SWITCH_QUERY_PARAM
= '_theme'
SWITCH_RESET_VALUES
`?_theme=...` values that cancel the switch and return to the theme from the settings.
private
mixed
SWITCH_RESET_VALUES
= ['off', 'reset', 'default', 'none']
Properties
$availableThemesCache
Per-request memo of {@see availableThemes()}.
private
array<string, array<int, string>>
$availableThemesCache
= []
The method runs scandir() and is_dir() per entry and the appearance switcher calls it on
every rendered page (ThemeSwitcher).
Theme directories do not change during a request, so a second disk read gains nothing.
IMPORTANT: the key is the root of the front branch, not just NULL/array:
frontendThemesDir() derives from the active theme, which changes during resolve()
(override). Without the key the memo could return the list of another root.
$deviceDetector
private
DeviceDetector
$deviceDetector
$httpRequest
private
Request
$httpRequest
$httpResponse
private
Response
$httpResponse
$settingsSkinName
Skin from the website settings, i.e. before the switch ({@see settingsSkinName()}).
private
string|null
$settingsSkinName
= NULL
$settingsThemeName
Theme name from the website settings, i.e. before the switch ({@see settingsThemeName()}).
private
string|null
$settingsThemeName
= NULL
$theme
private
Theme|null
$theme
= NULL
Methods
__construct()
public
__construct(DeviceDetector $deviceDetector, Request $httpRequest, Response $httpResponse) : mixed
Parameters
- $deviceDetector : DeviceDetector
- $httpRequest : Request
- $httpResponse : Response
activeSkinName()
Returns the skin that is really rendered for this request; NULL is the base appearance.
public
activeSkinName() : string|null
Return values
string|nullavailableThemes()
Returns the theme directories one can switch to: only those with a `desktop/` variant (without it `formatLayoutTemplateFiles()` would not find a layout and the page would fail).
public
availableThemes() : array<int, string>
Plain directory names sorted alphabetically; the active theme is among them. An empty array means nothing to switch to, and the caller then does not render the switcher.
IMPORTANT: it reads from the front branch by the active theme, not from %wwwDir%, which is
computed from the outermost stack frame and points elsewhere in CLI and harnesses.
Return values
array<int, string>formatTemplateFiles()
Returns the candidate action templates, in order of preference.
public
formatTemplateFiles(Presenter $presenter) : array<int, string>
IMPORTANT: it must never return an empty array. After a failed search Nette's
Presenter::findTemplateFile() reaches for $files[0] to name the missing template in
the message and send a nice 404. Over an empty array that is a TypeError in strtr(), i.e.
HTTP 500 instead of 404 for every missing front template.
So the result is only preferred by existence, not filtered: when nothing exists, the candidates
are returned anyway. On the happy path nothing changes: an existing file is still first and
findTemplateFile() takes it before it gets to the candidates.
Parameters
- $presenter : Presenter
Return values
array<int, string>frontendThemesDir()
Returns the root of the front themes (`.../www/themes/frontend/`), or NULL outside the front branch (the resolver also passes the admin theme through it, see {@see applyLocalOverride()}).
public
frontendThemesDir() : string|null
Return values
string|nullgetTheme()
public
getTheme() : Theme|null
Return values
Theme|nullisSkinSwitchingAllowed()
Returns whether URL/cookie may switch the skin.
public
isSkinSwitchingAllowed() : bool
It has its own switch CMS_SKIN_SWITCH, separate from the theme switch CMS_THEME_SWITCH.
Both are on until someone turns them off explicitly.
NOTE: turning the theme switch off does not turn skins off, on purpose: CMS_THEME_SWITCH=0
means "this installation has one theme", which says nothing about its color variants. To lock
the appearance completely, set both variables to 0.
Return values
boolisSwitchingAllowed()
Returns whether URL/cookie may switch the theme.
public
isSwitchingAllowed() : bool
Always on, for every visitor: the switcher is part of the CMS showcase
(ThemeSwitcher), not only a
developer aid. It is turned off only by env CMS_THEME_SWITCH=0, for an installation that
should not have the switcher. A visitor can switch the appearance, but only through their own
session cookie; everyone else sees the site as set in the admin.
NOTE: only directories that really exist in www/themes/frontend/ are offered
(availableThemes()), so with a single theme there is nothing to switch.
Return values
boolresolve()
public
resolve(ThemeManagerInterface<string|int, T> $themeManager) : T
Parameters
- $themeManager : ThemeManagerInterface<string|int, T>
Tags
Return values
TsetTheme()
public
setTheme(Theme|null $theme) : void
Parameters
- $theme : Theme|null
settingsSkinName()
Returns the skin set in the admin, i.e. what a visitor without their own choice sees.
public
settingsSkinName() : string|null
The switcher uses it to know that "back to default" must delete the cookie instead of setting it to the same value (same reasoning as settingsThemeName()).
NOTE: after switching the theme it is meaningless, since the configured skin belongs to the theme from the settings, not the switched one. It then returns NULL so that the switcher offers "base appearance" as the default choice.
Return values
string|nullsettingsThemeName()
Returns the theme set in the admin, i.e. what a visitor without their own choice sees.
public
settingsThemeName() : string|null
The switcher uses it to know that "back to default" must delete the cookie (?_theme=off)
instead of setting it to the same value; otherwise clicking the default appearance would pin a
state that survives a later theme change in the admin.
NOTE: precisely it is what a visitor without their own choice sees, so on a server started with
CMS_THEME_OVERRIDE it is that variable, not the DB row. Without this exception the switcher
would offer to cancel the choice for a theme that cannot be reached there anyway.
Return values
string|nullapplyLocalOverride()
Switches the theme: the URL parameter `?_theme=<directory>` (remembered in a session cookie so the site can be browsed), or the environment variable `CMS_THEME_OVERRIDE` as the default theme of a server run.
private
applyLocalOverride(Theme|null $theme) : void
The switch is not a setting because theme.frontend.path is one row in cms_system_settings
and the table has no environment column. The database is shared by dev and production, so
overwriting it would change the theme on the live site too, and since production lacks the
files of a new theme, all its front pages would fail on missing layouts. This switch leaves the
database alone and acts only where the variable is set:
CMS_THEME_OVERRIDE=template2 php -S 127.0.0.1:8099 -t www
Without the variable the method is a no-op; production never sets it. A nonexistent directory is ignored so that a typo cannot take the site down.
IMPORTANT: it acts only on the front theme. The resolver is one shared service and
resolve() also passes the admin theme through it
(ThemeMapper). Without the branch check the admin
theme would be overridden too and the admin would look for layouts in
/www/themes/frontend/<override>/desktop/layouts/, where @layout.latte and @login.latte do
not exist. Presenter::findLayoutTemplateFile() then silently returns null, so the whole
admin renders as a bare {block content} without <html>, CSS and JS, with nothing in the log.
Parameters
- $theme : Theme|null
applySkinOverride()
Picks the skin for this request: the website setting, or `?_skin=...`/cookie/env.
private
applySkinOverride(Theme|null $theme) : void
IMPORTANT: the skin is checked against the resulting theme, i.e. after applyLocalOverride(). Skins belong to a concrete theme; after switching to another one the configured name would point into a directory that does not exist there. A nonexistent skin therefore falls back to NULL (base appearance) instead of rendering a link to a 404.
IMPORTANT: the admin branch respects the skin from the settings (theme.admin.skin) but has no
?_skin=/cookie/env switching, on purpose. The visitor switcher is an offer for anonymous front
visitors; the admin looks the same for everyone per one setting, so a URL parameter would let
anybody override the appearance the administrator chose.
Parameters
- $theme : Theme|null
formatTemplateFiles_inMainThemeFolder()
private
formatTemplateFiles_inMainThemeFolder(Presenter $presenter) : array<int, string>
Parameters
- $presenter : Presenter
Return values
array<int, string>getNamePartsForThemePath()
private
getNamePartsForThemePath(Presenter $presenter) : array<int, string>
Parameters
- $presenter : Presenter
Return values
array<int, string>isValidThemeName()
A directory name only: no `../`, no absolute path.
private
isValidThemeName(string $name) : bool
Parameters
- $name : string
Return values
boolrememberChoice()
Remembers (or forgets) the choice in a session cookie, for both theme and skin.
private
rememberChoice(string $cookieName, string|null $name) : void
expire NULL makes a session cookie: the choice disappears when the browser closes, so the
appearance is not fixed for a visitor forever.
Parameters
- $cookieName : string
- $name : string|null
resolveOverride()
Shared core of both switches; theme and skin are decided identically and differ only in the input names.
private
resolveOverride(string $envName, string $queryParam, string $cookieName, bool $switchingAllowed) : string|null
Priority: ?<param>=..., then cookie, then env. A reset (off/reset/default/none or an
empty value) forgets the choice and returns env, not the DB value; see
resolveOverrideName().
Parameters
- $envName : string
- $queryParam : string
- $cookieName : string
- $switchingAllowed : bool
-
whether URL/cookie may switch; passed in because theme and skin have separate switches, see isSkinSwitchingAllowed()
Return values
string|nullresolveOverrideName()
Returns the theme directory name that overrides the DB setting, or NULL (leave unchanged).
private
resolveOverrideName() : string|null
Priority, strongest first:
?_theme=<directory>in the URL: the freshest and most explicit intent, stored in the cookie.?_theme=off(andreset/default/none) deletes the cookie.- The cookie from an earlier
?_theme=...: keeps the switch across clicks. - Env
CMS_THEME_OVERRIDE: the default theme of that server run.
The URL ranks above env on purpose: CMS_THEME_OVERRIDE=template2 php -S ... configures the
whole server run, not one window. If env won, ?_theme=template3 would silently do nothing on
such a server. So ?_theme=off means "back to the default theme of the run", i.e. env when set,
not the DB theme.
Points 1 and 2 work only where isSwitchingAllowed() permits.
Return values
string|nullresolveSkinOverrideName()
Returns the skin name that overrides the setting, or NULL (keep the configured one).
private
resolveSkinOverrideName() : string|null
Same priority as for the theme: ?_skin=..., then cookie, then env CMS_SKIN_OVERRIDE.
?_skin=off (and reset/default/none) cancels the choice and returns to the website
setting.
IMPORTANT: it is gated by isSkinSwitchingAllowed(), not isSwitchingAllowed().
Otherwise CMS_THEME_SWITCH=0 would silence skins too, and on an installation with a single
theme and several color variants the only switchable thing would be turned off.
Return values
string|nullthemeTemplateCandidate()
Returns the path the template should have in the theme, whether or not it exists. Used only to name the missing file in the 404 message ({@see self::formatTemplateFiles()}).
private
themeTemplateCandidate(Presenter $presenter) : string|null
Parameters
- $presenter : Presenter