English, Nederlands
Donate with PayPal

Manual

Config Reference

In this chapter

Types
Sections
Settings

About

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.

Site configuration

This section covers site-wide configuration that affects the entire installation (global behavior, policies, and defaults). Reference tables for these keys are listed below.

Types

boolean

Description

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.

Examples
<?PHP
'<setting>' => TRUE,
'<setting>' => FALSE,
'<setting>' => 1,
'<setting>' => 0,
?>
See Also

content_security_policy_spec

Description

Content Security Policy specification (Nocterra keyword form).

This type configures the Content Security Policy (CSP) that Nocterra outputs for the page:

Nocterra directive keywords (recommended):

Reporting (Nocterra keyword):

Notes:

Examples
<?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'",
?>
See Also

content_type_eum

Description

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:

Notes:

Examples
<?PHP
'<setting>' => 'WebPage',
'<setting>' => 'BlogPosting',
'<setting>' => 'NewsArticle',
'<setting>' => NULL,
?>
See Also

data_store_enum

Description

Enumeration used by environment.data_store to select the URL-path to /data filename mapping mode.

Examples
<?PHP
'<setting>' => 'locale_prefix',
'<setting>' => 'locale_directory',
'<setting>' => 'locale_prefix_menu',
?>
See Also

duration_seconds

Description

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.

Examples
<?PHP
'<setting>' => 300,
'<setting>' => 3600,
'<setting>' => 86400,
'<setting>' => 24*60*60,
?>
See Also

footer_columns_spec

Description

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:

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:

Link lists:
A link list is emitted as <UL> with <LI><A> entries.

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.

Examples
<?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',
),
),,
?>
See Also

host_name

Description

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:

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.

Examples
<?PHP
'<setting>' => 'www.example.com',
'<setting>' => 'account.example.com',
'<setting>' => '.example.com',
?>
See Also

html_block

Description

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.

Examples
<?PHP
'<setting>' => '<P>Line one</P><P>Line two</P>',
'<setting>' => '<DIV class="notice"><P>Maintenance</P></DIV>',
?>
See Also

html_inline

Description

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.

Examples
<?PHP
'<setting>' => 'Welcome',
'<setting>' => 'You are here: <SPAN class="hint">Home</SPAN>',
?>
See Also

integer

Description

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.

Examples
<?PHP
'<setting>' => 7,
'<setting>' => NULL,
?>
See Also

integer_list

Description

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.

Examples
<?PHP
'<setting>' => array(
320,
640,
1280
),
?>
See Also

language

Description

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:

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).

Examples
<?PHP
'<setting>' => 'en',
'<setting>' => 'nl',
?>
See Also

language_selector_order_spec

Description

Language selector ordering specification.

This type defines the value of page<language>.languageSelector.order.

The order can be set in two forms:

  1. 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.

  2. 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.

Examples
<?PHP
'<setting>' => 'as-is',
'<setting>' => 'ascending',,
'<setting>' => array('nl', 'en'),,
?>
See Also

language_spec

Description

Language selection specification.

Use this type for settings that accept either:

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:

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.

Examples
<?PHP
'<setting>' => 'en',
'<setting>' => array('nl', 'en'),
?>
See Also

locale_code

Description

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:

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.

Examples
<?PHP
'<setting>' => 'en_GB',
'<setting>' => 'jp_JP',
?>
See Also

meta_scope_enum

Description

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:

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.

Examples
<?PHP
'<setting>' => 'extend',
'<setting>' => 'prepend',
'<setting>' => 'local',
?>
See Also

output_location_enum

Description

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:

Notes:

Examples
<?PHP
'<setting>' => 'page_bottom',
'<setting>' => 'body_top',
'<setting>' => 'navigation_top',
?>
See Also

php_callbacks

Description

One or more PHP callback function names to invoke.

This type accepts either:

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.

Examples
<?PHP
'<setting>' => 'myCallback',
'<setting>' => array(
'myCallback',
'myOtherCallback',
),
'<setting>' => NULL,
?>
See Also

php_files

Description

One or more PHP file paths to load with require_once.

This type accepts either:

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.

Examples
<?PHP
'<setting>' => 'addons/example-addon.php',
'<setting>' => array(
'addons/example-addon.php',
'addons/second-addon.php',
),
'<setting>' => NULL,
?>
See Also

resource_path

Description

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.

Examples
<?PHP
'<setting>' => 'images/favicon.png',
'<setting>' => 'style/layout.css',
'<setting>' => NULL,
?>
See Also

script_spec

Description

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:

Supported input forms:

Normalized runtime shape:
After compilation, the value is always a list of keyed pairs:

array(
array('script' => '...', 'type' => '...'),
array('script' => '...', 'type' => '...'),
...
)
Examples
<?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',
),
),
?>
See Also

sdatetime_format

Description

Date/time format specification string.

Use this type for settings that control how Nocterra renders dates and times via format_sdatetime, including:

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:

  1. 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)

  2. 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.

