Since TYPO3 6.2 it is possible to use an environment variable for the webserver. It is called “TYPO3_CONTEXT”. The aim is to ease distinguishung and configuring the different contexts, in which a website can live. This post will give you an overview what a context is, what are the default contextes and how to configure them for your webserver.
A context is an environment, in which your tool is run. Think of a car, which is run on
- a highway
- a interstate and
- city street
To each of them, other restrictions apply, mainly the wanted (aka regulated) top speed. If you do not want to control it manually, you tell the car “I am in the environment ‘interstate'”, and it would not speed up above 100 km/h. OK, this is future, but will happen with assisted driving.
Now transfer this thought to a webserver environment. Dependent on the webserver environment where TYPO3 is run, it will behave differently or use other resources. An example is the database access … if you are using several stages, each stage must have access to a different database or you would like to set special debug settings to the different installations.
Another use case is the TypoScript configuration. In many installations there are configurations like „config.absRefPrefix“ oder „config.baseUrl“ … especially those two defer between the various instances. Or, if you do not use version control with a branching model, you can use the context to (de-)activate features / snippets.
Available Contexts
TYPO3 supports the main contexts „Production“, „Development“ and „Testing“. If you need more contexts, sub-contexts must be used. A sub-context is set if a „/„ and a arbitrary string is appended to the main context. So you will end up with „Production/Live“, “Production/Stage“ or „Development/Local“.
Setting the TYPO3_CONTEXT
Basically the TYPO3_CONTEXT is just an environment variable, which many of you may know from the console. Usually an environment variable is set with the following command:
export TYPO3_CONTEXT=my_value
But this simple command only works for the session and the user, who is currently logged in. Technically it is also possible to set it at each login or define it for the webserver user or system wide. But this requires extended permissions on the system like root permissions. All shared hosters will deny these permissions (hopefully).
But the concept of an environment variable is also available within the webserver Apache. The two directives are „SetEnv“ and „SetEnvIf“. As you can imagine the “SetEnv” part is a short hand for “Set Environment Variable”.
Using „SetEnv“ the environment variable is set once. It cannot be overwritten by a later directive. The first one counts. I do not recommend its usage, since it reduces flexibility.
The better and more flexible alternative is „SetEnvIf“. It allows to set the environment variable dependent on several attributes.
The directive „SetEnvIf“ takes three arguments
- the connection attribute, e.g. Host
- a regular expression, against which the attribute is evaluated
- the environment variable itsself
SetEnvIf Host „.*“ TYPO3_CONTEXT=Development/Local SetEnvIf Host „www.\.my-live-domain\.de“ TYPO3_CONTEXT=Production/Live SetEnvIf Host „my-testing.host“ TYPO3_CONTEXT=Testing
Regarding the TYPO3_CONTEXT probably the „Host“ attribute, you will use in most cases. The first line of the example sets a default value, which will be overwritten by later statements if the condition is met.
Both directives “SetEnv” and “SetEnvIf” can be set in the server config, the virtual host and the directory configuration, which are not available to most of us. But they can also be used within the htaccess file, which is available with most (all?) shared hosters. Another advantage of the htaccess is that it can be used under version control and can be tracked together with the rest of the project.
For more details have a look at the Apache documentation at “https://httpd.apache.org/docs/current/mod/mod_setenvif.html#setenvif“.
Using the TYPO3_CONTEXT in TypoScript
In TypoScript the TYPO3_CONTEXT is available as „applicationContext“. It compares the current TYPO3_CONTEXT to the given value. The most easiest case is to compare it to a „normal“ value .
[applicationContext = Production/Stage] config { absRefPrefix = https://stage.my-live-domain.com baseURL = https://stage.my-live-domain.com } [end]
The value can also be a regular expression so that more than just one single context can be matched. In order to use a regular expression it must be wrapped by „/„, like you can see in the following example
[applicationContext = /^Development\/Preview\/d+$/] config { compressJS = 0 concatenateJS = 0 } [end]
As with any other TypoScript condition, it is possible to combine it with any other condition.
Using the TYPO3_CONTEXT in PHP-Code
Furthermore it is possible to use the TYPO3_CONTEXT environment variable within PHP code. It is available everywhere in the code. And with everywhere, I mean everywhere. Even in the file AdditionalConfiguration.php the context is usable with the following statement:
\TYPO3\CMS\Core\Utility\GeneralUtility::getApplicationContext()
It returns the current application context. According to the result, different values can be set:
switch (\TYPO3\CMS\Core\Utility\GeneralUtility::getApplicationContext()) { case 'Development': $GLOBALS['TYPO3_CONF_VARS']['SYS']['displayErrors'] = 1; $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask'] = '*'; break; case 'Production/Staging': $GLOBALS['TYPO3_CONF_VARS']['SYS']['displayErrors'] = 0; $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask'] = '192.168.1.*'; break; default: $GLOBALS['TYPO3_CONF_VARS']['SYS']['displayErrors'] = 0; $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask'] = '127.0.0.1'; }
Another use case is the setting of database access data. There is no need any more to set them manually in a file, which is not available in version control and thus error prone.
Conclusion
Setting and using the TYPO3_CONTEXT is easy to set and easy to use. As most (all ?) shared hosters are supporting it via the htaccess file there is no excuse to do not use it.
What are your experiences? Do you use it with nginx? If yes, do you have any documentation / blog post at hand?