Skip to the content
Documentation
Help Start
Reading in:
  • German: 9,059 of 9,059 pages
About the help in other languages
All help pages

Several sites: siteaccesses

Serve two public sites and one administration from one installation, matched by host name, each with its own design, start node, language and var directory, with the settings of each siteaccess and the checks that prove…

Download as PDF

Address: https://doc.exponential.earth/exphelp/viewer/examples/cookbook/multisite-siteaccess.md

On this page

Several sites: siteaccesses

A siteaccess is a named set of settings that applies to a request: which design, which part of the content tree, which language, whether visitors must sign in. One installation, one database, many siteaccesses. You set up:

Warning

.htaccess slows down every request. When .htaccess files are enabled (AllowOverride anything but None), let alone used, Apache looks for them and reads and evaluates them on every request, in every directory of the path, and page loading times go up drastically (measured). The only real fix is to switch the feature off for the virtual host: AllowOverride None in the HTTPS virtual host, and the rules in the virtual host's own configuration as mod_rewrite rules. That is far faster in production speed tests and well worth the time it takes to optimize a production configuration. Switch over right away: copy the rules of the example HTTPS virtual host into your virtual host (with the static cache, also staticcache_offload.conf), set AllowOverride None, run apachectl configtest, reload Apache and test the site. The same rules for other servers: nginx, LiteSpeed, Caddy, IIS, Velocity (built in); where virtual host rules go in a control panel: Plesk, cPanel, DirectAdmin, ISPConfig. On LiteSpeed or OpenLiteSpeed, the server's own page cache can also answer anonymous visitors and crawlers without PHP: Page caching with LiteSpeed and OpenLiteSpeed.

SiteaccessHostWhat it is
site_awww.example.comthe first public site, the subtree Site A
site_bwww.example.orgthe second public site, the subtree Site B, in German
adminadmin.example.comthe administration of both

Prerequisites: a working installation with the siteaccess admin; the three host names point to the server and the web server answers for all of them with the same document root (Web server examples); two folders Site A and Site B below the root of the content tree (note their node ids, here 60 and 61).

1. The list and the match

Siteaccess selection is installation-wide, so it goes in the global override, settings/override/site.ini.append.php (never committed: it also holds the database password):

<?php /* #?ini charset="utf-8"?

[SiteSettings]
DefaultAccess=site_a

[SiteAccessSettings]
AvailableSiteAccessList[]
AvailableSiteAccessList[]=site_a
AvailableSiteAccessList[]=site_b
AvailableSiteAccessList[]=admin
# Siteaccesses that share this database (the administration shows and clears their caches)
RelatedSiteAccessList[]
RelatedSiteAccessList[]=site_a
RelatedSiteAccessList[]=site_b
RelatedSiteAccessList[]=admin
# Choose the siteaccess by the host name only
MatchOrder=host
HostMatchType=map
HostMatchMapItems[]
HostMatchMapItems[]=www.example.com;site_a
HostMatchMapItems[]=www.example.org;site_b
HostMatchMapItems[]=admin.example.com;admin

*/ ?>
  • MatchOrder lists the probes tried in order: uri (the first segment of the path, /site_b/...), host, host_uri (host and segment together, HostUriMatchMapItems[]=example.com;de;site_de), port, servervar. The shipped default is uri;host;port.
  • With nothing matched, DefaultAccess answers.
  • HostMatchMethod=start (or ;start as a fourth field of an entry) also matches test hosts that begin with the name, such as www.example.com.test.local; see Siteaccess by host prefix.

2. The settings of each siteaccess

Each siteaccess has a directory settings/siteaccess/<name>/. What differs per site goes there.

settings/siteaccess/site_a/site.ini.append.php:

<?php /* #?ini charset="utf-8"?

[SiteSettings]
SiteName=Example A
SiteURL=www.example.com
DefaultPage=/content/view/full/60
IndexPage=/content/view/full/60

[SiteAccessSettings]
RequireUserLogin=false
# The URL alias of Site A's folder is not repeated in every address
PathPrefix=Site-A

[DesignSettings]
SiteDesign=mysite
AdditionalSiteDesignList[]
AdditionalSiteDesignList[]=base

[RegionalSettings]
Locale=eng-US
ContentObjectLocale=eng-US
SiteLanguageList[]
SiteLanguageList[]=eng-US

[FileSettings]
VarDir=var/site_a

*/ ?>