Examples
<?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',
?>
See Also

string

Description

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:

Examples
<?PHP
'<setting>' => 'Example',
'<setting>' => '',
?>
See Also

style_sheet_spec

Description

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:

Supported input forms:

The value is interpreted as a style sheet resource path. The MIME type defaults to text/css.

Each item is interpreted as a style sheet resource path. Each entry gets MIME type text/css.

A single entry with keys stylesheet and optionally type.

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.

Examples
<?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',
),
),
?>
See Also

timestamping_spec

Description

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:

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:

Examples
<?PHP
'<setting>' => 'images',
'<setting>' => array(
'images',
'downloads',
),
'<setting>' => array(
'excludePaths' => 'images',
),
'<setting>' => array(
'excludePaths' => array(
'images',
'downloads',
),
),
'<setting>' => array(
'excludePaths' => array(),
),
?>
See Also

url_path

Description

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:

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.

Examples
<?PHP
'<setting>' => '/',
'<setting>' => '/downloads/',
'<setting>' => '/blog/category/news/',
?>
See Also

viewport_value

Description

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.

Examples
<?PHP
'<setting>' => 'width=device-width, initial-scale=1',
'<setting>' => NULL,
?>
See Also

Sections

branding<language>

Description

$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:

See Also
Settings
branding<language>.author
Description
string | NULL $author = UNSET

Configures 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.

Examples
<?PHP
$branding = array(
'<language>' => array(
'author' => 'Example',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'author' => '',
),
);
?>
See Also
branding<language>.contentType
Description
content_type_eum | NULL $contentType = UNSET

Configures 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.

Examples
<?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,
),
);
?>
See Also
branding<language>.copyright
Description
html_inline | NULL $copyright = UNSET

Configures 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.

Examples
<?PHP
$branding = array(
'<language>' => array(
'copyright' => 'Welcome',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'copyright' => 'You are here: <SPAN class="hint">Home</SPAN>',
),
);
?>
See Also
branding<language>.description
Description
string | NULL $description = UNSET

Configures 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.

Examples
<?PHP
$branding = array(
'<language>' => array(
'description' => 'Example',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'description' => '',
),
);
?>
See Also
branding<language>.favicon
Description
resource_path | NULL $favicon = UNSET

Configures 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.

Examples
<?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,
),
);
?>
See Also
branding<language>.keywords
Description
string | NULL $keywords = UNSET

Configures 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.

Examples
<?PHP
$branding = array(
'<language>' => array(
'keywords' => 'Example',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'keywords' => '',
),
);
?>
See Also
branding<language>.logoImage
Description
resource_path | NULL $logoImage = UNSET

Configures 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.

Examples
<?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,
),
);
?>
See Also
branding<language>.logoLink
Description
string | NULL $logoLink = UNSET

Controls 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).

Examples
<?PHP
$branding = array(
'<language>' => array(
'logoLink' => 'Example',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'logoLink' => '',
),
);
?>
See Also
branding<language>.logoText
Description
string | NULL $logoText = UNSET

Configures 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.

Examples
<?PHP
$branding = array(
'<language>' => array(
'logoText' => 'Example',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'logoText' => '',
),
);
?>
See Also
branding<language>.siteImage
Description
resource_path | NULL $siteImage = UNSET

Configures 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.

Examples
<?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,
),
);
?>
See Also
branding<language>.stylesheet
Description
style_sheet_spec $stylesheet = UNSET

Configures 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.

Examples
<?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',
),
),
),
);
?>
See Also
branding<language>.subtitle
Description
html_inline | NULL $subtitle = UNSET

Configures 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.

Examples
<?PHP
$branding = array(
'<language>' => array(
'subtitle' => 'Welcome',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'subtitle' => 'You are here: <SPAN class="hint">Home</SPAN>',
),
);
?>
See Also
branding<language>.title
Description
html_inline | NULL $title = UNSET

Configures 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.

Examples
<?PHP
$branding = array(
'<language>' => array(
'title' => 'Welcome',
),
);
?>
<?PHP
$branding = array(
'<language>' => array(
'title' => 'You are here: <SPAN class="hint">Home</SPAN>',
),
);
?>
See Also

domains<domain>

Description

$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:

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>
Settings
domains<domain>.base
Description
url_path $base = UNSET MANDATORY

Required. 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.

Examples
<?PHP
$domains = array(
'<domain>' => array(
'base' => '/',
),
);
?>
<?PHP
$domains = array(
'<domain>' => array(
'base' => '/downloads/',
),
);
?>
<?PHP
$domains = array(
'<domain>' => array(
'base' => '/blog/category/news/',
),
);
?>
domains<domain>.cookieDomain
Description
host_name $cookieDomain = UNSET

Cookie 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.

Examples
<?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',
),
);
?>
See Also
domains<domain>.defaultLanguage
Description
language $defaultLanguage = UNSET

Default 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.

