This page is the configuration reference for Nocterra. It lists configuration keys, their meaning, valid values, defaults, and where each key can be set (site-wide, per language, per category, and so on).
If you want guided explanations and practical examples, see the Manual. If you are authoring articles, start with Manual: Blog Articles.
Configuration is defined in site.php using nested PHP arrays. In this reference, keys are shown exactly as they appear in configuration. Examples are written in the same nested-array style so they can be copied and adapted directly.
This section covers site-wide configuration that affects the entire installation (global behavior, policies, and defaults). Reference tables for these keys are listed below.
Boolean on/off value.
Use this type for settings that toggle a feature on or off. In Nocterra configuration, boolean values are typically written as the PHP keywords TRUE and FALSE.
Compatibility:
For simple on/off switches it is also common to use numeric forms 1 and 0. These are treated as TRUE and FALSE respectively in PHP boolean context and are acceptable for boolean settings such as rdfa.
Important:
Even though 1/0 are accepted, the setting is still a boolean switch. It is not an “integer setting”, and values like 10 do not carry “more true” meaning. Use TRUE/FALSE (or 1/0) only.
Note:
Other truthy/falsey spellings such as YES/NO and ON/OFF may be supported in some map-style key/value contexts, but they should not be assumed for settings unless explicitly documented.
<?PHP
'<setting>' => TRUE,
'<setting>' => FALSE,
'<setting>' => 1,
'<setting>' => 0,
?>
Content Security Policy specification (Nocterra keyword form).
This type configures the Content Security Policy (CSP) that Nocterra outputs for the page:
Nocterra emits a <META http-equiv="Content-Security-Policy" ...> tag in the HTML head, and later also sends a Content-Security-Policy: HTTP response header with the same value.
The configuration uses Nocterra directive keywords that map to official CSP directives. The Nocterra keywords are intentionally simpler and easier to read.
Nocterra directive keywords (recommended):
default Maps to default-src
fonts Maps to font-src
images Maps to img-src
media Maps to media-src
styles Maps to style-src
frames Maps to frame-src
ancestors Maps to frame-ancestors
workers Maps to worker-src
forms Maps to form-action
scripts Maps to script-src
connect Maps to connect-src
objects Maps to object-src
manifests Maps to manifest-src
Reporting (Nocterra keyword):
report Controls whether Nocterra appends a report-uri directive.
The value may be:
boolean/numeric: on/off
'no', 'off', 'none': off
When enabled, Nocterra can emit a site-specific report endpoint placeholder.
Notes:
Directive values are written in CSP syntax (for example 'self', 'none', specific hosts, etc.).
Nocterra strips characters such as quotes and semicolons from directive names/values before outputting them in the CSP meta/header.
Some directives may gain extra keywords automatically when reporting is enabled (for example adding 'report-sample' for default).
<?PHP
'<setting>' => array(
'default' => "'self'",
'styles' => "'self'",
'scripts' => "'self'",
'images' => "'self' data:",
'ancestors' => "'none'",
'forms' => "'self'",
),
'<setting>' => array(
'report' => true,
'frames' => "https://www.youtube-nocookie.com",
),
'<setting>' => array(
'report' => true,
'frames' => "https://www.youtube-nocookie.com https://www.youtube.com https://www.google.com https://consent.google.nl",
),
'<setting>' => array(
'report' => true,
'frames' => "https://www.youtube-nocookie.com",
'images' => "'self' https://i.ytimg.com",
),
'<setting>' => "default-src 'self'; style-src 'self'; script-src 'self'; img-src 'self' data:; frame-ancestors 'none'; form-action 'self'",
?>
Enumerated content type value.
This type is used to select a structured content type for pages. Only the values listed below are considered valid for this type.
Allowed values:
WebPage
BlogPosting
Article
NewsArticle
Notes:
Values containing Article
are typically treated as article-like in social meta output.
If NULL is used (or the setting is omitted), the renderer may fall back to the resource type for the requested path.
<?PHP
'<setting>' => 'WebPage',
'<setting>' => 'BlogPosting',
'<setting>' => 'NewsArticle',
'<setting>' => NULL,
?>
Enumeration used by environment.data_store to select the URL-path to /data filename mapping mode.
<?PHP
'<setting>' => 'locale_prefix',
'<setting>' => 'locale_directory',
'<setting>' => 'locale_prefix_menu',
?>
Time duration in seconds (integer).
Use this type for settings that represent a duration, such as HTTP cache max-age values.
Values are interpreted as seconds.
Write the value as a plain integer (for example 300) or as a PHP expression (for example 24*60*60), without quotes.
<?PHP
'<setting>' => 300,
'<setting>' => 3600,
'<setting>' => 86400,
'<setting>' => 24*60*60,
?>
Footer column specification.
This type defines the structure of page<language>.footer.columns. The footer columns are rendered as a set of categories. The number of top-level entries determines the footer layout class (columns-1, columns-2, …).
Each column is defined as:
A trusted HTML fragment (string), output inside the column container, or
A link list (associative array) where each entry is label => link.
Column keys:
The key of each top-level entry is the column category label. When page<language>.footer.showHeader is enabled and the key is not empty, Nocterra outputs the category label as a heading for that column.
Practical patterns:
Use human-readable category keys (for example Service, About) for titled link lists.
Use an empty key ('') for an untitled column (for example an icon block or contact details).
Use numeric keys ('1', '2', …) primarily to control layout while keeping showHeader disabled.
Link lists:
A link list is emitted as <UL> with <LI><A> entries.
The label is shown as link text.
The link is passed through Nocterra link handling (langLink()), so local paths are typically written as /path.
To insert a visual separator line inside a link list, use an entry with an empty label or empty link (for example '' => ''). Nocterra renders that entry as a separator item.
Trusted HTML columns:
When the column value is a string, it is emitted as-is (trusted HTML). Use your own markup (<P>, <DIV>, buttons, icons, etc.). If you include your own headings (<H2>, …), you typically want page<language>.footer.showHeader disabled to avoid duplicate headings.
<?PHP
'<setting>' => array(
'Service' => array(
'FAQ' => '/service/faq',
'Downloads' => '/service/downloads',
'Privacy' => '/service/privacy',
'Contact' => '/service/contact',
),
'About' => array(
'Foundation' => '/about',
'News' => '/articles/category/news',
),
),
'<setting>' => array(
'' => '<P><A href="/donate">Support us</A></P>',
'Service' => array(
'FAQ' => '/service/faq',
'Privacy' => '/service/privacy',
),
),
'<setting>' => array(
'1' => '<P>Address…</P>',
'2' => array(
'Contact' => '/contact',
'About' => '/about',
),
),
'<setting>' => array(
'Info' => array(
'Contact' => '/contact',
'' => '',
'Privacy' => '/privacy',
),
),,
?>
Host or domain name.
This type represents a DNS host name as used by Nocterra in domain configuration. It is written without a scheme and without a path.
Rules:
Do not include http://
or https://
.
Do not include a path, query string, or fragment.
Use a plain host name such as www.example.com
.
Nocterra compares hosts as strings; keep the spelling consistent with the actual host names used by your site.
Some settings allow a leading dot (.example.com
) to cover a whole domain for cookies. If a leading dot is allowed or required, the setting documentation will explicitly say so.
<?PHP
'<setting>' => 'www.example.com',
'<setting>' => 'account.example.com',
'<setting>' => '.example.com',
?>
Trusted HTML block fragment.
Values of this type are emitted as-is in a block context (for example directly inside a <DIV>...</DIV> or directly in the HTML body). Nocterra does not escape the value.
Use this type for longer fragments that should define their own structure (<P>, <DIV>, <UL>, headings, etc.).
Because the fragment is emitted directly, it should be valid HTML for the location where it is inserted.
<?PHP
'<setting>' => '<P>Line one</P><P>Line two</P>',
'<setting>' => '<DIV class="notice"><P>Maintenance</P></DIV>',
?>
Trusted HTML inline fragment.
Values of this type are emitted into a generated structure (for example inside <TITLE>...</TITLE>, <H1>...</H1>, or inside an existing <P>...</P>). Nocterra does not escape the value.
Use this type for short inline fragments such as text with simple markup (<EM>, <STRONG>, <A>, <SPAN>).
Do not include block-level layout that would break the surrounding structure.
<?PHP
'<setting>' => 'Welcome',
'<setting>' => 'You are here: <SPAN class="hint">Home</SPAN>',
?>
Scalar integer value.
Use this type for settings that accept a whole number (no decimals). The valid range depends on the specific setting; the reference for that setting should describe any minimum/maximum constraints.
Some settings also accept NULL as a special state (for example to inherit, disable an override, or indicate “not configured”). Whether NULL is allowed and what it means is always defined by the setting, not by this type.
<?PHP
'<setting>' => 7,
'<setting>' => NULL,
?>
List of integer values.
Use this type for settings that accept an ordered list of whole numbers. In the configuration, the value is written as a PHP array.
<?PHP
'<setting>' => array(
320,
640,
1280
),
?>
Language key.
Use this type for settings that expect a language identifier that is resolved via the configured language system (languages<language>).
The value must match a configured language key (for example en or nl) in languages<language>. The language system defines the language name, locale, formatting strings, and any language-specific assets used by Nocterra.
Format:
Currently, language keys are typically ISO 639-1 two-letter codes in lowercase (for example en, nl).
Some code paths expect a two-character language key. Do not use longer tags unless your installation explicitly supports it.
Note:
A language key is not the same as a locale. Locales are values such as en_GB or nl_NL and are configured inside the languages<language> entries (and, for example, in facebook.localeMap).
<?PHP
'<setting>' => 'en',
'<setting>' => 'nl',
?>
Language selector ordering specification.
This type defines the value of page<language>.languageSelector.order.
The order can be set in two forms:
A string keyword:
as-is (default)
Use the language order as defined in the site configuration ($languages).
ascending
Sort available languages by their display name.
descending
Sort available languages by their display name (reverse).
For sorting, Nocterra uses languages.<language>.name when present, otherwise the uppercased language code.
An array of language codes:
Provide an explicit order, for example array('nl','en').
Languages that are not available for the current page are skipped.
<?PHP
'<setting>' => 'as-is',
'<setting>' => 'ascending',,
'<setting>' => array('nl', 'en'),,
?>
Language selection specification.
Use this type for settings that accept either:
a single language key (string), or
a list of language keys (array of strings).
The value(s) must match configured language keys in languages<language> (for example en or nl). The language system defines the language name, locale, formatting strings, and any language-specific assets used by Nocterra.
Format:
Currently, language keys are typically ISO 639-1 two-letter codes in lowercase (for example en, nl).
Some code paths expect a two-character language key. Do not use longer tags unless your installation explicitly supports it.
Note:
A language key is not the same as a locale. Locales are values such as en_GB or nl_NL and are configured inside the languages<language> entries (and, for example, in facebook.localeMap).
Use a single language key when the setting applies to exactly one language. Use an array when the setting applies to multiple languages.
<?PHP
'<setting>' => 'en',
'<setting>' => array('nl', 'en'),
?>
Locale code.
A locale code identifies a language and region combination used by Nocterra and PHP for localization (for example formatting of dates/times and other locale-sensitive behavior).
Locale information also affects what Nocterra emits towards browsers and bots. It influences language-related markup and metadata (for example the document language in HTML, and locale selection for services such as Facebook OpenGraph when locale mapping is configured).
Format:
Common form: language_COUNTRY (for example en_GB, en_US), fr_FR), fr_BE).
language is typically an ISO 639 language code (often two lowercase letters).
COUNTRY is typically an ISO 3166-1 alpha-2 country code (two uppercase letters).
Optional suffixes (variant/encoding) are platform-dependent and should only be used when required (for example de_DE@euro, en_US.UTF-8).
Note:
A locale code is not the same as a Nocterra language key. Language keys are the identifiers used in languages<language> (for example en, nl). The locale code defines the regional behavior for that language entry.
<?PHP
'<setting>' => 'en_GB',
'<setting>' => 'jp_JP',
?>
Enumeration that defines how page-local metadata is combined with site-wide (global) metadata for a given field.
This type is used by the environment settings author, description, title and keywords. These settings do not contain the metadata values themselves. Instead, they determine how local values (page/article) and global values (site branding) are selected and/or concatenated when the final HTML meta output is generated.
Allowed values:
local Use only the local value (if present); otherwise fall back to the global value.
prepend Combine local + global, with the local value first.
extend Combine global + local, with the global value first.
Concatenation separators:
For title, author and description, concatenation uses the corresponding separator setting (titleSeparator, authorSeparator, descriptionSeparator) when present; otherwise a default separator is used by the implementation.
For keywords, concatenation uses keyword-specific logic (addKeywords()) and does not use the separator settings in the same way as the other fields.
<?PHP
'<setting>' => 'extend',
'<setting>' => 'prepend',
'<setting>' => 'local',
?>
This type is used by settings that control where Nocterra outputs a specific element (for example the language selector, referrers block, or navigation). The value selects a named output position in the page layout.
Allowed values:
header_top Output at the top of the header area.
header_bottom Output at the bottom of the header area.
page_top Output near the top of the HTML body, before the Nocterra page body content area.
page_bottom Output near the bottom of the HTML body, after the Nocterra page body content area.
body_top Output at the top of the page body content area (the main page content).
body_bottom Output at the end of the page body content area (the main page content).
navigation_top Output at the top in the navigation area.
navigation_bottom Output at the bottom in the navigation area.
footer_top Output at the top in the footer area.
footer_bottom Output at the bottom in the footer area.
Notes:
Some settings may only support a subset of these values; that subset is documented with the setting.
If a value is not supported for a specific element, Nocterra falls back to the element’s default location.
<?PHP
'<setting>' => 'page_bottom',
'<setting>' => 'body_top',
'<setting>' => 'navigation_top',
?>
One or more PHP callback function names to invoke.
This type accepts either:
a single string (one function name), or
an array of strings (multiple function names).
Each entry must be the name of a function that is callable at runtime. The implementation typically checks function_exists before calling the function. Non-existing function names are ignored.
If the corresponding setting is not configured (or is configured as NULL), no callbacks are invoked.
<?PHP
'<setting>' => 'myCallback',
'<setting>' => array(
'myCallback',
'myOtherCallback',
),
'<setting>' => NULL,
?>
One or more PHP file paths to load with require_once.
This type accepts either:
a single string (one file path), or
an array of strings (multiple file paths).
Each entry should be a PHP file path that can be passed to require_once. Paths may be absolute or relative, depending on how your site and addons are deployed.
If the corresponding setting is not configured (or is configured as NULL), no files are loaded.
<?PHP
'<setting>' => 'addons/example-addon.php',
'<setting>' => array(
'addons/example-addon.php',
'addons/second-addon.php',
),
'<setting>' => NULL,
?>
Site-local resource path that is used as a URL (for example in href or src) and that should also exist as a readable file on disk.
This type is used for resources that are served from the website itself (not external URLs). The value is typically passed through helper functions that generate the final URL (for example to apply base paths and resource rewriting/timestamping).
The value should be a path relative to the site root (for example images/favicon.png
). Do not include a scheme or domain; it is not a URL but a local file path for URL generation.
<?PHP
'<setting>' => 'images/favicon.png',
'<setting>' => 'style/layout.css',
'<setting>' => NULL,
?>
Script configuration specification.
This type accepts multiple input forms in site configuration. The settings compiler normalizes all supported forms into a single runtime shape: a list of script entries, where each entry is a keyed pair with:
script (resource path)
type (MIME type, default text/javascript
)
Supported input forms:
Single string:
The value is interpreted as a script resource path. The MIME type defaults to text/javascript
.
Array of strings:
Each item is interpreted as a script resource path. Each entry gets MIME type text/javascript
.
Single keyed pair:
A single entry with keys script and optionally type.
Array of keyed pairs:
A list of entries, each entry having script and optionally type.
Normalized runtime shape:
After compilation, the value is always a list of keyed pairs:
array(
array('script' => '...', 'type' => '...'),
array('script' => '...', 'type' => '...'),
...
)
<?PHP
'<setting>' => 'js/site.js',
'<setting>' => array(
'js/site.js',
'js/extra.js',
),
'<setting>' => array(
'script' => 'js/site.js',
'type' => 'text/javascript',
),
'<setting>' => array(
array(
'script' => 'js/site.js',
'type' => 'text/javascript',
),
array(
'script' => 'js/extra.js',
'type' => 'text/javascript',
),
),
?>
Date/time format specification string.
Use this type for settings that control how Nocterra renders dates and times via format_sdatetime, including:
languages<language>.time_s, time_m, time_l
languages<language>.date_s, date_m, date_l
and any other setting or output path that formats a date/time using the same formatter.
This format is a string containing tokens. At render time Nocterra replaces the tokens with localized values.
Two token styles are commonly used in Nocterra installations:
Nocterra token style (recommended):
Time:
%hour% Hour (00–23)
%minute% Minute (00–59)
%minutes% Alias of %minute% (legacy)
%second% Second (00–59)
%seconds% Alias of %second% (legacy)
Date:
%year% Year (4 digits)
%month% Month (1–12)
%month0% Month (01–12)
%date% Day of month (1–31)
%date0% Day of month (01–31)
%Month_abbr% Month name abbreviated (language/locale dependent)
%Month_name% Month name full (language/locale dependent)
%date_ord% Ordinal day string (language/locale dependent)
strftime-style tokens (legacy compatibility):
Time:
%H Hour (00–23)
%M Minute (00–59)
%S Second (00–59)
%I Hour (01–12)
%p AM/PM
Date:
%Y Year (4 digits)
%m Month (01–12)
%d Day of month (01–31)
%e Day of month (1–31, space padded in some formats)
%b Month name abbreviated (locale dependent)
%B Month name full (locale dependent)
Guideline:
Pick one style per site and keep it consistent. Prefer the Nocterra token style for new configurations, and keep strftime-style formats only when matching an existing installation.
<?PHP
'<setting>' => '%hour%:%minute%',
'<setting>' => '%hour%:%minute%:%seconds%',
'<setting>' => '%year%/%month0%/%date0%',
'<setting>' => '%Month_name% %date_ord%, %year%',
'<setting>' => '%H:%M',
'<setting>' => '%d-%m-%Y',
?>
Scalar string value.
This type is used for settings that accept plain text. The value is written as a quoted PHP string in the configuration (for example in site.php).
Notes:
Prefer single quotes in configuration ('...'). Use \' to include a literal single quote.
An empty string ('') is a valid value and is not the same as “not configured” (unset). Whether an empty string has a special meaning depends on the specific setting.
<?PHP
'<setting>' => 'Example',
'<setting>' => '',
?>
Style sheet configuration specification.
This type accepts multiple input forms in site configuration. The settings compiler normalizes all supported forms into a single runtime shape: a list of style sheet entries, where each entry is a keyed pair with:
stylesheet (resource path)
type (MIME type, default text/css
)
Supported input forms:
Single string:
The value is interpreted as a style sheet resource path. The MIME type defaults to text/css
.
Array of strings:
Each item is interpreted as a style sheet resource path. Each entry gets MIME type text/css
.
Single keyed pair:
A single entry with keys stylesheet and optionally type.
Array of keyed pairs:
A list of entries, each entry having stylesheet and optionally type.
Normalized runtime shape:
After compilation, the value is always a list of keyed pairs:
array(
array('stylesheet' => '...', 'type' => '...'),
array('stylesheet' => '...', 'type' => '...'),
...
)
This normalized list is used by the renderer to emit one <LINK rel="stylesheet" ...> per entry.
<?PHP
'<setting>' => 'style/layout.css',
'<setting>' => array(
'style/layout.css',
'style/print.css',
),
'<setting>' => array(
'stylesheet' => 'style/layout.css',
'type' => 'text/css',
),
'<setting>' => array(
array(
'stylesheet' => 'style/layout.css',
'type' => 'text/css',
),
array(
'stylesheet' => 'style/print.css',
'type' => 'text/css',
),
),
?>
Timestamping configuration specification.
This type controls which resource paths are excluded from Nocterra’s resource timestamping (the automatic _v...
suffix derived from file modification time).
Supported input forms:
Single string:
The value is treated as a single excluded path prefix.
Keyed pair:
An array with key excludePaths, where the value is either a single string or an array of strings.
Path prefixes are compared against resource filenames such as images/foo.png
. Use prefixes without a leading slash (for example images
, downloads
, vendor
).
Normalized runtime shape:
After compilation, excludePaths becomes either:
a compiled regular expression string that matches the configured prefixes, or
NULL when no exclusions are configured.
<?PHP
'<setting>' => 'images',
'<setting>' => array(
'images',
'downloads',
),
'<setting>' => array(
'excludePaths' => 'images',
),
'<setting>' => array(
'excludePaths' => array(
'images',
'downloads',
),
),
'<setting>' => array(
'excludePaths' => array(),
),
?>
Absolute URL path on the current host.
This type represents a path component of a URL (the part after the host), used by Nocterra to match requests or to generate links.
Rules:
Must start with /
.
Must not include a scheme, host, query string, or fragment.
For paths other than a domains base, use only URL-path-safe characters (letters, digits, /
, -
, _
, .
), matching the characters Nocterra keeps when parsing request paths.
Some settings require a trailing /
(for example when the value is used as a prefix). If a trailing slash matters, the setting documentation will explicitly say so.
<?PHP
'<setting>' => '/',
'<setting>' => '/downloads/',
'<setting>' => '/blog/category/news/',
?>
Viewport value for the HTML head meta tag.
This type represents the value written into the content attribute of:
<META name="viewport" content="...">
Typical values are comma-separated key/value pairs such as width=device-width and initial-scale=1.
<?PHP
'<setting>' => 'width=device-width, initial-scale=1',
'<setting>' => NULL,
?>
$branding = array(
'<language>' => array(
'author' => UNSET,
'contentType' => UNSET,
'copyright' => UNSET,
'description' => UNSET,
'favicon' => UNSET,
'keywords' => UNSET,
'logoImage' => UNSET,
'logoLink' => UNSET,
'logoText' => UNSET,
'siteImage' => UNSET,
'stylesheet' => UNSET,
'subtitle' => UNSET,
'title' => UNSET,
),
);
Per-language branding and site identity configuration.
This section contains the branding values used by the page renderer for the active language, such as the site title/subtitle, favicon/logo assets, default meta values, and stylesheet configuration.
Typical configuration structure:
$branding = array(
'en' => array(
...
),
'fr' => array(
...
),
);
Notes:
The renderer uses the current language’s branding entry as the baseline for header output (<TITLE>, meta tags, favicon/logo, and stylesheets).
Default meta values (author/description/title/keywords) are combined and scoped through the corresponding environment settings (for example whether local values are used, prepended, or extended).
Stylesheet configuration is expected to be available as a list at render time. Site configuration may start with a simpler form, but the compiled runtime structure should support iterating over one or more stylesheet entries.
string | NULL $author = UNSETConfigures the global author value for the current branding language.
This value is used as the global author meta value and participates in the local/global meta selection logic controlled by environment.author. Depending on that setting, the renderer may use:
only the global author,
only the local author,
or a combination (prepend/extend) using the configured separator.
If the value is not configured or is NULL, the global author value is considered empty.
<?PHP
$branding = array(
'<language>' => array(
'author' => 'Example',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'author' => '',
),
);
?>
content_type_eum | NULL $contentType = UNSETConfigures the default structured content type for pages under the current branding language.
This value is used to influence the Open Graph type selection and the RDFa typeof value emitted for certain elements. When not configured, the renderer may fall back to the current resource type determined for the requested path.
Behavior summary:
If this setting is NULL (or not configured), the renderer uses the requested resource type when available, and otherwise behaves as a generic website/page.
If this setting equals BlogPosting
or contains Article
, the Open Graph namespace is treated as article
.
Otherwise, the Open Graph namespace is treated as website
.
If the setting is not configured or is NULL, the content type is considered unspecified.
<?PHP
$branding = array(
'<language>' => array(
'contentType' => 'WebPage',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'contentType' => 'BlogPosting',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'contentType' => 'NewsArticle',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'contentType' => NULL,
),
);
?>
html_inline | NULL $copyright = UNSETConfigures the copyright line for the current branding language.
When non-empty, this value is emitted in the page footer as the copyright text. The value may contain HTML markup (it is output directly by the renderer), so it should be trusted content.
If the value is not configured or is NULL, the copyright line is considered empty and is not emitted.
<?PHP
$branding = array(
'<language>' => array(
'copyright' => 'Welcome',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'copyright' => 'You are here: <SPAN class="hint">Home</SPAN>',
),
);
?>
string | NULL $description = UNSETConfigures the global description value for the current branding language.
This value is used as the global description meta value and participates in the local/global meta selection logic controlled by environment.description. Depending on that setting, the renderer may use:
only the global description,
only the local description,
or a combination (prepend/extend) using the configured separator.
If the value is not configured or is NULL, the global description value is considered empty.
<?PHP
$branding = array(
'<language>' => array(
'description' => 'Example',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'description' => '',
),
);
?>
resource_path | NULL $favicon = UNSETConfigures the favicon resource for the current branding language.
When this setting is configured, the page header generation attempts to emit a favicon link tag in the HTML head:
<LINK rel="icon" href="..." type="...">
The value is treated as a site-local resource path. It is used:
as a file path (to detect the image type on disk), and
as a URL (emitted in the href attribute via the resource link generator).
If the value is not configured (or is NULL), no favicon link tag is emitted.
If the resource file does not exist or the image type cannot be detected, the favicon link tag is not emitted.
<?PHP
$branding = array(
'<language>' => array(
'favicon' => 'images/favicon.png',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'favicon' => 'style/layout.css',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'favicon' => NULL,
),
);
?>
string | NULL $keywords = UNSETConfigures the global keywords value for the current branding language.
This value is used as the global keywords meta value and participates in the local/global meta selection logic controlled by environment.keywords.
Unlike other meta values, keywords are typically merged as a list. Depending on environment.keywords, the renderer may:
use only the global keywords,
use only the local keywords,
or combine them (prepend/extend) using the keyword merge logic.
If the value is not configured or is NULL, the global keywords value is considered empty.
<?PHP
$branding = array(
'<language>' => array(
'keywords' => 'Example',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'keywords' => '',
),
);
?>
resource_path | NULL $logoImage = UNSETConfigures the logo image resource for the current branding language.
When configured, the logo image is emitted in the header. The value is treated as a site-local resource path and is passed to the image rendering logic, which may apply site-specific URL generation and resource rewriting (for example timestamping).
If the value is not configured (or is NULL), no logo image is emitted.
Link behavior:
Whether the logo image is wrapped in a link is controlled by branding<language>.logoLink. In the current implementation, the presence of the logoLink key enables linking the logo to the site root (/). The configured value of logoLink is not used as a URL.
<?PHP
$branding = array(
'<language>' => array(
'logoImage' => 'images/favicon.png',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'logoImage' => 'style/layout.css',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'logoImage' => NULL,
),
);
?>
string | NULL $logoLink = UNSETControls whether the logo image is emitted as a link.
In the current implementation, the presence of the branding<language>.logoLink setting enables linking the logo to the site root (/). The configured value is not used as a URL; the setting acts as an on/off flag.
To disable the logo link, omit this setting (or set it to NULL).
<?PHP
$branding = array(
'<language>' => array(
'logoLink' => 'Example',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'logoLink' => '',
),
);
?>
string | NULL $logoText = UNSETConfigures the alternative text for the logo image for the current branding language.
When branding<language>.logoImage is configured, this value is passed as the image alternative text (alt text). It is also the primary textual fallback/description for the logo image.
If the value is not configured or is NULL, the logo alt text is considered empty.
<?PHP
$branding = array(
'<language>' => array(
'logoText' => 'Example',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'logoText' => '',
),
);
?>
resource_path | NULL $siteImage = UNSETConfigures the site image resource used for social meta output.
When configured, this image is emitted as the Open Graph image and Twitter image in the document head, for example:
<META property="og:image" content="...">
<META name="twitter:image" content="...">
The value is treated as a site-local resource path and is emitted as a URL via the resource link generator.
If the value is not configured (or is NULL), these image meta tags are omitted.
<?PHP
$branding = array(
'<language>' => array(
'siteImage' => 'images/favicon.png',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'siteImage' => 'style/layout.css',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'siteImage' => NULL,
),
);
?>
style_sheet_spec $stylesheet = UNSETConfigures one or more stylesheets for the current branding language.
This setting accepts multiple input forms (see the style_sheet_spec
type). During compilation, all supported forms are normalized into a list of stylesheet entries. Each entry has:
stylesheet (resource path)
type (MIME type, default text/css
)
During page rendering, a stylesheet link tag is emitted for each normalized entry:
<LINK rel="stylesheet" href="..." type="..." charset="UTF-8">
If this setting is not configured, it is treated as an empty list and no stylesheet link tags are emitted.
<?PHP
$branding = array(
'<language>' => array(
'stylesheet' => 'style/layout.css',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'stylesheet' => array(
'style/layout.css',
'style/print.css',
),
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'stylesheet' => array(
'stylesheet' => 'style/layout.css',
'type' => 'text/css',
),
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'stylesheet' => array(
array(
'stylesheet' => 'style/layout.css',
'type' => 'text/css',
),
array(
'stylesheet' => 'style/print.css',
'type' => 'text/css',
),
),
),
);
?>
html_inline | NULL $subtitle = UNSETConfigures the site subtitle for the current branding language.
The subtitle is displayed in the page header (for example as <H2>...</H2>) when it is non-empty. It is a visual/site-identity element and is not part of the meta title selection logic.
If the value is not configured or is NULL, the subtitle is considered empty and the subtitle element is not emitted.
<?PHP
$branding = array(
'<language>' => array(
'subtitle' => 'Welcome',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'subtitle' => 'You are here: <SPAN class="hint">Home</SPAN>',
),
);
?>
html_inline | NULL $title = UNSETConfigures the site title for the current branding language.
The title is used as the primary site title displayed in the page header (for example as <H1>...</H1>), and it is also used as the global title value for meta generation.
Meta behavior:
The value participates in the local/global title selection logic controlled by environment.title. Depending on that setting, the renderer may use:
only the global title,
only the local title,
or a combination (prepend/extend) using the configured separator.
If the value is not configured or is NULL, the title is considered empty and the header title block may be omitted.
<?PHP
$branding = array(
'<language>' => array(
'title' => 'Welcome',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'title' => 'You are here: <SPAN class="hint">Home</SPAN>',
),
);
?>
$domains = array(
'<domain>' MANDATORY => array(
'base' => UNSET MANDATORY,
'cookieDomain' => UNSET,
'defaultLanguage' => UNSET,
'host' => UNSET,
'languages' => UNSET,
'priority' => UNSET,
),
);
Domain configuration.
The domains section defines which hosts Nocterra serves, what URL base path is used on each host, and which languages are served on each host.
Each entry is keyed by a domain match string. At request time Nocterra selects the first domain entry for which:$_SERVER['HTTP_HOST'] ends with the configured key.
Because this is a suffix match, overlapping keys are possible (for example example.com
and account.example.com
). If multiple keys match, the first matching entry in domains wins.
The selected domain’s base is used as the path prefix for all requests on that host. If the request path does not start with what is set in domains<domain>.base, the request fails.
The languages setting supports two modes:
Single-language mode (domains<domain>.languages is a string): the site does not use a language prefix in the URL on that host.
Multi-language mode (domains<domain>.languages is an array): the first path component may be a language code (/en/...
, /nl/...
).
If no language is present in the URL and the domain serves multiple languages, Nocterra can select a language using the browser’s Accept-Language, otherwise it falls back to the domain’s defaultLanguage.
Note:
The language and domain compiler derives additional per-language base URLs (such as baseLang) used internally for link generation and dynamic placeholders. Those derived fields are not configured manually.
Example 1 (single-language host):
This configuration serves one language on one host. Because domains<domain>.languages is a string, Nocterra does not expect a language prefix in the URL on this host. Every request is handled as that single language.
$domains = array(
'example.com' => array(
'base' => '/',
'languages' => 'nl',
'host' => 'www.example.com',
),
);
Example 2 (multi-language host):
This configuration serves multiple languages on one host. Because domains<domain>.languages is an array, the first path component may be a language key (for example /en/...
or /nl/...
). If no language prefix is present, Nocterra can select a language from the browser’s Accept-Language header, and otherwise falls back to domains<domain>.defaultLanguage.
$domains = array(
'example.com' => array(
'base' => '/',
'languages' => array('nl', 'en'),
'defaultLanguage' => 'en',
'host' => 'www.example.com',
),
);
Example 3 (one domain per language):
Use this pattern when you want clean URLs without a language prefix, but still serve multiple languages by splitting them across hosts (for example one host for German and one host for English).
$domains = array(
'example.de' => array(
'base' => '/',
'languages' => 'de',
'host' => 'www.example.de',
),
'example.com' => array(
'base' => '/',
'languages' => 'en',
'host' => 'www.example.com',
),
);
If you prefer subdomains instead of TLDs, this is the same pattern with keys like nl.example.com
and en.example.com
.
$domains = array(
'de.example.com' => array(
'base' => '/',
'languages' => 'de',
'host' => 'de.example.com'
),
'example.com' => array(
'base' => '/',
'languages' => 'en',
'host' => 'en.example.com'
),
);
Example 4 (production + test/staging domains):
Use this pattern when you run the same site configuration on multiple hosts (for example a live domain and a staging domain). Each domain entry can still choose its own base, language mode, and cookie domain.
Configured this way, you can deploy the same site tree to both production and test without editing site.php. For example, you can upload the full site (including site.php) to the live host using an rsync script or an SFTP client.
$domains = array(
'example.com' => array(
'base' => '/',
'languages' => array('en', 'nl'),
'defaultLanguage' => 'en',
'host' => 'www.example.com',
'cookieDomain' => '.example.com',
),
'staging.example.com' => array(
'base' => '/',
'languages' => array('en', 'nl'),
'defaultLanguage' => 'en',
'host' => 'staging.example.com',
'cookieDomain' => '.example.com',
),
);$domains = array(
'example.com' => array(
'base' => '/',
'languages' => array('en', 'nl'),
'defaultLanguage' => 'en',
'host' => 'www.example.com',
),
'localhost' => array(
'base' => '/',
'languages' => array('en', 'nl'),
'defaultLanguage' => 'en',
'host' => 'localhost',
),
);
Example 5 (split URL space over multiple domains):
This example turns /account/... into a different browser origin by moving it to account.<domain>. That creates a hard security boundary: cookies, localStorage, ServiceWorkers, and many browser security policies are not shared with www.<domain>. In practice, that reduces the blast radius of mistakes or content-level issues on the public site (e.g., an XSS in a page/article on www can’t automatically read cookies or storage scoped to account).
Note:
If you also configure a more generic overlapping domain key (for example example.com
next to account.example.com
), ensure the more specific key appears first in $domains, because domain selection uses a suffix match and the first match wins.
site.php:
$domains = array(
'account.example.com' => array(
'base' => '/',
'languages' => array('en', 'fr'),
'host' => 'account.example.com'
),
'example.com' => array(
'base' => '/',
'languages' => array('en', 'fr'),
'host' => 'www.example.com',
),
);
.htaccess:
<IfModule mod_rewrite.c>
RewriteEngine on
# Redirect /account on the main host to the account host
RewriteCond %{REQUEST_URI} ^/(en/|fr/)?account(/.)?$
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteRule . https://account.example.com%{REQUEST_URI} [R=301,END]
# Redirect non-/account paths on the account host back to the main host
RewriteCond %{HTTP_HOST} ^account.example.com$
RewriteRule !^(en/|fr/)?account(/.*)? https://www.example.com%{REQUEST_URI} [R=301,END]
# Force HTTPS on the account host
RewriteCond %{HTTP_HOST} ^account.example.com$
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,END]
</IfModule>
Use the pattern below when the public site is split over multiple language-specific domains (for example www.example.nl
and www.example.org
), but the authenticated area must keep one login session while the user switches languages.
Because browsers scope cookies to a host (and you cannot share cookies across different domains such as example.nl
and example.org
), a login cookie set on one public domain cannot be reused on the other. Trying to “share” it typically means third-party cookies or passing a session id in the URL, both of which are unreliable or undesirable.
By placing the authenticated area on a single host (for example account.example.com
) and serving multiple languages there (URL language prefix mode), the session cookie remains a first-party cookie on that host. Users can switch languages within the account area without losing their session, and no session id needs to be copied through redirects or query strings.
site.php:
$domains = array(
// Authenticated area (one host, multiple languages)
'account.example.com' => array(
'base' => '/',
'languages' => array('fr', 'en'),
'defaultLanguage' => 'en',
'host' => 'account.example.com',
'cookieDomain' => 'account.example.com',
),
// Public site (single-language per host)
'example.fr' => array(
'base' => '/',
'languages' => 'fr',
'host' => 'www.example.fr',
'cookieDomain' => 'www.example.fr',
),
'example.com' => array(
'base' => '/',
'languages' => 'en',
'host' => 'www.example.com',
'cookieDomain' => '.example.com',
),
);
.htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
# French public domain -> account host, force /fr/ prefix in account area
RewriteCond %{HTTP_HOST} ^(www\.)?example\.fr$ [NC]
RewriteRule ^account(?:/(.*))?$ https://account.example.com/fr/account/$1 [R=301,L]
# English public domain -> account host, force /en/ prefix in account area
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$ [NC]
RewriteRule ^account(?:/(.*))?$ https://account.example.com/en/account/$1 [R=301,L]
# Force HTTPS on the account host (only)
RewriteCond %{HTTP_HOST} ^account\.example\.com$ [NC]
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Anything on account host that is NOT under /fr/account
# is redirected back to the corresponding public domain.
RewriteCond %{HTTP_HOST} ^account\.example\.com$ [NC]
RewriteRule ^fr/(?!account(?:/|$))(.*)$ https://www.example.fr/$1 [R=301,L]
# Anything on account host that is NOT under /en/account
# is redirected back to the corresponding public domain.
RewriteCond %{HTTP_HOST} ^account\.example\.com$ [NC]
RewriteRule ^en/(?!account(?:/|$))(.*)$ https://www.example.com/$1 [R=301,L]
# Optional: if a request lands on the account host without a language prefix,
# send it to the default public domain (pick the one you want).
RewriteCond %{HTTP_HOST} ^account\.example\.com$ [NC]
RewriteRule !^(fr|en)/account(?:/|$) https://www.example.com%{REQUEST_URI} [R=301,L]
</IfModule>
url_path $base = UNSET MANDATORYRequired. The base path prefix for the site on this host.
Nocterra strips this prefix from the request path before resolving the menu path. If the request path does not start with base, the request fails.
Use /
when the site is served from the web root.
<?PHP
$domains = array(
'<domain>' => array(
'base' => '/',
),
);
?>
<?PHP
$domains = array(
'<domain>' => array(
'base' => '/downloads/',
),
);
?>
<?PHP
$domains = array(
'<domain>' => array(
'base' => '/blog/category/news/',
),
);
?>
host_name $cookieDomain = UNSETCookie domain used by the site.
If not configured, Nocterra defaults this value to domains<domain>.host.
Use a leading dot when you intentionally want cookies to be shared across subdomains, for example .example.com
.
<?PHP
$domains = array(
'<domain>' => array(
'cookieDomain' => 'www.example.com',
),
);
?>
<?PHP
$domains = array(
'<domain>' => array(
'cookieDomain' => 'account.example.com',
),
);
?>
<?PHP
$domains = array(
'<domain>' => array(
'cookieDomain' => '.example.com',
),
);
?>
language $defaultLanguage = UNSETDefault language for this host.
If not configured, the compiler assigns a default:
For multi-language domains: the first entry in domains<domain>.languages.
For single-language domains: the configured language.
This default is used when the URL does not specify a language and no browser language is selected.
<?PHP
$domains = array(
'<domain>' => array(
'defaultLanguage' => 'en',
),
);
?>
<?PHP
$domains = array(
'<domain>' => array(
'defaultLanguage' => 'nl',
),
);
?>
host_name $host = UNSETRequired. The canonical host name for this domain entry.
This value is used by the compiler to derive base URLs for link generation and placeholders.
<?PHP
$domains = array(
'<domain>' => array(
'host' => 'www.example.com',
),
);
?>
<?PHP
$domains = array(
'<domain>' => array(
'host' => 'account.example.com',
),
);
?>
<?PHP
$domains = array(
'<domain>' => array(
'host' => '.example.com',
),
);
?>
language_spec $languages = UNSETDefines which languages are served on this domain.
Use a single language key for a single-language domain, or a list of language keys for a multi-language domain.
Language keys must match configured entries in languages<language>.
In most installations these keys are ISO 639-1 two-letter codes in lowercase (for example en, nl).
If this value is an array (multi-language mode), Nocterra may accept a language prefix as the first URL path component (/en/...
, /nl/...
) and may select a language using the browser’s Accept-Language when no prefix is present.
The fallback language is controlled by domains<domain>.defaultLanguage.
<?PHP
$domains = array(
'<domain>' => array(
'languages' => 'en',
),
);
?>
<?PHP
$domains = array(
'<domain>' => array(
'languages' => array('nl', 'en'),
),
);
?>
integer $priority = UNSETOptional priority value used when resolving languages and domains.
This value influences derived localization paths between domains when a language is not explicitly served on a specific domain. It is also used when selecting a default domain candidate in fallback logic.
Lower numbers represent higher priority.
<?PHP
$domains = array(
'<domain>' => array(
'priority' => 7,
),
);
?>
<?PHP
$domains = array(
'<domain>' => array(
'priority' => NULL,
),
);
?>
$environment MANDATORY = array(
'authorSeparator' => ', ',
'author' => 'extend',
'canonicalLanguage' => UNSET,
'data_storeLevels' => 1,
'data_store' => UNSET MANDATORY,
'descriptionSeparator' => ', ',
'description' => 'local',
'dynamicMaxAge' => UNSET MANDATORY,
'generateDynamic' => NULL,
'generateStatic' => NULL,
'keywordsSeparator' => ', ',
'keywords' => 'extend',
'loadAddons' => NULL,
'rdfa' => FALSE,
'redirectMaxAge' => UNSET MANDATORY,
'responseMaxAge' => UNSET MANDATORY,
'sitemapCacheMaxAge' => 24*60*60,
'titleSeparator' => ' | ',
'title' => 'prepend',
'viewport' => UNSET,
);
Settings in this section belong to the runtime environment configuration.
string $authorSeparator = ', 'Separator used when Nocterra concatenates local and site-wide author metadata.
This setting is only used when environment.author is configured as prepend or extend and both values are present and different.
Default:
If not configured (or configured as an empty value), the implementation uses a default separator.
<?PHP
$environment = array(
'authorSeparator' => 'Example',
);
?>
<?PHP
$environment = array(
'authorSeparator' => '',
);
?>
meta_scope_enum $author = 'extend'Determines how the final author metadata is assembled for the HTML output.
This setting does not define the author text itself. It controls how Nocterra combines:
the site-wide author value (configured under the branding settings), and
a page-local author value (provided by the current page/article metadata or by page-level API calls).
Allowed values:
local
Use the local author when it is present (non-empty). If no local author is provided, fall back to the site-wide author.
prepend
When both local and site-wide author are present and different: output local + separator + site-wide. Otherwise output the site-wide author.
extend
When both local and site-wide author are present and different: output site-wide + separator + local. Otherwise output the site-wide author.
Separator:
When concatenating, the separator is taken from environment.authorSeparator. If no separator is configured (or it is empty), a default separator is used by the implementation.
Default:
If not configured (or configured as an empty value), Nocterra sets this setting to 'extend'.
<?PHP
$environment = array(
'author' => 'extend',
);
?>
<?PHP
$environment = array(
'author' => 'prepend',
);
?>
<?PHP
$environment = array(
'author' => 'local',
);
?>
language | NULL $canonicalLanguage = UNSETSelect the canonical language used when generating certain canonical-style URLs.
When configured, Nocterra uses this language key as the canonical language for URL generation in contexts where a single “canonical language URL” is needed (for example for social metadata).
Default:
If this setting is not configured (omitted), Nocterra uses the active language of the current request.
Notes:
The value must be a configured language key from $languages (for example <CODE
<?PHP
$environment = array(
'canonicalLanguage' => 'en',
);
?>
<?PHP
$environment = array(
'canonicalLanguage' => 'nl',
);
?>
integer $data_storeLevels = 1Controls how the requested URL path is mapped to directories and filenames under /data.
This setting determines how many path components are treated as directory levels before the remaining components are combined into a filename. The exact result depends on the selected environment.data_store mode, but the goal is always the same: make the /data tree match the scale and structure of your site.
Default:
If this setting is not configured, or if a value lower than 1 is used, Nocterra uses 1.
Examples (illustrative mappings)
data_store = 'locale_prefix'
With a flat site you typically keep data_storeLevels at 1. Increasing it introduces directories for the first components of the path.
Example URL: /support/docs/api
data_storeLevels = 1
/data/en_support_docs_api
data_storeLevels = 2
/data/en_support/docs_api
data_storeLevels = 3
/data/en_support/docs/apidata_store = 'locale_directory'
This mode always starts with a per-language directory. Increasing data_storeLevels introduces additional directories for the first components of the path.
Example URL: /support/docs/api
data_storeLevels = 1
/data/en/support_docs_api
data_storeLevels = 2
/data/en/support/docs_api
data_storeLevels = 3
/data/en/support/docs/apidata_store = 'locale_prefix_menu'
This mode uses directories for structural sections and uses language-prefixed filenames inside those directories. Increasing data_storeLevels increases how deep the directories go before the remainder is combined into the filename.
Example URL: /account/profile/address-edit
data_storeLevels = 2
/data/account/en_profile_address-edit
data_storeLevels = 3
/data/account/profile/en_address-editNotes:
For small sites, 1 is often sufficient.
For medium sites, 2 or 3 typically offers a good balance between a readable directory structure and manageable filenames.
For larger sites with many sections and translations, higher values can keep related pages grouped together and reduce very long filenames.
<?PHP
$environment = array(
'data_storeLevels' => 7,
);
?>
<?PHP
$environment = array(
'data_storeLevels' => NULL,
);
?>
data_store_enum $data_store = UNSET MANDATORYSelects the data store mapping mode used to locate page data files under /data.
Nocterra resolves each request by converting the requested URL path (and the active language) into a filename under /data, and then loading that file. The files in /data are authored site pages and may contain HTML output and/or PHP that generates dynamic output (for example forms, indexes, or syndicated content).
Allowed values:
locale_prefix
A simple, mostly flat layout where the language key is prefixed in the filename.
Best for small sites (few pages, one or two languages) where you prefer a straightforward /data tree.
locale_directory
A layout where pages are stored under a directory per language (for example /data/en/...).
Best when you prefer strict separation per language and want language trees to be easy to browse.
locale_prefix_menu
A layout that uses directories for structural sections and uses language-prefixed filenames inside those directories.
Best for larger sites, because it keeps translations and related pages close together while allowing sections to be grouped into directories.
Examples (illustrative mappings and directory layouts):
Flat layout (locale_prefix)
Typical URLs:
/
/about
/contact
Example /data tree:
/data/
en_
nl_
en_about
nl_over
en_contact
nl_contact
en_404
nl_404Per-language directories (locale_directory)
Typical URLs:
/
/about
/contact
Example /data tree:
/data/
en/
_
about
contact
404
nl/
_
over
contact
404Section directories with language-prefixed filenames (locale_prefix_menu)
This layout scales well for sites with many pages and multiple languages. Related pages and translations live next to each other in the same directory.
Typical URLs:
/
/account/
/account/login
/account/invoices
/account/profile/
/account/profile/address-edit
Example /data tree:
/data/
en_
nl_
en_404
nl_404
en_contact
nl_contact
account/
en_
nl_
en_login
nl_aanmelden
en_invoices
nl_facturen
profile/
en_
nl_
en_address-edit
nl_adres-bewerken
Notes:
Choose a mode that matches how you want to organize the /data tree for your site size and language count.
environment.data_storeLevels influences when path components become directories versus being combined into filenames.
Changing this setting changes which file paths Nocterra will attempt to load. Adjust the /data tree accordingly.
Required:
This setting must be configured. If it is missing or empty, Nocterra aborts with a fatal configuration error.
<?PHP
$environment = array(
'data_store' => 'locale_prefix',
);
?>
<?PHP
$environment = array(
'data_store' => 'locale_directory',
);
?>
<?PHP
$environment = array(
'data_store' => 'locale_prefix_menu',
);
?>
string $descriptionSeparator = ', 'Separator used when Nocterra concatenates local and site-wide description metadata.
This setting is only used when environment.description is configured as prepend or extend and both values are present and different.
Default:
If not configured (or configured as an empty value), the implementation uses a default separator.
<?PHP
$environment = array(
'descriptionSeparator' => 'Example',
);
?>
<?PHP
$environment = array(
'descriptionSeparator' => '',
);
?>
meta_scope_enum $description = 'local'Determines how the final description metadata is assembled for the HTML output.
This setting does not define the description text itself. It controls how Nocterra combines:
the site-wide description value (configured under the branding settings), and
a page-local description value (provided by the current page/article metadata or by page-level API calls).
Allowed values:
local
Use the local description when it is present (non-empty). If no local description is provided, fall back to the site-wide description.
prepend
When both local and site-wide description are present and different: output local + separator + site-wide. Otherwise output the site-wide description.
extend
When both local and site-wide description are present and different: output site-wide + separator + local. Otherwise output the site-wide description.
Separator:
When concatenating, the separator is taken from environment.descriptionSeparator. If no separator is configured (or it is empty), a default separator is used by the implementation.
Default:
If not configured (or configured as an empty value), Nocterra sets this setting to 'local'.
<?PHP
$environment = array(
'description' => 'extend',
);
?>
<?PHP
$environment = array(
'description' => 'prepend',
);
?>
<?PHP
$environment = array(
'description' => 'local',
);
?>
duration_seconds $dynamicMaxAge = UNSET MANDATORYControls the cache lifetime (in seconds) for responses that contain dynamic pair placeholders.
At the end of handling a request, Nocterra decides which Cache-Control headers to emit. If the generated output contains “dynamic pair” placeholders, Nocterra treats the response as partially dynamic and sends:
Cache-Control: max-age=...
In this case, the max-age value is taken from environment.dynamicMaxAge (instead of environment.responseMaxAge). This allows you to keep the overall page cacheable, while ensuring that pages with dynamic pair expansions are revalidated more frequently.
This setting applies to responses where:
The request is cacheable (not in “no-store/no-cache” mode due to dynamic generation callbacks, error handling, or explicit cache disabling), and
The output contains at least one dynamic pair placeholder (as detected by the dynamic pair scanner).
Notes:
Because Nocterra treats “empty” values as not configured, 0 is not a usable value here.
If the request is handled in a mode that forces no-store/no-cache, this setting is not used (no max-age is emitted in that path).
<?PHP
$environment = array(
'dynamicMaxAge' => 300,
);
?>
<?PHP
$environment = array(
'dynamicMaxAge' => 3600,
);
?>
<?PHP
$environment = array(
'dynamicMaxAge' => 86400,
);
?>
<?PHP
$environment = array(
'dynamicMaxAge' => 24*60*60,
);
?>
php_callbacks | NULL $generateDynamic = NULLRegisters one or more callbacks that provide per-request, site-wide dynamic behavior.
This hook is intended to set or prepare values for site-wide output that changes per request (or per time window), such as values used to expand dynamic pair placeholders. The placeholder itself can be emitted earlier (for example by templates or by generateStatic), while this hook provides the per-request values used for expansion.
Execution point:
These callbacks are executed during shutdown, after the main output has been generated and just before dynamic pair placeholders are expanded.
Important caching behavior:
If this setting is configured (i.e. it is set and not NULL), Nocterra treats the response as dynamic and emits:
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
This prevents browsers and intermediary caches from storing the response. Use this hook only when the resulting output must be request-specific.
Output guidance:
Because this hook runs after the page output is already produced, callbacks should not generate page HTML. Use this hook to prepare dynamic values (for example dynamic pair replacements) and other per-request state.
Accepted forms:
A single function name (string), or
A list of function names (array of strings).
Behavior notes:
If a list is configured, callbacks run in the configured order.
Only callbacks that exist (function_exists) are invoked; unknown names are ignored.
If the setting is not configured or is NULL, no callbacks are executed and the response may remain cacheable (subject to other cache rules).
<?PHP
$environment = array(
'generateDynamic' => 'myCallback',
);
?>
<?PHP
$environment = array(
'generateDynamic' => array(
'myCallback',
'myOtherCallback',
),
);
?>
<?PHP
$environment = array(
'generateDynamic' => NULL,
);
?>
php_callbacks | NULL $generateStatic = NULLRegisters one or more callbacks that generate site-wide output during request rendering.
When configured, Nocterra invokes the callback(s) while building the page layout. This hook is intended for site-wide output that is safe to include in the normal page output and can be stored in the cache.
Typical use cases:
Emitting site-wide markup that is the same for many pages (for example shared blocks inserted by an addon).
Emitting site-wide placeholders, including dynamic pair placeholders, where the placeholder itself is cacheable and only the replacement value may change later.
This hook is not intended for per-page content generation. Pages can generate their own output directly, and they can decide whether the page should be cacheable or not.
Accepted forms:
A single function name (string), or
A list of function names (array of strings).
Behavior notes:
If a list is configured, callbacks run in the configured order.
Only callbacks that exist (function_exists) are invoked; unknown names are ignored.
If the setting is not configured or is NULL, no callbacks are executed.
<?PHP
$environment = array(
'generateStatic' => 'myCallback',
);
?>
<?PHP
$environment = array(
'generateStatic' => array(
'myCallback',
'myOtherCallback',
),
);
?>
<?PHP
$environment = array(
'generateStatic' => NULL,
);
?>
string $keywordsSeparator = ', 'Reserved separator setting for keywords concatenation.
Note:
In the current implementation, keywords are combined using keyword-specific merge logic (not simple separator concatenation). This means this separator is not used in the same way as authorSeparator, descriptionSeparator and titleSeparator.
Default:
If not configured (or configured as an empty value), the implementation behaves as if no custom separator was provided.
<?PHP
$environment = array(
'keywordsSeparator' => 'Example',
);
?>
<?PHP
$environment = array(
'keywordsSeparator' => '',
);
?>
meta_scope_enum $keywords = 'extend'Determines how the final keywords metadata is assembled for the HTML output.
This setting does not define the keywords themselves. It controls how Nocterra combines:
the site-wide keywords value (configured under the branding settings), and
a page-local keywords value (provided by the current page/article metadata or by page-level API calls).
Allowed values:
local
Use only the local keywords when present (non-empty). If no local keywords are provided, fall back to the site-wide keywords.
prepend
When both local and site-wide keywords are present: combine them with the local keywords first.
extend
When both local and site-wide keywords are present: combine them with the site-wide keywords first.
Note:
Keywords are combined using keyword-specific merge logic. This is intentionally different from the simple “separator concatenation” used by title, author and description.
Default:
If not configured (or configured as an empty value), Nocterra sets this setting to 'extend'.
<?PHP
$environment = array(
'keywords' => 'extend',
);
?>
<?PHP
$environment = array(
'keywords' => 'prepend',
);
?>
<?PHP
$environment = array(
'keywords' => 'local',
);
?>
php_files | NULL $loadAddons = NULLLoads additional PHP files (addons) before handling the request.
When this setting is configured, Nocterra loads each configured file using require_once. This happens early in the request handling flow, before page output is generated. Use this to register addon functions, overrides, or other integration code that must be available during request processing.
Accepted forms:
A single file path (string), or
A list of file paths (array of strings).
Behavior notes:
The configured order is preserved. If multiple addon files depend on each other, list them in the required load order.
If a configured file cannot be loaded, require_once will raise a PHP warning and typically results in a fatal error (depending on PHP configuration). Ensure paths are correct and files are deployable on all environments where the site runs.
If the setting is not configured or is NULL, no addon files are loaded.
<?PHP
$environment = array(
'loadAddons' => 'addons/example-addon.php',
);
?>
<?PHP
$environment = array(
'loadAddons' => array(
'addons/example-addon.php',
'addons/second-addon.php',
),
);
?>
<?PHP
$environment = array(
'loadAddons' => NULL,
);
?>
boolean $rdfa = FALSEEnable or disable RDFa output.
When enabled, Nocterra emits the HTML 4.01 + RDFa 1.1 doctype and includes RDFa attributes where applicable (for example in breadcrumbs output).
When disabled, Nocterra emits the regular HTML 4.01 Strict doctype and RDFa-specific attributes are not emitted.
Default:
If this setting is not configured (omitted), Nocterra behaves as if RDFa is disabled.
Notes:
This is a boolean switch. Use TRUE/FALSE or 1/0.
NULL is treated the same as “not configured”.
<?PHP
$environment = array(
'rdfa' => TRUE,
);
?>
<?PHP
$environment = array(
'rdfa' => FALSE,
);
?>
<?PHP
$environment = array(
'rdfa' => 1,
);
?>
<?PHP
$environment = array(
'rdfa' => 0,
);
?>
duration_seconds $redirectMaxAge = UNSET MANDATORYControls the cache lifetime (in seconds) for redirect responses generated by Nocterra.
When Nocterra performs a redirect (for example to enforce the canonical scheme/URL), it sends:
Location: ...
Cache-Control: max-age=...
The max-age value is taken from environment.redirectMaxAge. This influences how long user agents and intermediary caches may reuse the redirect response without revalidating. In practice, a higher value reduces repeat redirects for returning visitors and can reduce load, while a lower value makes redirect changes propagate more quickly.
This setting applies to:
External redirects generated by the request handler when the requested URL differs from the canonical URL (see the redirect logic that compares the current request URL with the reconstructed canonical URL).
Error responses cached through dieMessage(..., ..., TRUE) when the cache layer stores the response without dependencies; in that case the cache TTL falls back to redirectMaxAge.
Notes:
Redirect behavior for search engines is primarily determined by the HTTP status code (permanent vs temporary). The cache lifetime can still affect how often crawlers and clients need to re-fetch redirecting URLs, but it does not replace correct redirect status codes and canonical URL configuration.
Because Nocterra treats “empty” values as not configured, 0 is not a usable value here.
<?PHP
$environment = array(
'redirectMaxAge' => 300,
);
?>
<?PHP
$environment = array(
'redirectMaxAge' => 3600,
);
?>
<?PHP
$environment = array(
'redirectMaxAge' => 86400,
);
?>
<?PHP
$environment = array(
'redirectMaxAge' => 24*60*60,
);
?>
duration_seconds $responseMaxAge = UNSET MANDATORYControls the cache lifetime (in seconds) for normal (non-dynamic) responses.
At the end of handling a request, Nocterra decides which Cache-Control headers to emit. When the request is handled as a regular response (no dynamic generation, no error state, and no “never cache” mode), Nocterra sends:
Cache-Control: max-age=...
For regular responses, the max-age value is taken from environment.responseMaxAge. This influences how long browsers and intermediary caches may reuse the response without re-fetching it. Higher values reduce repeat requests and improve performance for returning visitors; lower values make changes become visible sooner without relying on cache invalidation.
This setting applies to responses where:
The request is not considered dynamic (no dynamic generation callbacks are active for the request).
The output does not trigger the “no-cache/no-store” path (for example due to errors or explicit cache disabling).
No “dynamic pair” placeholders are detected in the output; if dynamic pairs are present, environment.dynamicMaxAge is used instead.
Notes:
Because Nocterra treats “empty” values as not configured, 0 is not a usable value here.
Response caching behavior depends on multiple factors (request mode, dynamic generation, error handling). This setting only controls the max-age used for the cacheable, non-dynamic path.
<?PHP
$environment = array(
'responseMaxAge' => 300,
);
?>
<?PHP
$environment = array(
'responseMaxAge' => 3600,
);
?>
<?PHP
$environment = array(
'responseMaxAge' => 86400,
);
?>
<?PHP
$environment = array(
'responseMaxAge' => 24*60*60,
);
?>
duration_seconds $sitemapCacheMaxAge = 24*60*60Controls the cache lifetime (in seconds) for sitemap caching.
This setting is intended for sitemap generation and/or sitemap cache entries so that sitemap output does not need to be regenerated on every request. A higher value reduces regeneration frequency and load; a lower value makes sitemap changes become visible sooner when the sitemap is fetched again.
Default:
If this setting is missing or “empty”, Nocterra sets it to: 24*60*60.
Notes:
Nocterra uses empty(...) when applying the default. This means values such as NULL, 0, '0' and '' are treated as empty and will result in the default being applied.
This setting applies to sitemap-related requests/outputs handled by the sitemap generation and caching logic. It does not affect normal page responses (responseMaxAge) or redirects (redirectMaxAge).
<?PHP
$environment = array(
'sitemapCacheMaxAge' => 300,
);
?>
<?PHP
$environment = array(
'sitemapCacheMaxAge' => 3600,
);
?>
<?PHP
$environment = array(
'sitemapCacheMaxAge' => 86400,
);
?>
<?PHP
$environment = array(
'sitemapCacheMaxAge' => 24*60*60,
);
?>
string $titleSeparator = ' | 'Separator used when Nocterra concatenates local and site-wide title metadata.
This setting is only used when environment.title is configured as prepend or extend and both values are present and different.
Default:
If not configured (or configured as an empty value), Nocterra sets this setting to ' | '.
<?PHP
$environment = array(
'titleSeparator' => 'Example',
);
?>
<?PHP
$environment = array(
'titleSeparator' => '',
);
?>
meta_scope_enum $title = 'prepend'Determines how the final title metadata is assembled for the HTML output.
This setting does not define the title text itself. It controls how Nocterra combines:
the site-wide title value (configured under the branding settings), and
a page-local title value (provided by the current page/article metadata or by page-level API calls, for example setTitle()).
Allowed values:
local
Use the local title when it is present (non-empty). If no local title is provided, fall back to the site-wide title.
prepend
When both local and site-wide title are present and different: output local + separator + site-wide. Otherwise output the site-wide title.
extend
When both local and site-wide title are present and different: output site-wide + separator + local. Otherwise output the site-wide title.
Separator:
When concatenating, the separator is taken from environment.titleSeparator.
Default:
If not configured (or configured as an empty value), Nocterra sets this setting to 'prepend'.
<?PHP
$environment = array(
'title' => 'extend',
);
?>
<?PHP
$environment = array(
'title' => 'prepend',
);
?>
<?PHP
$environment = array(
'title' => 'local',
);
?>
viewport_value $viewport = UNSETControls the HTML <META name="viewport"> tag emitted in the document <HEAD>.
The value is used as the content attribute of the viewport meta tag. This allows you to control how the page is scaled and laid out on mobile and responsive browsers.
Default:
If this setting is empty or not configured, no viewport meta tag is emitted in the HTML head.
Example configuration:
'viewport' => 'width=device-width, initial-scale=1',
Example output:
<META name="viewport" content="width=device-width, initial-scale=1">
<?PHP
$environment = array(
'viewport' => 'width=device-width, initial-scale=1',
);
?>
<?PHP
$environment = array(
'viewport' => NULL,
);
?>
$environment = array(
'imageScaler' => array(
'EtagIncludeiNode' => FALSE,
'sizes' => UNSET MANDATORY,
'xSendFile' => FALSE,
),
);
Settings for the image scaling endpoint.
When this subsection is configured, Nocterra can serve scaled images by generating a resized variant on-demand and storing it in /cache/images/. The requested size is provided via the request parameter size and must match one of the configured allowed sizes.
At minimum, environment.imageScaler.sizes must be configured. Other settings are optional and control how the scaled file is served (for example via X-Sendfile).
boolean $EtagIncludeiNode = FALSEControl whether the generated Etag includes the file i-node.
When environment.imageScaler.xSendFile is disabled (or not configured), the image scaler emits an Etag header for the cached image file.
If this setting is enabled, the Etag includes:
the i-node,
the content length,
and a timestamp derived from the source image modification time.
If disabled (or not configured), the Etag omits the i-node and uses:
the content length,
and a timestamp derived from the source image modification time.
Default:
If not configured, the scaler behaves as if this setting is FALSE.
<?PHP
$environment = array(
'imageScaler' => array(
'EtagIncludeiNode' => TRUE,
),
);
?>
<?PHP
$environment = array(
'imageScaler' => array(
'EtagIncludeiNode' => FALSE,
),
);
?>
<?PHP
$environment = array(
'imageScaler' => array(
'EtagIncludeiNode' => 1,
),
);
?>
<?PHP
$environment = array(
'imageScaler' => array(
'EtagIncludeiNode' => 0,
),
);
?>
integer_list $sizes = UNSET MANDATORYList of allowed target widths (in pixels) for scaled images.
The image scaler expects the request parameter size to match one of the values in this list. If the requested size is not in the list, the scaler responds with 404.
The target height is derived automatically by preserving the original aspect ratio.
Required:
This setting must be configured when environment.imageScaler is used.
<?PHP
$environment = array(
'imageScaler' => array(
'sizes' => array(
320,
640,
1280
),
),
);
?>
boolean $xSendFile = FALSEEnable server-assisted file delivery using the X-Sendfile response header.
When enabled, the image scaler emits:
X-Sendfile: ...
Content-Type: ...
The web server is then expected to send the cached image file to the client.
When disabled (or not configured), the image scaler sends the file contents itself and also emits caching headers (such as Last-Modified and Etag).
Default:
If not configured, the scaler behaves as if this setting is FALSE.
<?PHP
$environment = array(
'imageScaler' => array(
'xSendFile' => TRUE,
),
);
?>
<?PHP
$environment = array(
'imageScaler' => array(
'xSendFile' => FALSE,
),
);
?>
<?PHP
$environment = array(
'imageScaler' => array(
'xSendFile' => 1,
),
);
?>
<?PHP
$environment = array(
'imageScaler' => array(
'xSendFile' => 0,
),
);
?>
$environment = array(
'imageSets' => array(
'<imageset>' => array(
'defaultWidth' => UNSET,
'fileWidths' => UNSET,
'imageOverride' => UNSET,
'renderHints' => UNSET,
'timestampBase' => UNSET,
),
),
);
Settings for a single image set definition under environment.imageSets.
An image set defines how Nocterra expands image placeholders into concrete resource URLs, and (when applicable) how it emits responsive image variants (such as srcset and sizes). The <imageset> key is fully author-defined and has no built-in meaning; choose stable, descriptive names because the key becomes part of the placeholder syntax used throughout the site.
Image sets are referenced using the same notation in configuration values, pages and articles, for example:
LogoSet{images/logo.png}
Photograph{images/home/workshop.png}
Using an image set in page/article HTML is straightforward: the author can place the placeholder directly in an attribute that expects a URL, for example:
<IMG src="FooterIcon{images/icon_linkedin.png}" alt="LinkedIn">
Nocterra expands the image set placeholder into a concrete URL. When multiple widths are configured, the expansion can also provide responsive variants (for example via srcset and optionally sizes, depending on the image set settings and the output context).
Nocterra may additionally apply its resource timestamping mechanism to the local URLs produced by image set expansion. This is the same mechanism used for other local resources: it rewrites eligible URLs into an internal placeholder and expands that placeholder just before output to include a cache-busting version token. Image sets and resource timestamping are separate features, but they commonly interact because image set expansion typically yields local resource URLs.
Typical uses:
Responsive icons and logos with a fixed set of pre-rendered pixel-optimized widths.
Switching themed assets (for example seasonal logos) by changing the image set key used in branding, which results in different emitted filenames and therefore a browser fetch of the updated asset.
Large images (such as photographs or social preview images) where the configured widths may need to align with the sizes supported by environment.imageScaler.
The behavior of an image set is configured by its nested settings (override target, version source, width set, rendering hints and default width).
integer $defaultWidth = UNSETDefault width (in pixels) used for the primary emitted URL of this image set.
When fileWidths is configured, Nocterra still emits a primary URL (for example in src). The defaultWidth controls which width variant is used for that primary URL.
If this setting is not configured:
when fileWidths is configured, the first width may be used as the default (depending on the implementation),
otherwise the base filename without a width suffix is used.
<?PHP
$environment = array(
'imageSets' => array(
'<imageset>' => array(
'defaultWidth' => 7,
),
),
);
?>
<?PHP
$environment = array(
'imageSets' => array(
'<imageset>' => array(
'defaultWidth' => NULL,
),
),
);
?>
integer_list $fileWidths = UNSETList of available file widths (in pixels) for this image set.
When more than one width is configured, Nocterra can emit a srcset attribute for the resource so the browser can pick the most appropriate variant. The variants are expected to exist as separate files whose filenames include the width suffix.
Typical naming pattern:
images/icon.png
images/icon-48.png
images/icon-96.png
images/icon-256.png
If exactly one width is configured, Nocterra treats that width as the default width unless defaultWidth is configured.
Default:
If not configured, Nocterra emits a single URL without srcset.
<?PHP
$environment = array(
'imageSets' => array(
'<imageset>' => array(
'fileWidths' => array(
320,
640,
1280
),
),
),
);
?>
resource_path $imageOverride = UNSETOverride the resource filename used for this image set.
When configured, the {...} part of an image-set placeholder is ignored for the purpose of selecting the source filename. Instead, the configured override filename is used. This makes it possible to switch themed assets (for example seasonal logos) by changing only the image set key used elsewhere, while keeping all references stable.
If the override filename includes a file extension, that extension is used. If it has no extension, the extension from the placeholder is used.
Default:
If not configured, the placeholder’s filename is used.
<?PHP
$environment = array(
'imageSets' => array(
'<imageset>' => array(
'imageOverride' => 'images/favicon.png',
),
),
);
?>
<?PHP
$environment = array(
'imageSets' => array(
'<imageset>' => array(
'imageOverride' => 'style/layout.css',
),
),
);
?>
<?PHP
$environment = array(
'imageSets' => array(
'<imageset>' => array(
'imageOverride' => NULL,
),
),
);
?>
string $renderHints = UNSETRendering hints for responsive images, emitted as the sizes attribute.
When configured, Nocterra includes a sizes attribute alongside srcset so the browser can choose an appropriate variant more accurately. The value is copied as-is into the HTML attribute and must be valid according to HTML rules for sizes.
This setting is only meaningful when fileWidths provides multiple widths.
Default:
If not configured, no sizes attribute is emitted by the image set expansion.
<?PHP
$environment = array(
'imageSets' => array(
'<imageset>' => array(
'renderHints' => 'Example',
),
),
);
?>
<?PHP
$environment = array(
'imageSets' => array(
'<imageset>' => array(
'renderHints' => '',
),
),
);
?>
integer $timestampBase = UNSETControl cache-busting versioning for URLs emitted by this image set.
When configured, Nocterra appends a version token to the emitted filename based on file modification time. If timestampBase is configured, it is also incorporated into the versioning behavior for this image set.
This setting is primarily used to keep predictable versioning behavior when switching image overrides or when using multiple image sets with different width sets.
Default:
If not configured, versioning is based on the image file itself.
<?PHP
$environment = array(
'imageSets' => array(
'<imageset>' => array(
'timestampBase' => 7,
),
),
);
?>
<?PHP
$environment = array(
'imageSets' => array(
'<imageset>' => array(
'timestampBase' => NULL,
),
),
);
?>
$languages = array(
'<language>' MANDATORY => array(
'date_l' => UNSET,
'date_m' => UNSET,
'date_s' => UNSET,
'image' => UNSET,
'locale' => UNSET,
'name' => UNSET,
'text' => UNSET,
'time_l' => UNSET,
'time_m' => UNSET,
'time_s' => UNSET,
),
);
Language configuration.
The languages section defines per-language metadata and formatting settings. Each entry is keyed by a language code (commonly two letters such as en
, nl
).
Required:
locale is used for setLocale(LC_ALL, locale) after the request language is selected.
Optional but commonly used:
name display name of the language.
text user-facing label for links (used by the language selector). If absent, name is used.
image optional image reference for the language selector.
Time and date formatting fields (time_s, time_m, time_l, date_s, date_m, date_l) are format templates used by Nocterra’s formatting functions.
Note:
Nocterra adds internal derived fields (such as per-domain base and baseLang) under each language entry. Those are not configured manually.
sdatetime_format $date_l = UNSETLong date format for language <language>.
Used where a natural-language date is preferred (article headers, detailed metadata, print-style pages). This format typically uses full month names and may include an ordinal day.
Common tokens for long date:
%Month_name% full month name (locale dependent)
%date% day of month (1–31)
%date_ord% ordinal day string (locale dependent)
%year% year (4 digits)
Typical formats:
%Month_name% %date_ord%, %year%
%date% %Month_name% %year%
<?PHP
$languages = array(
'<language>' => array(
'date_l' => '%hour%:%minute%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'date_l' => '%hour%:%minute%:%seconds%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'date_l' => '%year%/%month0%/%date0%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'date_l' => '%Month_name% %date_ord%, %year%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'date_l' => '%H:%M',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'date_l' => '%d-%m-%Y',
),
);
?>
sdatetime_format $date_m = UNSETMedium date format for language <language>.
Used where the date should be human-friendly while still compact. Often uses an abbreviated month name.
Common tokens for medium date:
%date0% day of month (01–31)
%date% day of month (1–31)
%Month_abbr% abbreviated month name (locale dependent)
%year% year (4 digits)
Typical formats:
%date0%-%Month_abbr%-%year%
%Month_abbr%/%date0%/%year%
<?PHP
$languages = array(
'<language>' => array(
'date_m' => '%hour%:%minute%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'date_m' => '%hour%:%minute%:%seconds%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'date_m' => '%year%/%month0%/%date0%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'date_m' => '%Month_name% %date_ord%, %year%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'date_m' => '%H:%M',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'date_m' => '%d-%m-%Y',
),
);
?>
sdatetime_format $date_s = UNSETShort date format for language <language>.
Used where a compact numeric date is preferred (tables, lists, small UI). This format should avoid long month names.
Common tokens for short date:
%year% year (4 digits)
%month0% month (01–12)
%date0% day of month (01–31)
Alternatives (non-zero padded):
%month% month (1–12)
%date% day (1–31)
Typical formats:
ISO-like: %year%-%month0%-%date0%
Slash: %year%/%month0%/%date0%
<?PHP
$languages = array(
'<language>' => array(
'date_s' => '%hour%:%minute%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'date_s' => '%hour%:%minute%:%seconds%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'date_s' => '%year%/%month0%/%date0%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'date_s' => '%Month_name% %date_ord%, %year%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'date_s' => '%H:%M',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'date_s' => '%d-%m-%Y',
),
);
?>
resource_path $image = UNSETOptional image reference for the language selector.
If configured, the language selector renders the image instead of text for that language. The image alt text uses languages<language>.name when available, otherwise the uppercased language code.
<?PHP
$languages = array(
'<language>' => array(
'image' => 'images/favicon.png',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'image' => 'style/layout.css',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'image' => NULL,
),
);
?>
locale_code $locale = UNSETLocale for this language.
This setting assigns a locale code to a language entry in languages<language>. Nocterra uses it to determine the language’s regional behavior, such as how dates and times are formatted and which locale should be communicated to user agents and bots where applicable.
Use a locale that matches the language and region you want to present for this language (for example en_GB for British English, nl_NL for Dutch in the Netherlands).
Format:
Use a locale code in the common form language_COUNTRY.
The code should be supported by your server environment.
<?PHP
$languages = array(
'<language>' => array(
'locale' => 'en_GB',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'locale' => 'jp_JP',
),
);
?>
string $name = UNSETDisplay name of the language.
Used for user-facing output such as the language selector and for sorting when the language selector order is set to ascending or descending.
<?PHP
$languages = array(
'<language>' => array(
'name' => 'Example',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'name' => '',
),
);
?>
string $text = UNSETOptional user-facing label for this language.
Used by the language selector as link text (and may be used as a tooltip when an image is configured). If not configured, Nocterra falls back to name, and otherwise to the uppercased language code.
<?PHP
$languages = array(
'<language>' => array(
'text' => 'Example',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'text' => '',
),
);
?>
sdatetime_format $time_l = UNSETLong time format for language <language>.
Used when time formatting may be shown in contexts where clarity is preferred over compactness (for example detailed views, logs, or long-form metadata). Depending on the site, this format may match the medium format.
Common tokens for long time:
%hour% hour (00–23)
%minute% minute (00–59)
%second% second (00–59)
If your site never displays seconds, you can keep it equal to time_s.
<?PHP
$languages = array(
'<language>' => array(
'time_l' => '%hour%:%minute%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'time_l' => '%hour%:%minute%:%seconds%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'time_l' => '%year%/%month0%/%date0%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'time_l' => '%Month_name% %date_ord%, %year%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'time_l' => '%H:%M',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'time_l' => '%d-%m-%Y',
),
);
?>
sdatetime_format $time_m = UNSETMedium time format for language <language>.
Used where time should remain readable and precise, but still compact. Commonly includes seconds.
Common tokens for medium time:
%hour% hour (00–23)
%minute% minute (00–59)
%second% second (00–59)
Legacy aliases (seen on older sites):
%minutes% alias of %minute%
%seconds% alias of %second%
Typical format:%hour%:%minute%:%second%
<?PHP
$languages = array(
'<language>' => array(
'time_m' => '%hour%:%minute%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'time_m' => '%hour%:%minute%:%seconds%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'time_m' => '%year%/%month0%/%date0%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'time_m' => '%Month_name% %date_ord%, %year%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'time_m' => '%H:%M',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'time_m' => '%d-%m-%Y',
),
);
?>
sdatetime_format $time_s = UNSETShort time format for language <language>.
Used when Nocterra needs a compact time representation (for example in lists, compact metadata, or UI elements where space is limited). The exact places depend on the templates and features used by the site, but all use the same date/time formatter.
Common tokens for short time:
%hour% hour (00–23)
%minute% minute (00–59)
Typical format:%hour%:%minute%
<?PHP
$languages = array(
'<language>' => array(
'time_s' => '%hour%:%minute%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'time_s' => '%hour%:%minute%:%seconds%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'time_s' => '%year%/%month0%/%date0%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'time_s' => '%Month_name% %date_ord%, %year%',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'time_s' => '%H:%M',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'time_s' => '%d-%m-%Y',
),
);
?>
$page = array(
'<language>' => array(
'contentSecurityPolicy' => UNSET,
'script' => UNSET,
'timestamping' => UNSET,
),
);
Per-language page rendering configuration.
This section contains page-level rendering settings for the active language. The settings in this section influence structural output (header/body/footer fragments), scripts, Content-Security-Policy emission, resource timestamping rules, and navigation components such as breadcrumbs and footer layout.
The configuration is defined per language and is merged into the active runtime variant during compilation:
Base values are taken from $page for the language.
Variant overrides may be provided via $variants[variant]['page'][language].
Missing keys are filled with defaults by the compiler, and several settings are normalized into a consistent runtime shape.
Typical configuration structure:
$page = array(
'en' => array(
...
),
'fr' => array(
...
),
);
Variant overrides:
$variants = array(
'' => array(
'page' => array(
'en' => array(
...
),
),
),
'myvariant' => array(
'page' => array(
'en' => array(
...
),
),
),
);
Notes:
This section is per language. The currently active page configuration is selected through the current variant and language.
Several nested structures are normalized by the compiler (for example scripts, breadcrumbs, CSP directives, and timestamping).
content_security_policy_spec $contentSecurityPolicy = UNSETContent Security Policy configuration for the current page language.
What this does in Nocterra:
The configured policy is emitted into the HTML head as:
<META http-equiv="Content-Security-Policy" content="...">
Nocterra then also sends the same policy as an HTTP response header:
Content-Security-Policy: ...
This means the CSP is applied to:
regular dynamic responses,
cached responses that are served from the generated page output,
and therefore it affects the page as seen by browsers and other user agents that enforce CSP.
Nocterra directive keywords:
Nocterra uses a simplified, readable set of directive keywords in the configuration. Use these Nocterra keywords instead of the official CSP directive names.
Common Nocterra directives:
default Baseline policy for sources not explicitly covered by other directives.
scripts Where scripts may load from.
styles Where stylesheets may load from.
images Where images may load from.
fonts Where fonts may load from.
connect Where fetch/XHR/WebSocket connections may connect to.
forms Where forms may submit to.
frames Where frames/iframes may load from.
ancestors Which pages may embed this page as a frame (clickjacking protection).
media, objects, manifests, workers More specialized controls.
Reporting:
Nocterra supports a report key that controls whether CSP violation reports are enabled. When enabled, Nocterra appends a reporting directive to the emitted policy.
Input forms supported by Nocterra:
Preferred: an associative array using Nocterra keywords.
Also supported: a single CSP string. Nocterra parses the string and normalizes known CSP directives into its Nocterra keyword form. For maintainability, prefer the Nocterra keyword form in configuration.
YouTube embeds:
For YouTube video pages, the most common requirement is to allow the framed player origin via frames. Many sites only need https://www.youtube-nocookie.com. Some installations (or user/region consent flows) also require allowing additional framed origins such as https://www.youtube.com, https://www.google.com, and https://consent.google.nl.
Thumbnails:
Do not add an images allowlist just for the YouTube player’s preview image. If the thumbnail is rendered inside the YouTube iframe, it is not governed by your page’s CSP. Only add external image sources (for example https://i.ytimg.com) when your Nocterra page itself loads those thumbnails outside the iframe (for example via an <IMG> tag or CSS background images).
Nocterra defaults:
If certain directives are missing, Nocterra applies defaults:
default 'self'
forms 'self'
ancestors 'none'
Important notes:
Values are written in CSP syntax (for example 'self', 'none', hosts, schemes).
Nocterra sanitizes directive names and values before output to avoid breaking the emitted CSP.
<?PHP
$page = array(
'<language>' => array(
'contentSecurityPolicy' => array(
'default' => "'self'",
'styles' => "'self'",
'scripts' => "'self'",
'images' => "'self' data:",
'ancestors' => "'none'",
'forms' => "'self'",
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'contentSecurityPolicy' => array(
'report' => true,
'frames' => "https://www.youtube-nocookie.com",
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'contentSecurityPolicy' => array(
'report' => true,
'frames' => "https://www.youtube-nocookie.com https://www.youtube.com https://www.google.com https://consent.google.nl",
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'contentSecurityPolicy' => array(
'report' => true,
'frames' => "https://www.youtube-nocookie.com",
'images' => "'self' https://i.ytimg.com",
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'contentSecurityPolicy' => "default-src 'self'; style-src 'self'; script-src 'self'; img-src 'self' data:; frame-ancestors 'none'; form-action 'self'",
),
);
?>
script_spec $script = UNSETConfigures one or more script resources for the current page language.
This setting accepts multiple input forms. During compilation, all supported forms are normalized into a list of script entries. Each entry has:
script (resource path)
type (MIME type, default text/javascript
)
During page rendering, a script tag is emitted for each normalized entry:
<SCRIPT charset="UTF-8" src="..." type="..."></SCRIPT>
If this setting is not configured, it is treated as an empty list and no scripts are emitted.
<?PHP
$page = array(
'<language>' => array(
'script' => 'js/site.js',
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'script' => array(
'js/site.js',
'js/extra.js',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'script' => array(
'script' => 'js/site.js',
'type' => 'text/javascript',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'script' => array(
array(
'script' => 'js/site.js',
'type' => 'text/javascript',
),
array(
'script' => 'js/extra.js',
'type' => 'text/javascript',
),
),
),
);
?>
timestamping_spec $timestamping = UNSETConfigures resource timestamping exclusions for the current page language.
When a resource path matches one of the configured excluded prefixes, Nocterra will not append a timestamp suffix (for example _v1234567890
) to that resource URL.
If this setting is not configured, no paths are excluded.
<?PHP
$page = array(
'<language>' => array(
'timestamping' => 'images',
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'timestamping' => array(
'images',
'downloads',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'timestamping' => array(
'excludePaths' => 'images',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'timestamping' => array(
'excludePaths' => array(
'images',
'downloads',
),
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'timestamping' => array(
'excludePaths' => array(),
),
),
);
?>
$page = array(
'<language>' => array(
'body' => array(
'ariaLabelledBy' => NULL,
'ariaLabel' => NULL,
'class' => 'body',
'epilogue' => '',
'prologue' => '',
'role' => NULL,
),
),
);
Page body container configuration for the current page language.
The page body is the Nocterra page body <DIV class="body">...</DIV> that wraps the generated page content. The settings in this subsection control:
optional prologue and epilogue output inside the body container,
the CSS class applied to the body container, and
optional ARIA attributes on the body container.
Values such as prologue and epilogue are emitted as-is by Nocterra and may contain trusted HTML.
string | NULL $ariaLabelledBy = NULLOptional aria-labelledby for the Nocterra page body container.
Accessibility:aria-labelledby gives the page body region an accessible name by referencing the ID of another element whose text labels it. Prefer this over aria-label when a visible heading exists.
Where the label element can live:
Most obvious: the first heading in the page body content (for example the page’s <H1>), if it has an id.
Also common: an element added in prologue (for example a short heading or label placed directly before the main body content).
Less common: an element added in epilogue.
Also possible: another element elsewhere in the page output, as long as it exists in the final HTML and has a unique ID.
When NULL or not configured, no aria-labelledby attribute is emitted.
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'ariaLabelledBy' => 'Example',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'ariaLabelledBy' => '',
),
),
);
?>
string | NULL $ariaLabel = NULLOptional aria-label for the Nocterra page body container.
Accessibility:
An aria-label provides an accessible name for the region. Use this only if you intentionally turn the body container into a landmark (for example via role) and you need a label to distinguish it from other regions.
When NULL or not configured, no aria-label attribute is emitted.
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'ariaLabel' => 'Example',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'ariaLabel' => '',
),
),
);
?>
string $class = 'body'CSS class name for the Nocterra page body container (<DIV class="..."></DIV>).
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'class' => 'Example',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'class' => '',
),
),
);
?>
html_block $epilogue = ''Optional content emitted at the end of the Nocterra page body container.
This value is emitted as-is and may contain trusted HTML. Use block-level markup as needed (<P>, <DIV>, <UL>, etc.).
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'epilogue' => '<P>Line one</P><P>Line two</P>',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'epilogue' => '<DIV class="notice"><P>Maintenance</P></DIV>',
),
),
);
?>
html_block $prologue = ''Optional content emitted at the start of the Nocterra page body container.
This value is emitted as-is and may contain trusted HTML. Use block-level markup as needed (<P>, <DIV>, <UL>, etc.).
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'prologue' => '<P>Line one</P><P>Line two</P>',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'prologue' => '<DIV class="notice"><P>Maintenance</P></DIV>',
),
),
);
?>
string | NULL $role = NULLOptional role attribute for the Nocterra page body container (<DIV class="body">...</DIV>).
Accessibility:
A landmark role helps assistive technologies (such as screen readers) identify the page’s main regions and provides quick navigation between them. Use a role here only when you intentionally want the Nocterra page body container to act as a landmark.
Recommended values (common use):
main The primary content of the page. This is the most useful role for the Nocterra page body on most pages.
article A self-contained composition (for example a blog article). Prefer using article on an inner article container if available; keep the page body as main.
region A labelled section. Use this when the page body is one of multiple distinct regions and you provide ariaLabel or ariaLabelledBy.
form A region that contains a form. Prefer applying this to a dedicated form container inside the body; use it on the body only if the body is essentially “the form page”.
Less useful or advanced values:
document Usually redundant for typical pages.
application Use with great care and typically only on a dedicated interactive application container, not on the whole page body.
Practical guidance by Nocterra page type:
Regular content page: use main.
Contact form / signup / checkout page: use main; optionally set form on the form container inside the body. Use form on the body only if the body is entirely the form interaction.
Portal / dashboard page: keep the page body as main. If the page has multiple panels/blocks, prefer region + label on those inner blocks, not on the entire body.
Article page (blog post): keep the page body as main and use article on the article container when available.
When set to NULL or when not configured, no role attribute is emitted.
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'role' => 'Example',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'role' => '',
),
),
);
?>
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'epilogue' => '',
'minLevel' => 1,
'nonLinkText' => TRUE,
'prologue' => '',
'separator' => ', ',
'subSeparator' => ' - ',
),
),
);
Configures breadcrumb rendering for the current page language.
The breadcrumbs section controls when breadcrumbs are emitted, how the trail is formatted, and whether intermediate non-link path parts may be shown as text.
Defaults are applied by the settings compiler when keys are not configured.
Notes:
Values such as prologue, separator, subSeparator, and epilogue are emitted as-is by the renderer, so they may contain trusted HTML.
html_inline $epilogue = ''Text emitted after the breadcrumb trail.
This value is emitted as-is (trusted HTML).
<?PHP
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'epilogue' => 'Welcome',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'epilogue' => 'You are here: <SPAN class="hint">Home</SPAN>',
),
),
);
?>
integer $minLevel = 1Minimum path depth required before breadcrumbs are emitted.
If the current request path has fewer components than minLevel, the breadcrumb block is not emitted.
<?PHP
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'minLevel' => 7,
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'minLevel' => NULL,
),
),
);
?>
boolean $nonLinkText = TRUEControls whether intermediate non-link path parts may be emitted as plain text.
When TRUE, non-link parts are not emitted as accumulated text.
When FALSE, non-link parts may be accumulated and emitted as text before the next linked breadcrumb item, separated using subSeparator.
<?PHP
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'nonLinkText' => TRUE,
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'nonLinkText' => FALSE,
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'nonLinkText' => 1,
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'nonLinkText' => 0,
),
),
);
?>
html_inline $prologue = ''Text emitted before the breadcrumb trail.
This value is emitted as-is (trusted HTML).
<?PHP
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'prologue' => 'Welcome',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'prologue' => 'You are here: <SPAN class="hint">Home</SPAN>',
),
),
);
?>
html_inline $separator = ', 'Separator emitted between breadcrumb items.
This value is emitted as-is (trusted HTML).
<?PHP
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'separator' => 'Welcome',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'separator' => 'You are here: <SPAN class="hint">Home</SPAN>',
),
),
);
?>
string $subSeparator = ' - 'Separator emitted between accumulated non-link text and the next linked breadcrumb item.
This value is only relevant when nonLinkText is FALSE. The value is emitted as-is (trusted HTML).
<?PHP
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'subSeparator' => 'Example',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'subSeparator' => '',
),
),
);
?>
$page = array(
'<language>' => array(
'footer' => array(
'columns' => UNSET,
'epilogue' => '',
'prologue' => '',
'showHeader' => true,
),
),
);
Footer configuration for the current page language.
Nocterra outputs the footer as a dedicated footer block near the end of the HTML body. This section controls:
optional footer prologue and epilogue fragments (trusted HTML),
whether the footer column headers are shown,
and (in a separate setting) the footer column structure.
The footer is typically emitted after the navigation block and before the page-level epilogue output.
footer_columns_spec $columns = UNSETDefines the footer column layout and content.
Each top-level entry in columns creates one footer column. The number of entries determines the layout class (columns-1, columns-2, …) that can be styled in CSS.
A column value can be:
A trusted HTML fragment (string), emitted as-is, or
A link list (associative array) of label => link.
The column key is used as the column header when page<language>.footer.showHeader is enabled and the key is not empty.
If this setting is not configured (or is an empty array), no footer columns are rendered.
<?PHP
$page = array(
'<language>' => array(
'footer' => array(
'columns' => array(
'Service' => array(
'FAQ' => '/service/faq',
'Downloads' => '/service/downloads',
'Privacy' => '/service/privacy',
'Contact' => '/service/contact',
),
'About' => array(
'Foundation' => '/about',
'News' => '/articles/category/news',
),
),
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'footer' => array(
'columns' => array(
'' => '<P><A href="/donate">Support us</A></P>',
'Service' => array(
'FAQ' => '/service/faq',
'Privacy' => '/service/privacy',
),
),
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'footer' => array(
'columns' => array(
'1' => '<P>Address…</P>',
'2' => array(
'Contact' => '/contact',
'About' => '/about',
),
),
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'footer' => array(
'columns' => array(
'Info' => array(
'Contact' => '/contact',
'' => '',
'Privacy' => '/privacy',
),
),,
),
),
);
?>
html_block $epilogue = ''Optional footer epilogue fragment.
When set, this value is output at the end of the footer block, after the footer columns (and any default footer elements such as copyright).
This value is emitted as-is and may contain trusted HTML. Use block-level markup as needed (<P>, <DIV>, <UL>, etc.).
<?PHP
$page = array(
'<language>' => array(
'footer' => array(
'epilogue' => '<P>Line one</P><P>Line two</P>',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'footer' => array(
'epilogue' => '<DIV class="notice"><P>Maintenance</P></DIV>',
),
),
);
?>
html_block $prologue = ''Optional footer prologue fragment.
When set, this value is output at the start of the footer block, before the footer columns are rendered.
This value is emitted as-is and may contain trusted HTML. Use block-level markup as needed (<P>, <DIV>, <UL>, etc.).
<?PHP
$page = array(
'<language>' => array(
'footer' => array(
'prologue' => '<P>Line one</P><P>Line two</P>',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'footer' => array(
'prologue' => '<DIV class="notice"><P>Maintenance</P></DIV>',
),
),
);
?>
boolean $showHeader = trueControls whether footer column headers are displayed.
When enabled, Nocterra outputs a heading element for each footer column category (the category key of the columns structure). When disabled, column headers are suppressed.
Note:
This setting affects only the column header output; it does not enable/disable the footer itself.
<?PHP
$page = array(
'<language>' => array(
'footer' => array(
'showHeader' => TRUE,
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'footer' => array(
'showHeader' => FALSE,
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'footer' => array(
'showHeader' => 1,
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'footer' => array(
'showHeader' => 0,
),
),
);
?>
$page = array(
'<language>' => array(
'languageSelector' => array(
'location' => '',
'order' => 'as-is',
'showCurrent' => false,
'showNearest' => false,
),
),
);
Settings for the language selector element.
The language selector is rendered as a block with <DIV class="language"> containing one entry per available language.
Each entry is normally a link (<A>) with hreflang set. Depending on configuration it may also include the current language as non-link text or image.
output_location_enum $location = ''Selects where the language selector is emitted.
When this setting is not configured (or is an empty string), the language selector is not emitted.
<?PHP
$page = array(
'<language>' => array(
'languageSelector' => array(
'location' => 'page_bottom',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'languageSelector' => array(
'location' => 'body_top',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'languageSelector' => array(
'location' => 'navigation_top',
),
),
);
?>
language_selector_order_spec $order = 'as-is'Controls the order of language entries in the selector.
Use as-is to keep the order from $languages, or use ascending/descending to sort by the language display name.
You can also provide an explicit array of language codes.
<?PHP
$page = array(
'<language>' => array(
'languageSelector' => array(
'order' => 'as-is',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'languageSelector' => array(
'order' => 'ascending',,
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'languageSelector' => array(
'order' => array('nl', 'en'),,
),
),
);
?>
boolean $showCurrent = falseWhen enabled, include the current language in the language selector output.
If the current language has an image configured in languages<language>, the image is rendered with class current.
Otherwise a <SPAN class="current"> is rendered using the language text.
When disabled, the current language is omitted from the selector.
<?PHP
$page = array(
'<language>' => array(
'languageSelector' => array(
'showCurrent' => TRUE,
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'languageSelector' => array(
'showCurrent' => FALSE,
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'languageSelector' => array(
'showCurrent' => 1,
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'languageSelector' => array(
'showCurrent' => 0,
),
),
);
?>
boolean $showNearest = falseControls what happens when the current page does not exist in a specific language.
When enabled:
If a language does not have a direct link for the current page, Nocterra can still include that language by linking to the nearest available page in that language.
When disabled:
Languages without a direct link are not shown.
Note:
When a direct link exists, the language link is emitted with rel="alternate".
When a nearest fallback is used, rel is omitted.
<?PHP
$page = array(
'<language>' => array(
'languageSelector' => array(
'showNearest' => TRUE,
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'languageSelector' => array(
'showNearest' => FALSE,
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'languageSelector' => array(
'showNearest' => 1,
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'languageSelector' => array(
'showNearest' => 0,
),
),
);
?>
$page = array(
'<language>' => array(
'navigation' => array(
'ariaLabelledBy' => NULL,
'ariaLabel' => NULL,
'class' => 'navigation',
'epilogue' => '',
'location' => 'body_end',
'prologue' => '',
'role' => 'navigation',
),
),
);
Navigation rendering configuration for the current page language.
This subsection controls how the main navigation block is emitted:
placement in the page output (for example at the start or end of the HTML body, header, footer, or page body),
the CSS class used for the navigation container,
optional ARIA attributes.
Values such as prologue and epilogue are emitted as-is by the renderer and may contain trusted HTML.
string | NULL $ariaLabelledBy = NULLOptional aria-labelledby for the navigation container.
Accessibility:aria-labelledby gives the navigation landmark an accessible name by referencing the ID of another element whose text labels the navigation. This is often preferred over aria-label when a visible heading already exists, because the label is then visible to all users and is reused by assistive technologies.
Usage:
Set this value to the ID of an element that contains the label text, for example a heading that precedes the menu.
Where the label element can live:
Most common: in prologue (for example a hidden or visible heading placed immediately before the menu).
Less common: in epilogue.
Also possible: anywhere in the page content, as long as the referenced element exists in the final HTML output and has a unique ID.
When NULL or not configured, no aria-labelledby attribute is emitted.
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'ariaLabelledBy' => 'Example',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'ariaLabelledBy' => '',
),
),
);
?>
string | NULL $ariaLabel = NULLOptional aria-label for the navigation container.
Accessibility:
An aria-label provides an accessible name for the navigation landmark. This allows screen reader users to distinguish navigation regions, especially when there are multiple menus (for example a main menu, a footer menu, or a language selector).
Guidance:
Use a short, descriptive label such as Main navigation
, Footer navigation
, or Service menu
.
Prefer ariaLabelledBy when there is a visible heading that already labels the menu; use ariaLabel when there is no suitable visible label.
When NULL or not configured, no aria-label attribute is emitted.
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'ariaLabel' => 'Example',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'ariaLabel' => '',
),
),
);
?>
string $class = 'navigation'CSS class name for the navigation container element.
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'class' => 'Example',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'class' => '',
),
),
);
?>
html_block $epilogue = ''Optional content emitted at the end of the navigation block.
This value is emitted as-is and may contain trusted HTML.
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'epilogue' => '<P>Line one</P><P>Line two</P>',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'epilogue' => '<DIV class="notice"><P>Maintenance</P></DIV>',
),
),
);
?>
output_location_enum $location = 'body_end'Controls where the navigation block is emitted.
Common values:
body_start, body_end
header_start, header_end
footer_start, footer_end
page_start, page_end
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'location' => 'page_bottom',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'location' => 'body_top',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'location' => 'navigation_top',
),
),
);
?>
html_block $prologue = ''Optional content emitted at the start of the navigation block.
This value is emitted as-is and may contain trusted HTML.
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'prologue' => '<P>Line one</P><P>Line two</P>',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'prologue' => '<DIV class="notice"><P>Maintenance</P></DIV>',
),
),
);
?>
string | NULL $role = 'navigation'Optional role attribute for the navigation container.
Accessibility:
Landmark roles help assistive technologies (such as screen readers) identify page regions and provide quick navigation between them. Using role="navigation" makes the container a navigation landmark.
Notes:
When the element is already a semantic navigation element, an explicit role is often unnecessary. Nocterra emits a DIV container, so setting a role can be useful.
If multiple navigation landmarks exist on one page, use ariaLabel or ariaLabelledBy to distinguish them.
When set to NULL or when not configured, no role attribute is emitted.
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'role' => 'Example',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'role' => '',
),
),
);
?>
$page = array(
'<language>' => array(
'page' => array(
'epilogue' => '',
'prologue' => '',
),
),
);
Page-level output hooks for the current page language.
This subsection controls optional content that Nocterra outputs directly in the HTML <BODY>:
prologue is output immediately after <BODY>, before Nocterra outputs the header/logo and the rest of the page structure.
epilogue is output near the end of <BODY>, after Nocterra outputs the footer and closing page structure.
These values are emitted as-is and may contain trusted HTML. Use block-level markup as needed.
html_block $epilogue = ''Optional content output near the end of the HTML <BODY>, after Nocterra outputs the footer and closing page structure.
This value is emitted as-is and may contain trusted HTML. Use block-level markup as needed (<P>, <DIV>, <UL>, etc.).
Typical uses include site-wide fragments that must be placed at the end of the body.
<?PHP
$page = array(
'<language>' => array(
'page' => array(
'epilogue' => '<P>Line one</P><P>Line two</P>',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'page' => array(
'epilogue' => '<DIV class="notice"><P>Maintenance</P></DIV>',
),
),
);
?>
html_block $prologue = ''Optional content output immediately after the HTML <BODY> tag, before Nocterra outputs the header/logo and the rest of the page structure.
This value is emitted as-is and may contain trusted HTML. Use block-level markup as needed (<P>, <DIV>, <UL>, etc.).
Typical uses include global banners, a skip-link block, or other site-wide fragments that must appear at the very start of the body.
<?PHP
$page = array(
'<language>' => array(
'page' => array(
'prologue' => '<P>Line one</P><P>Line two</P>',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'page' => array(
'prologue' => '<DIV class="notice"><P>Maintenance</P></DIV>',
),
),
);
?>
boolean $EtagIncludeiNode = FALSEControl whether the generated Etag includes the file i-node.
string | NULL $ariaLabel = NULLOptional aria-label for the Nocterra page body container.
string | NULL $ariaLabel = NULLOptional aria-label for the navigation container.
string | NULL $ariaLabelledBy = NULLOptional aria-labelledby for the Nocterra page body container.
string | NULL $ariaLabelledBy = NULLOptional aria-labelledby for the navigation container.
string | NULL $author = UNSETConfigures the global author value for the current branding language.
meta_scope_enum $author = 'extend'Determines how the final author metadata is assembled for the HTML output.
string $authorSeparator = ', 'Separator used when Nocterra concatenates local and site-wide author metadata.
url_path $base = UNSET MANDATORYRequired. The base path prefix for the site on this host.
language | NULL $canonicalLanguage = UNSETSelect the canonical language used when generating certain canonical-style URLs.
string $class = 'body'CSS class name for the Nocterra page body container (<DIV class="..."></DIV>).
string $class = 'navigation'CSS class name for the navigation container element.
footer_columns_spec $columns = UNSETDefines the footer column layout and content.
content_security_policy_spec $contentSecurityPolicy = UNSETContent Security Policy configuration for the current page language.
content_type_eum | NULL $contentType = UNSETConfigures the default structured content type for pages under the current branding language.
host_name $cookieDomain = UNSETCookie domain used by the site.
html_inline | NULL $copyright = UNSETConfigures the copyright line for the current branding language.
data_store_enum $data_store = UNSET MANDATORYSelects the data store mapping mode used to locate page data files under /data.
integer $data_storeLevels = 1Controls how the requested URL path is mapped to directories and filenames under /data.
sdatetime_format $date_l = UNSETLong date format for language <language>.
sdatetime_format $date_m = UNSETMedium date format for language <language>.
sdatetime_format $date_s = UNSETShort date format for language <language>.
language $defaultLanguage = UNSETDefault language for this host.
integer $defaultWidth = UNSETDefault width (in pixels) used for the primary emitted URL of this image set.
string | NULL $description = UNSETConfigures the global description value for the current branding language.
meta_scope_enum $description = 'local'Determines how the final description metadata is assembled for the HTML output.
string $descriptionSeparator = ', 'Separator used when Nocterra concatenates local and site-wide description metadata.
duration_seconds $dynamicMaxAge = UNSET MANDATORYControls the cache lifetime (in seconds) for responses that contain dynamic pair placeholders.
html_block $epilogue = ''Optional content emitted at the end of the Nocterra page body container.
html_inline $epilogue = ''Text emitted after the breadcrumb trail.
html_block $epilogue = ''Optional footer epilogue fragment.
html_block $epilogue = ''Optional content emitted at the end of the navigation block.
html_block $epilogue = ''Optional content output near the end of the HTML <BODY>, after Nocterra outputs the footer and closing page structure.
resource_path | NULL $favicon = UNSETConfigures the favicon resource for the current branding language.
integer_list $fileWidths = UNSETList of available file widths (in pixels) for this image set.
php_callbacks | NULL $generateDynamic = NULLRegisters one or more callbacks that provide per-request, site-wide dynamic behavior.
php_callbacks | NULL $generateStatic = NULLRegisters one or more callbacks that generate site-wide output during request rendering.
host_name $host = UNSETRequired. The canonical host name for this domain entry.
resource_path $image = UNSETOptional image reference for the language selector.
resource_path $imageOverride = UNSETOverride the resource filename used for this image set.
string | NULL $keywords = UNSETConfigures the global keywords value for the current branding language.
meta_scope_enum $keywords = 'extend'Determines how the final keywords metadata is assembled for the HTML output.
string $keywordsSeparator = ', 'Reserved separator setting for keywords concatenation.
language_spec $languages = UNSETDefines which languages are served on this domain.
php_files | NULL $loadAddons = NULLLoads additional PHP files (addons) before handling the request.
output_location_enum $location = ''Selects where the language selector is emitted.
output_location_enum $location = 'body_end'Controls where the navigation block is emitted.
resource_path | NULL $logoImage = UNSETConfigures the logo image resource for the current branding language.
string | NULL $logoLink = UNSETControls whether the logo image is emitted as a link.
string | NULL $logoText = UNSETConfigures the alternative text for the logo image for the current branding language.
integer $minLevel = 1Minimum path depth required before breadcrumbs are emitted.
boolean $nonLinkText = TRUEControls whether intermediate non-link path parts may be emitted as plain text.
language_selector_order_spec $order = 'as-is'Controls the order of language entries in the selector.
integer $priority = UNSETOptional priority value used when resolving languages and domains.
html_block $prologue = ''Optional content emitted at the start of the Nocterra page body container.
html_inline $prologue = ''Text emitted before the breadcrumb trail.
html_block $prologue = ''Optional footer prologue fragment.
html_block $prologue = ''Optional content emitted at the start of the navigation block.
html_block $prologue = ''Optional content output immediately after the HTML <BODY> tag, before Nocterra outputs the header/logo and the rest of the page structure.
duration_seconds $redirectMaxAge = UNSET MANDATORYControls the cache lifetime (in seconds) for redirect responses generated by Nocterra.
string $renderHints = UNSETRendering hints for responsive images, emitted as the sizes attribute.
duration_seconds $responseMaxAge = UNSET MANDATORYControls the cache lifetime (in seconds) for normal (non-dynamic) responses.
string | NULL $role = NULLOptional role attribute for the Nocterra page body container (<DIV class="body">...</DIV>).
string | NULL $role = 'navigation'Optional role attribute for the navigation container.
script_spec $script = UNSETConfigures one or more script resources for the current page language.
html_inline $separator = ', 'Separator emitted between breadcrumb items.
boolean $showCurrent = falseWhen enabled, include the current language in the language selector output.
boolean $showHeader = trueControls whether footer column headers are displayed.
boolean $showNearest = falseControls what happens when the current page does not exist in a specific language.
resource_path | NULL $siteImage = UNSETConfigures the site image resource used for social meta output.
duration_seconds $sitemapCacheMaxAge = 24*60*60Controls the cache lifetime (in seconds) for sitemap caching.
integer_list $sizes = UNSET MANDATORYList of allowed target widths (in pixels) for scaled images.
style_sheet_spec $stylesheet = UNSETConfigures one or more stylesheets for the current branding language.
string $subSeparator = ' - 'Separator emitted between accumulated non-link text and the next linked breadcrumb item.
html_inline | NULL $subtitle = UNSETConfigures the site subtitle for the current branding language.
sdatetime_format $time_l = UNSETLong time format for language <language>.
sdatetime_format $time_m = UNSETMedium time format for language <language>.
sdatetime_format $time_s = UNSETShort time format for language <language>.
integer $timestampBase = UNSETControl cache-busting versioning for URLs emitted by this image set.
timestamping_spec $timestamping = UNSETConfigures resource timestamping exclusions for the current page language.
html_inline | NULL $title = UNSETConfigures the site title for the current branding language.
meta_scope_enum $title = 'prepend'Determines how the final title metadata is assembled for the HTML output.
string $titleSeparator = ' | 'Separator used when Nocterra concatenates local and site-wide title metadata.
viewport_value $viewport = UNSETControls the HTML <META name="viewport"> tag emitted in the document <HEAD>.