settings/siteaccess/site_a/content.ini.append.php (the root of menus and of fetch with no parent):

<?php /* #?ini charset="utf-8"?

[NodeSettings]
RootNode=60

*/ ?>

settings/siteaccess/site_b/ is the same with SiteName=Example B, SiteURL=www.example.org, node 61, PathPrefix=Site-B, VarDir=var/site_b, and German first:

[RegionalSettings]
Locale=ger-DE
ContentObjectLocale=ger-DE
SiteLanguageList[]
SiteLanguageList[]=ger-DE
SiteLanguageList[]=eng-US

SiteLanguageList[] is the order in which content languages are shown; the languages must exist (Setup > Languages). The siteaccess admin keeps its own settings; add SiteLanguageList[] for both languages there.

VarDir per site keeps the caches and the storage of each site apart. To put all their logs and caches in trees of their own with one line each, use LogVarDir, CacheVarDir and INICacheDir=site in the global override: Logs, INI cache and expiry timestamps per site. With CacheVarDir, the web server must also serve the public caches below it: enable the commented var_cache rule of .htaccess_root (or the matching rule of your server's example). Do that in your copy, .htaccess (put into place with ./console exp:setup:htaccess --apply), never in the template. From then on your .htaccess differs from .htaccess_root: after an upgrade, ./console exp:setup:htaccess shows that line among the differences and refuses to copy without --force; after --force --apply, enable the rule again (Setting up .htaccess and config.php from the console).

Settings carried by an extension. A site extension can ship extension/<ext>/settings/siteaccess/<name>/ instead, so the settings are in version control; see Per-site settings inside extensions.

3. Clear and check

php bin/php/ezcache.php --clear-tag=ini --allow-root-user
./console exp:ini get site.ini/SiteSettings/SiteName -s site_b --allow-root-user
curl -sI https://www.example.org/ | head -1

Expected: Example B, and HTTP/... 200 (or a redirect to the start page). Each site shows its own subtree, in its own language; https://admin.example.com/ asks for a sign-in. Under Velocity, restart it after a siteaccess change (./console exp:velocity restart --allow-root-user): its workers hold the settings in memory.

On the command line every script takes the siteaccess with -s (--siteaccess): php runcronjobs.php -s site_b frequent --allow-root-user.

Checked for this page (2026-10-18): every setting named exists in the shipped settings/site.ini or settings/content.ini with the meaning described; the host map and its methods are those of doc/eng-us/features/6.0/siteaccess-host-and-language-matching.md. The configuration was not applied to a site for this page.

Common mistakes

SymptomCause
Every host shows the same siteMatchOrder does not contain host, or the INI cache; the web server rewrites the host
A redirect loop on the administration hostthe host is not in HostMatchMapItems[]; DefaultAccess answers and asks for a sign-in somewhere else
A siteaccess is ignoredit is not in AvailableSiteAccessList[], or its directory name differs
Links point to the other hostSiteURL of the siteaccess; for links between sites, ezurl with a full address or the language switcher
exp:ini get ... -s shows the global valuethe setting is in the wrong directory, or in the override file, which wins over the siteaccess

Derived from

  • settings/site.ini ([SiteAccessSettings], [SiteSettings], [DesignSettings], [RegionalSettings], [FileSettings])
  • settings/content.ini ([NodeSettings] RootNode), settings/siteaccess/mysite/site.ini.append
  • doc/eng-us/features/6.0/siteaccess-host-and-language-matching.md, doc/eng-us/features/6.0/multi-site-log-and-cache-paths.md

Something wrong on this page? Report an error

Documentation license

This documentation is free documentation, licensed under the GNU Free Documentation License 1.3 or later.

Exponential Copyright © 1998-2026 Exponential Foundation and 7x