Examples
<?PHP
$domains = array(
'<domain>' => array(
'defaultLanguage' => 'en',
),
);
?>
<?PHP
$domains = array(
'<domain>' => array(
'defaultLanguage' => 'nl',
),
);
?>
domains<domain>.host
Description
host_name $host = UNSET

Required. The canonical host name for this domain entry.

This value is used by the compiler to derive base URLs for link generation and placeholders.

Examples
<?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',
),
);
?>
domains<domain>.languages
Description
language_spec $languages = UNSET

Defines 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.

Examples
<?PHP
$domains = array(
'<domain>' => array(
'languages' => 'en',
),
);
?>
<?PHP
$domains = array(
'<domain>' => array(
'languages' => array('nl', 'en'),
),
);
?>
See Also
domains<domain>.priority
Description
integer $priority = UNSET

Optional 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.

Examples
<?PHP
$domains = array(
'<domain>' => array(
'priority' => 7,
),
);
?>
<?PHP
$domains = array(
'<domain>' => array(
'priority' => NULL,
),
);
?>

environment

Description

$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.

Settings
environment.authorSeparator
Description
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.

Examples
<?PHP
$environment = array(
'authorSeparator' => 'Example',
);
?>
<?PHP
$environment = array(
'authorSeparator' => '',
);
?>
See Also
environment.author
Description
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'.

Examples
<?PHP
$environment = array(
'author' => 'extend',
);
?>
<?PHP
$environment = array(
'author' => 'prepend',
);
?>
<?PHP
$environment = array(
'author' => 'local',
);
?>
See Also
environment.canonicalLanguage
Description
language | NULL $canonicalLanguage = UNSET

Select 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

Examples
<?PHP
$environment = array(
'canonicalLanguage' => 'en',
);
?>
<?PHP
$environment = array(
'canonicalLanguage' => 'nl',
);
?>
environment.data_storeLevels
Description
integer $data_storeLevels = 1

Controls 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)

  1. 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/api
  2. data_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/api
  3. data_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-edit

Notes:

  • 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.

Examples
<?PHP
$environment = array(
'data_storeLevels' => 7,
);
?>
<?PHP
$environment = array(
'data_storeLevels' => NULL,
);
?>
See Also
environment.data_store
Description
data_store_enum $data_store = UNSET MANDATORY

Selects 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):

  1. 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_404
  2. Per-language directories (locale_directory)
    Typical URLs:

    • /

    • /about

    • /contact

    Example /data tree:

    /data/
    en/
    _
    about
    contact
    404
    nl/
    _
    over
    contact
    404
  3. Section 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.

Examples
<?PHP
$environment = array(
'data_store' => 'locale_prefix',
);
?>
<?PHP
$environment = array(
'data_store' => 'locale_directory',
);
?>
<?PHP
$environment = array(
'data_store' => 'locale_prefix_menu',
);
?>
See Also
environment.descriptionSeparator
Description
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.

Examples
<?PHP
$environment = array(
'descriptionSeparator' => 'Example',
);
?>
<?PHP
$environment = array(
'descriptionSeparator' => '',
);
?>
See Also
environment.description
Description
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'.

Examples
<?PHP
$environment = array(
'description' => 'extend',
);
?>
<?PHP
$environment = array(
'description' => 'prepend',
);
?>
<?PHP
$environment = array(
'description' => 'local',
);
?>
See Also
environment.dynamicMaxAge
Description
duration_seconds $dynamicMaxAge = UNSET MANDATORY

Controls 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).

Examples
<?PHP
$environment = array(
'dynamicMaxAge' => 300,
);
?>
<?PHP
$environment = array(
'dynamicMaxAge' => 3600,
);
?>
<?PHP
$environment = array(
'dynamicMaxAge' => 86400,
);
?>
<?PHP
$environment = array(
'dynamicMaxAge' => 24*60*60,
);
?>
See Also
environment.generateDynamic
Description
php_callbacks | NULL $generateDynamic = NULL

Registers 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).

Examples
<?PHP
$environment = array(
'generateDynamic' => 'myCallback',
);
?>
<?PHP
$environment = array(
'generateDynamic' => array(
'myCallback',
'myOtherCallback',
),
);
?>
<?PHP
$environment = array(
'generateDynamic' => NULL,
);
?>
See Also
environment.generateStatic
Description
php_callbacks | NULL $generateStatic = NULL

Registers 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.

Examples
<?PHP
$environment = array(
'generateStatic' => 'myCallback',
);
?>
<?PHP
$environment = array(
'generateStatic' => array(
'myCallback',
'myOtherCallback',
),
);
?>
<?PHP
$environment = array(
'generateStatic' => NULL,
);
?>
See Also
environment.keywordsSeparator
Description
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.

Examples
<?PHP
$environment = array(
'keywordsSeparator' => 'Example',
);
?>
<?PHP
$environment = array(
'keywordsSeparator' => '',
);
?>
See Also
environment.keywords
Description
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'.

Examples
<?PHP
$environment = array(
'keywords' => 'extend',
);
?>
<?PHP
$environment = array(
'keywords' => 'prepend',
);
?>
<?PHP
$environment = array(
'keywords' => 'local',
);
?>
See Also
environment.loadAddons
Description
php_files | NULL $loadAddons = NULL

Loads 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.

Examples
<?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,
);
?>
See Also
environment.rdfa
Description
boolean $rdfa = FALSE

Enable 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”.

Examples
<?PHP
$environment = array(
'rdfa' => TRUE,
);
?>
<?PHP
$environment = array(
'rdfa' => FALSE,
);
?>
<?PHP
$environment = array(
'rdfa' => 1,
);
?>
<?PHP
$environment = array(
'rdfa' => 0,
);
?>
environment.redirectMaxAge
Description
duration_seconds $redirectMaxAge = UNSET MANDATORY

Controls 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.

Examples
<?PHP
$environment = array(
'redirectMaxAge' => 300,
);
?>
<?PHP
$environment = array(
'redirectMaxAge' => 3600,
);
?>
<?PHP
$environment = array(
'redirectMaxAge' => 86400,
);
?>
<?PHP
$environment = array(
'redirectMaxAge' => 24*60*60,
);
?>
See Also
environment.responseMaxAge
Description
duration_seconds $responseMaxAge = UNSET MANDATORY

Controls 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.

Examples
<?PHP
$environment = array(
'responseMaxAge' => 300,
);
?>
<?PHP
$environment = array(
'responseMaxAge' => 3600,
);
?>
<?PHP
$environment = array(
'responseMaxAge' => 86400,
);
?>
<?PHP
$environment = array(
'responseMaxAge' => 24*60*60,
);
?>
See Also
environment.sitemapCacheMaxAge
Description
duration_seconds $sitemapCacheMaxAge = 24*60*60

Controls 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).

Examples
<?PHP
$environment = array(
'sitemapCacheMaxAge' => 300,
);
?>
<?PHP
$environment = array(
'sitemapCacheMaxAge' => 3600,
);
?>
<?PHP
$environment = array(
'sitemapCacheMaxAge' => 86400,
);
?>
<?PHP
$environment = array(
'sitemapCacheMaxAge' => 24*60*60,
);
?>
See Also
environment.titleSeparator
Description
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 ' | '.

Examples
<?PHP
$environment = array(
'titleSeparator' => 'Example',
);
?>
<?PHP
$environment = array(
'titleSeparator' => '',
);
?>
See Also
environment.title
Description
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'.

Examples
<?PHP
$environment = array(
'title' => 'extend',
);
?>
<?PHP
$environment = array(
'title' => 'prepend',
);
?>
<?PHP
$environment = array(
'title' => 'local',
);
?>
See Also
environment.viewport
Description
viewport_value $viewport = UNSET

Controls 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">
Examples
<?PHP
$environment = array(
'viewport' => 'width=device-width, initial-scale=1',
);
?>
<?PHP
$environment = array(
'viewport' => NULL,
);
?>

environment.imageScaler

Description

$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).

See Also
Settings
environment.imageScaler.EtagIncludeiNode
Description
boolean $EtagIncludeiNode = FALSE

Control 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.

Examples
<?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,
),
);
?>
See Also
environment.imageScaler.sizes
Description
integer_list $sizes = UNSET MANDATORY

List 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.

Examples
<?PHP
$environment = array(
'imageScaler' => array(
'sizes' => array(
320,
640,
1280
),
),
);
?>
See Also
environment.imageScaler.xSendFile
Description
boolean $xSendFile = FALSE

Enable 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.

Examples
<?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,
),
);
?>
See Also

environment.imageSets<imageset>

Description

$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:

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:

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:

The behavior of an image set is configured by its nested settings (override target, version source, width set, rendering hints and default width).

See Also
Settings
environment.imageSets<imageset>.defaultWidth
Description
integer $defaultWidth = UNSET

Default 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.

Examples
<?PHP
$environment = array(
'imageSets' => array(
'<imageset>' => array(
'defaultWidth' => 7,
),
),
);
?>
<?PHP
$environment = array(
'imageSets' => array(
'<imageset>' => array(
'defaultWidth' => NULL,
),
),
);
?>
See Also
environment.imageSets<imageset>.fileWidths
Description
integer_list $fileWidths = UNSET

List 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.

Examples
<?PHP
$environment = array(
'imageSets' => array(
'<imageset>' => array(
'fileWidths' => array(
320,
640,
1280
),
),
),
);
?>
See Also
environment.imageSets<imageset>.imageOverride
Description
resource_path $imageOverride = UNSET

Override 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.

Examples
<?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,
),
),
);
?>
See Also
environment.imageSets<imageset>.renderHints
Description
string $renderHints = UNSET

Rendering 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.

Examples
<?PHP
$environment = array(
'imageSets' => array(
'<imageset>' => array(
'renderHints' => 'Example',
),
),
);
?>
<?PHP
$environment = array(
'imageSets' => array(
'<imageset>' => array(
'renderHints' => '',
),
),
);
?>
See Also
environment.imageSets<imageset>.timestampBase
Description
integer $timestampBase = UNSET

Control 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.

Examples
<?PHP
$environment = array(
'imageSets' => array(
'<imageset>' => array(
'timestampBase' => 7,
),
),
);
?>
<?PHP
$environment = array(
'imageSets' => array(
'<imageset>' => array(
'timestampBase' => NULL,
),
),
);
?>
See Also

languages<language>

Description

$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:

Optional but commonly used:

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.

Settings
languages<language>.date_l
Description
sdatetime_format $date_l = UNSET

Long 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%

Examples
<?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',
),
);
?>
See Also
languages<language>.date_m
Description
sdatetime_format $date_m = UNSET

Medium 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%

Examples
<?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',
),
);
?>
See Also
languages<language>.date_s
Description
sdatetime_format $date_s = UNSET

Short 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%

Examples
<?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',
),
);
?>
See Also
languages<language>.image
Description
resource_path $image = UNSET

Optional 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.

Examples
<?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,
),
);
?>
See Also
languages<language>.locale
Description
locale_code $locale = UNSET

Locale 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.

Examples
<?PHP
$languages = array(
'<language>' => array(
'locale' => 'en_GB',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'locale' => 'jp_JP',
),
);
?>
languages<language>.name
Description
string $name = UNSET

Display 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.

Examples
<?PHP
$languages = array(
'<language>' => array(
'name' => 'Example',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'name' => '',
),
);
?>
See Also
languages<language>.text
Description
string $text = UNSET

Optional 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.

Examples
<?PHP
$languages = array(
'<language>' => array(
'text' => 'Example',
),
);
?>
<?PHP
$languages = array(
'<language>' => array(
'text' => '',
),
);
?>
See Also
languages<language>.time_l
Description
sdatetime_format $time_l = UNSET

Long 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.

Examples
<?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',
),
);
?>
See Also
languages<language>.time_m
Description
sdatetime_format $time_m = UNSET

Medium 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%

Examples
<?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',
),
);
?>
See Also
languages<language>.time_s
Description
sdatetime_format $time_s = UNSET

Short 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%

Examples
<?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',
),
);
?>
See Also

page<language>

Description

$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:

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:

See Also
Settings
page<language>.contentSecurityPolicy
Description
content_security_policy_spec $contentSecurityPolicy = UNSET

Content 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.

Examples
<?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'",
),
);
?>
See Also
page<language>.script
Description
script_spec $script = UNSET

Configures 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.

Examples
<?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',
),
),
),
);
?>
See Also
page<language>.timestamping
Description
timestamping_spec $timestamping = UNSET

Configures 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.

Examples
<?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(),
),
),
);
?>
See Also

page<language>.body

Description

$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:

Values such as prologue and epilogue are emitted as-is by Nocterra and may contain trusted HTML.

See Also
Settings
page<language>.body.ariaLabelledBy
Description
string | NULL $ariaLabelledBy = NULL

Optional 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.

Examples
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'ariaLabelledBy' => 'Example',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'ariaLabelledBy' => '',
),
),
);
?>
See Also
page<language>.body.ariaLabel
Description
string | NULL $ariaLabel = NULL

Optional 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.

Examples
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'ariaLabel' => 'Example',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'ariaLabel' => '',
),
),
);
?>
See Also
page<language>.body.class
Description
string $class = 'body'

CSS class name for the Nocterra page body container (<DIV class="..."></DIV>).

Examples
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'class' => 'Example',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'class' => '',
),
),
);
?>
See Also
page<language>.body.epilogue
Description
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.).

Examples
<?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>',
),
),
);
?>
See Also
page<language>.body.prologue
Description
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.).

Examples
<?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>',
),
),
);
?>
See Also
page<language>.body.role
Description
string | NULL $role = NULL

Optional 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.

Examples
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'role' => 'Example',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'body' => array(
'role' => '',
),
),
);
?>
See Also

page<language>.breadcrumbs

Description

$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:

See Also
Settings
page<language>.breadcrumbs.epilogue
Description
html_inline $epilogue = ''

Text emitted after the breadcrumb trail.

This value is emitted as-is (trusted HTML).

Examples
<?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>',
),
),
);
?>
See Also
page<language>.breadcrumbs.minLevel
Description
integer $minLevel = 1

Minimum path depth required before breadcrumbs are emitted.

If the current request path has fewer components than minLevel, the breadcrumb block is not emitted.

Examples
<?PHP
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'minLevel' => 7,
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'minLevel' => NULL,
),
),
);
?>
See Also
page<language>.breadcrumbs.nonLinkText
Description
boolean $nonLinkText = TRUE

Controls 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.

Examples
<?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,
),
),
);
?>
See Also
page<language>.breadcrumbs.prologue
Description
html_inline $prologue = ''

Text emitted before the breadcrumb trail.

This value is emitted as-is (trusted HTML).

Examples
<?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>',
),
),
);
?>
See Also
page<language>.breadcrumbs.separator
Description
html_inline $separator = ', '

Separator emitted between breadcrumb items.

This value is emitted as-is (trusted HTML).

Examples
<?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>',
),
),
);
?>
See Also
page<language>.breadcrumbs.subSeparator
Description
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).

Examples
<?PHP
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'subSeparator' => 'Example',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'breadcrumbs' => array(
'subSeparator' => '',
),
),
);
?>
See Also

page<language>.footer

Description

$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:

The footer is typically emitted after the navigation block and before the page-level epilogue output.

See Also
Settings
page<language>.footer.columns
Description
footer_columns_spec $columns = UNSET

Defines 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.

Examples
<?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',
),
),,
),
),
);
?>
See Also
page<language>.footer.epilogue
Description
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.).

Examples
<?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>',
),
),
);
?>
See Also
page<language>.footer.prologue
Description
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.).

Examples
<?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>',
),
),
);
?>
See Also
page<language>.footer.showHeader
Description
boolean $showHeader = true

Controls 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.

Examples
<?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,
),
),
);
?>
See Also

page<language>.languageSelector

Description

$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.

See Also
Settings
page<language>.languageSelector.location
Description
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.

Examples
<?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',
),
),
);
?>
See Also
page<language>.languageSelector.order
Description
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.

Examples
<?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'),,
),
),
);
?>
See Also
page<language>.languageSelector.showCurrent
Description
boolean $showCurrent = false

When 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.

Examples
<?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,
),
),
);
?>
See Also
page<language>.languageSelector.showNearest
Description
boolean $showNearest = false

Controls 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.

Examples
<?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,
),
),
);
?>
See Also

page<language>.navigation

Description

$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:

Values such as prologue and epilogue are emitted as-is by the renderer and may contain trusted HTML.

See Also
Settings
page<language>.navigation.ariaLabelledBy
Description
string | NULL $ariaLabelledBy = NULL

Optional 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.

Examples
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'ariaLabelledBy' => 'Example',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'ariaLabelledBy' => '',
),
),
);
?>
See Also
page<language>.navigation.ariaLabel
Description
string | NULL $ariaLabel = NULL

Optional 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.

Examples
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'ariaLabel' => 'Example',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'ariaLabel' => '',
),
),
);
?>
See Also
page<language>.navigation.class
Description
string $class = 'navigation'

CSS class name for the navigation container element.

Examples
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'class' => 'Example',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'class' => '',
),
),
);
?>
See Also
page<language>.navigation.epilogue
Description
html_block $epilogue = ''

Optional content emitted at the end of the navigation block.

This value is emitted as-is and may contain trusted HTML.

Examples
<?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>',
),
),
);
?>
See Also
page<language>.navigation.location
Description
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

Examples
<?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',
),
),
);
?>
See Also
page<language>.navigation.prologue
Description
html_block $prologue = ''

Optional content emitted at the start of the navigation block.

This value is emitted as-is and may contain trusted HTML.

Examples
<?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>',
),
),
);
?>
See Also
page<language>.navigation.role
Description
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.

Examples
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'role' => 'Example',
),
),
);
?>
<?PHP
$page = array(
'<language>' => array(
'navigation' => array(
'role' => '',
),
),
);
?>
See Also

page<language>.page

Description

$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>:

See Also
Settings
page<language>.page.epilogue
Description
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.

Examples
<?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>',
),
),
);
?>
See Also
page<language>.page.prologue
Description
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.

Examples
<?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>',
),
),
);
?>
See Also

Settings

EtagIncludeiNode

environment.imageScaler.EtagIncludeiNode
boolean $EtagIncludeiNode = FALSE

Control whether the generated Etag includes the file i-node.

ariaLabel

page<language>.body.ariaLabel
string | NULL $ariaLabel = NULL

Optional aria-label for the Nocterra page body container.

page<language>.navigation.ariaLabel
string | NULL $ariaLabel = NULL

Optional aria-label for the navigation container.

ariaLabelledBy

page<language>.body.ariaLabelledBy
string | NULL $ariaLabelledBy = NULL

Optional aria-labelledby for the Nocterra page body container.

page<language>.navigation.ariaLabelledBy
string | NULL $ariaLabelledBy = NULL

Optional aria-labelledby for the navigation container.

author

branding<language>.author
string | NULL $author = UNSET

Configures the global author value for the current branding language.

environment.author
meta_scope_enum $author = 'extend'

Determines how the final author metadata is assembled for the HTML output.

authorSeparator

environment.authorSeparator
string $authorSeparator = ', '

Separator used when Nocterra concatenates local and site-wide author metadata.

base

domains<domain>.base
url_path $base = UNSET MANDATORY

Required. The base path prefix for the site on this host.

canonicalLanguage

environment.canonicalLanguage
language | NULL $canonicalLanguage = UNSET

Select the canonical language used when generating certain canonical-style URLs.

class

page<language>.body.class
string $class = 'body'

CSS class name for the Nocterra page body container (<DIV class="..."></DIV>).

page<language>.navigation.class
string $class = 'navigation'

CSS class name for the navigation container element.

columns

page<language>.footer.columns
footer_columns_spec $columns = UNSET

Defines the footer column layout and content.

contentSecurityPolicy

page<language>.contentSecurityPolicy
content_security_policy_spec $contentSecurityPolicy = UNSET

Content Security Policy configuration for the current page language.

contentType

branding<language>.contentType
content_type_eum | NULL $contentType = UNSET

Configures the default structured content type for pages under the current branding language.

cookieDomain

domains<domain>.cookieDomain
host_name $cookieDomain = UNSET

Cookie domain used by the site.

copyright

branding<language>.copyright
html_inline | NULL $copyright = UNSET

Configures the copyright line for the current branding language.

data_store

environment.data_store
data_store_enum $data_store = UNSET MANDATORY

Selects the data store mapping mode used to locate page data files under /data.

data_storeLevels

environment.data_storeLevels
integer $data_storeLevels = 1

Controls how the requested URL path is mapped to directories and filenames under /data.

date_l

languages<language>.date_l
sdatetime_format $date_l = UNSET

Long date format for language <language>.

date_m

languages<language>.date_m
sdatetime_format $date_m = UNSET

Medium date format for language <language>.

date_s

languages<language>.date_s
sdatetime_format $date_s = UNSET

Short date format for language <language>.

defaultLanguage

domains<domain>.defaultLanguage
language $defaultLanguage = UNSET

Default language for this host.

defaultWidth

environment.imageSets<imageset>.defaultWidth
integer $defaultWidth = UNSET

Default width (in pixels) used for the primary emitted URL of this image set.

description

branding<language>.description
string | NULL $description = UNSET

Configures the global description value for the current branding language.

environment.description
meta_scope_enum $description = 'local'

Determines how the final description metadata is assembled for the HTML output.

descriptionSeparator

environment.descriptionSeparator
string $descriptionSeparator = ', '

Separator used when Nocterra concatenates local and site-wide description metadata.

dynamicMaxAge

environment.dynamicMaxAge
duration_seconds $dynamicMaxAge = UNSET MANDATORY

Controls the cache lifetime (in seconds) for responses that contain dynamic pair placeholders.

epilogue

page<language>.body.epilogue
html_block $epilogue = ''

Optional content emitted at the end of the Nocterra page body container.

page<language>.breadcrumbs.epilogue
html_inline $epilogue = ''

Text emitted after the breadcrumb trail.

page<language>.footer.epilogue
html_block $epilogue = ''

Optional footer epilogue fragment.

page<language>.navigation.epilogue
html_block $epilogue = ''

Optional content emitted at the end of the navigation block.

page<language>.page.epilogue
html_block $epilogue = ''

Optional content output near the end of the HTML <BODY>, after Nocterra outputs the footer and closing page structure.

favicon

branding<language>.favicon
resource_path | NULL $favicon = UNSET

Configures the favicon resource for the current branding language.

fileWidths

environment.imageSets<imageset>.fileWidths
integer_list $fileWidths = UNSET

List of available file widths (in pixels) for this image set.

generateDynamic

environment.generateDynamic
php_callbacks | NULL $generateDynamic = NULL

Registers one or more callbacks that provide per-request, site-wide dynamic behavior.

generateStatic

environment.generateStatic
php_callbacks | NULL $generateStatic = NULL

Registers one or more callbacks that generate site-wide output during request rendering.

host

domains<domain>.host
host_name $host = UNSET

Required. The canonical host name for this domain entry.

image

languages<language>.image
resource_path $image = UNSET

Optional image reference for the language selector.

imageOverride

environment.imageSets<imageset>.imageOverride
resource_path $imageOverride = UNSET

Override the resource filename used for this image set.

keywords

branding<language>.keywords
string | NULL $keywords = UNSET

Configures the global keywords value for the current branding language.

environment.keywords
meta_scope_enum $keywords = 'extend'

Determines how the final keywords metadata is assembled for the HTML output.

keywordsSeparator

environment.keywordsSeparator
string $keywordsSeparator = ', '

Reserved separator setting for keywords concatenation.

languages

domains<domain>.languages
language_spec $languages = UNSET

Defines which languages are served on this domain.

loadAddons

environment.loadAddons
php_files | NULL $loadAddons = NULL

Loads additional PHP files (addons) before handling the request.

locale

languages<language>.locale
locale_code $locale = UNSET

Locale for this language.

location

page<language>.languageSelector.location
output_location_enum $location = ''

Selects where the language selector is emitted.

page<language>.navigation.location
output_location_enum $location = 'body_end'

Controls where the navigation block is emitted.

logoImage

branding<language>.logoImage
resource_path | NULL $logoImage = UNSET

Configures the logo image resource for the current branding language.

logoLink

branding<language>.logoLink
string | NULL $logoLink = UNSET

Controls whether the logo image is emitted as a link.

logoText

branding<language>.logoText
string | NULL $logoText = UNSET

Configures the alternative text for the logo image for the current branding language.

minLevel

page<language>.breadcrumbs.minLevel
integer $minLevel = 1

Minimum path depth required before breadcrumbs are emitted.

name

languages<language>.name
string $name = UNSET

Display name of the language.

nonLinkText

page<language>.breadcrumbs.nonLinkText
boolean $nonLinkText = TRUE

Controls whether intermediate non-link path parts may be emitted as plain text.

order

page<language>.languageSelector.order
language_selector_order_spec $order = 'as-is'

Controls the order of language entries in the selector.

priority

domains<domain>.priority
integer $priority = UNSET

Optional priority value used when resolving languages and domains.

prologue

page<language>.body.prologue
html_block $prologue = ''

Optional content emitted at the start of the Nocterra page body container.

page<language>.breadcrumbs.prologue
html_inline $prologue = ''

Text emitted before the breadcrumb trail.

page<language>.footer.prologue
html_block $prologue = ''

Optional footer prologue fragment.

page<language>.navigation.prologue
html_block $prologue = ''

Optional content emitted at the start of the navigation block.

page<language>.page.prologue
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.

rdfa

environment.rdfa
boolean $rdfa = FALSE

Enable or disable RDFa output.

redirectMaxAge

environment.redirectMaxAge
duration_seconds $redirectMaxAge = UNSET MANDATORY

Controls the cache lifetime (in seconds) for redirect responses generated by Nocterra.

renderHints

environment.imageSets<imageset>.renderHints
string $renderHints = UNSET

Rendering hints for responsive images, emitted as the sizes attribute.

responseMaxAge

environment.responseMaxAge
duration_seconds $responseMaxAge = UNSET MANDATORY

Controls the cache lifetime (in seconds) for normal (non-dynamic) responses.

role

page<language>.body.role
string | NULL $role = NULL

Optional role attribute for the Nocterra page body container (<DIV class="body">...</DIV>).

page<language>.navigation.role
string | NULL $role = 'navigation'

Optional role attribute for the navigation container.

script

page<language>.script
script_spec $script = UNSET

Configures one or more script resources for the current page language.

separator

page<language>.breadcrumbs.separator
html_inline $separator = ', '

Separator emitted between breadcrumb items.

showCurrent

page<language>.languageSelector.showCurrent
boolean $showCurrent = false

When enabled, include the current language in the language selector output.

showHeader

page<language>.footer.showHeader
boolean $showHeader = true

Controls whether footer column headers are displayed.

showNearest

page<language>.languageSelector.showNearest
boolean $showNearest = false

Controls what happens when the current page does not exist in a specific language.

siteImage

branding<language>.siteImage
resource_path | NULL $siteImage = UNSET

Configures the site image resource used for social meta output.

sitemapCacheMaxAge

environment.sitemapCacheMaxAge
duration_seconds $sitemapCacheMaxAge = 24*60*60

Controls the cache lifetime (in seconds) for sitemap caching.

sizes

environment.imageScaler.sizes
integer_list $sizes = UNSET MANDATORY

List of allowed target widths (in pixels) for scaled images.

stylesheet

branding<language>.stylesheet
style_sheet_spec $stylesheet = UNSET

Configures one or more stylesheets for the current branding language.

subSeparator

page<language>.breadcrumbs.subSeparator
string $subSeparator = ' - '

Separator emitted between accumulated non-link text and the next linked breadcrumb item.

subtitle

branding<language>.subtitle
html_inline | NULL $subtitle = UNSET

Configures the site subtitle for the current branding language.

text

languages<language>.text
string $text = UNSET

Optional user-facing label for this language.

time_l

languages<language>.time_l
sdatetime_format $time_l = UNSET

Long time format for language <language>.

time_m

languages<language>.time_m
sdatetime_format $time_m = UNSET

Medium time format for language <language>.

time_s

languages<language>.time_s
sdatetime_format $time_s = UNSET

Short time format for language <language>.

timestampBase

environment.imageSets<imageset>.timestampBase
integer $timestampBase = UNSET

Control cache-busting versioning for URLs emitted by this image set.

timestamping

page<language>.timestamping
timestamping_spec $timestamping = UNSET

Configures resource timestamping exclusions for the current page language.

title

branding<language>.title
html_inline | NULL $title = UNSET

Configures the site title for the current branding language.

environment.title
meta_scope_enum $title = 'prepend'

Determines how the final title metadata is assembled for the HTML output.

titleSeparator

environment.titleSeparator
string $titleSeparator = ' | '

Separator used when Nocterra concatenates local and site-wide title metadata.

viewport

environment.viewport
viewport_value $viewport = UNSET

Controls the HTML <META name="viewport"> tag emitted in the document <HEAD>.

xSendFile

environment.imageScaler.xSendFile
boolean $xSendFile = FALSE

Enable server-assisted file delivery using the X-Sendfile response header.