<p>It transpires that the problem actually relates to some seemingly undocumented behaviour of the <code>{% exit %}</code> call.</p>
<p>When the <code>ENVIRONMENT</code> .env config is set to <code>dev</code> this appears to flush the buffer and terminate processing, but in <code>staging</code> or <code>production</code> mode, it appears to simply stop processing. (Even manually calling <code>{% flush %}</code> before <code>{% exit %}</code> doesn't appear to work.)</p>
<p>As such, it was necessary to alter the logic as follows…</p>
<pre><code>{% set maintenanceModeActive = false %}
{% if site.maintenanceMode is defined and site.maintenanceMode %}
    {% if site.maintenanceIpAddress is defined %}
        {% set currentIpAddress = craft.app.request.userIP %}
        {% if currentIpAddress != site.maintenanceIpAddress %}
            {% set maintenanceModeActive = true %}
        {% endif %}
    {% else %}
        {% set maintenanceModeActive = true %}
    {% endif %}
{% endif %}
{% if maintenanceModeActive %}
    {% include '/maintenance' %}
{% else %}
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
…
&lt;/html&gt;
{% endif %}
</code></pre>

CC BY-SA 4.0
2020-10-07T12:28:49.333Z
Good catch! By the way, the exit tag is documented but it's a Craft extension, so the documentation is on the Craft website: https://craftcms.com/docs/3.x/dev/tags.html#exit
nstCactus
CC BY-SA 4.0
2020-10-07T12:22:16.763Z
2020-10-07T13:23:05.997Z
2020-10-07T13:23:05.997Z
John Parker
<p>It looks like you're reinventing the wheel here: in Settings → General, you can toggle the site live/offline. When the site is offline, Craft serve the <em>templates/503.twig</em> templates, no matter which URL you hit.</p>
<p>You can even configure users to have access to the site, when it's offline. To do so, go to the user edit page in the control panel and then to the Preferences tab.</p>
<hr />
<p>Regarding your specific blank page issue, it's caused by a mixup between the Twig <code>include</code> function &amp; the Twig <code>include</code> tag.</p>
<h3>Function</h3>
<p>As per <a href="https://twig.symfony.com/doc/2.x/functions/include.html" rel="nofollow noreferrer">the documentation</a>:</p>
<blockquote>
<p>The include function returns the rendered content of a template.</p>
</blockquote>
<p>You then have to do something with the returned value or it is pointless.</p>
<h3>Tag</h3>
<p>The <a href="https://twig.symfony.com/doc/2.x/tags/include.html" rel="nofollow noreferrer">documentation of this tag</a> is misleading. It states that :</p>
<blockquote>
<p>The include statement includes a template and returns the rendered content of that file</p>
</blockquote>
<p>but what it really does is <strong>output</strong> the rendered content of that file.</p>
<p>In your case, you use the function but forget to output its value. To fix you're issue, you can either use output delimiters (<code>{{ include('/maintenance') }}</code>) or use the tag instead of the function (<code>{% include'/maintenance' %}</code>).</p>
<p><a href="https://twig.symfony.com/doc/2.x/tags/include.html" rel="nofollow noreferrer">The documentation of the <code>include</code> tag</a> encourages us to prefer the former:</p>
<p>As of Twig 1.12, it is recommended to use the include function instead as it provides the same features with a bit more flexibility</p>
<h1>Solution</h1>
<h1>TL;DR</h1>
<p>Use <code>{{ include('/maintenance') }}</code>.</p>

CC BY-SA 4.0
2020-10-06T14:32:24.130Z
I'm only using the free version of CraftCMS, so I don't believe I can create additional users. (It's my first site using Craft.) Any thoughts as to why my code isn't working when the environment isn't set to 'dev'? It would be good to know what's going awry for future reference, even though I'm reinventing the wheel.
John Parker
CC BY-SA 4.0
2020-10-06T14:44:32.540Z
You're right, using Craft Solo, you're stuck with a single user and might not want to share your password with everyone!
Am I correct assuming the `site`is a global set having the following fields: `maintenanceMode` and `maintenanceIpAddress`?
nstCactus
CC BY-SA 4.0
2020-10-06T14:49:39.460Z
Yup. All of the necessary config variables are present and correct.
John Parker
CC BY-SA 4.0
2020-10-06T14:59:06.547Z
Can't help you much more then, your code seems fine, except what I mentioned in my comment on your question.
nstCactus
CC BY-SA 4.0
2020-10-07T12:19:02.803Z
This is a brilliantly formatted answer, but it unfortunately transpired this is issue is with the seemingly undocumented `{% exit %}` call.
John Parker
CC BY-SA 4.0
2020-10-06T14:24:52.593Z
2020-10-07T07:50:16.013Z
2020-10-07T07:50:16.013Z
nstCactus
<p>I've created a base twig template which contains some basic &quot;maintenance mode&quot; logic. This works perfectly as long as the main <code>ENVIRONMENT</code> in the .env file is set as <code>dev</code>, but fails for staging or production.</p>
<pre><code>{% if site.maintenanceMode is defined and site.maintenanceMode %}
    {% if site.maintenanceIpAddress is defined %}
        {% set currentIpAddress = craft.app.request.userIP %}
        {% if currentIpAddress != site.maintenanceIpAddress %}
            {% include('/maintenance') %}
            {% exit %}
        {% endif %}
    {% else %}
        {% include('/maintenance') %}
        {% exit %}
    {% endif %}
{% endif %}
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;…
</code></pre>
<p>Being fairly new to CraftCMS, I'm somewhat at a loss as to why this might be occurring and there's nothing in either the <code>…/storage/logs/web.log</code> file or the main nginx error log file. (In short no errors <em>appear</em> to be being thrown.)</p>
<p>I've tried flushing all of the available caches (including the template cache, etc.) and rebuilding the config, etc. to no avail.</p>

CC BY-SA 4.0
2020-10-06T14:57:22.827Z
It may not be the issue but it looks like you're mistaking the `include` Twig function (which returns the given rendered template but need to be output using `{{ include('maintenance.twig') }}`) and the `include` Twig tag (which directly outputs the rendered template: `{% include 'maintenance.twig' %}`).
nstCactus
<craft3><templating>
Twig template outputting blank page on non-"dev" environment
# Twig template outputting blank page on non-"dev" environment

(Asked by: username_0 on 2020-10-06)

I've created a base twig template which contains some basic "maintenance mode" logic. This works perfectly as long as the main ENVIRONMENT in the .env file is set as dev, but fails for staging or production.
{% if site.maintenanceMode is defined and site.maintenanceMode %}
    {% if site.maintenanceIpAddress is defined %}
        {% set currentIpAddress = craft.app.request.userIP %}
        {% if currentIpAddress != site.maintenanceIpAddress %}
            {% include('/maintenance') %}
            {% exit %}
        {% endif %}
    {% else %}
        {% include('/maintenance') %}
        {% exit %}
    {% endif %}
{% endif %}


Being fairly new to CraftCMS, I'm somewhat at a loss as to why this might be occurring and there's nothing in either the …/storage/logs/web.log file or the main nginx error log file. (In short no errors appear to be being thrown.)
I've tried flushing all of the available caches (including the template cache, etc.) and rebuilding the config, etc. to no avail.

**Tags:** craft3, templating

> **Comments:**
> **username_1**: It may not be the issue but it looks like you're mistaking the `include` Twig function (which returns the given rendered template but need to be output using `{{ include('maintenance.twig') }}`) and the `include` Twig tag (which directly outputs the rendered template: `{% include 'maintenance.twig' %}`).  

---

## 2 answers

### Answer by username_0 on 2020-10-07. Score: 1 | Accepted answer

It transpires that the problem actually relates to some seemingly undocumented behaviour of the {% exit %} call.
When the ENVIRONMENT .env config is set to dev this appears to flush the buffer and terminate processing, but in staging or production mode, it appears to simply stop processing. (Even manually calling {% flush %} before {% exit %} doesn't appear to work.)
As such, it was necessary to alter the logic as follows…
{% set maintenanceModeActive = false %}
{% if site.maintenanceMode is defined and site.maintenanceMode %}
    {% if site.maintenanceIpAddress is defined %}
        {% set currentIpAddress = craft.app.request.userIP %}
        {% if currentIpAddress != site.maintenanceIpAddress %}
            {% set maintenanceModeActive = true %}
        {% endif %}
    {% else %}
        {% set maintenanceModeActive = true %}
    {% endif %}
{% endif %}
{% if maintenanceModeActive %}
    {% include '/maintenance' %}
{% else %}


…

{% endif %}

> **Comments:**
> **username_1**: Good catch! By the way, the exit tag is documented but it's a Craft extension, so the documentation is on the Craft website: https://craftcms.com/docs/3.x/dev/tags.html#exit  

---

### Answer by username_1 on 2020-10-06. Score: 2

It looks like you're reinventing the wheel here: in Settings → General, you can toggle the site live/offline. When the site is offline, Craft serve the *templates/503.twig* templates, no matter which URL you hit.

You can even configure users to have access to the site, when it's offline. To do so, go to the user edit page in the control panel and then to the Preferences tab.

---

Regarding your specific blank page issue, it's caused by a mixup between the Twig `include` function & the Twig `include` tag.

### Function

As per [the documentation](https://twig.symfony.com/doc/2.x/functions/include.html):

> The include function returns the rendered content of a template.

You then have to do something with the returned value or it is pointless.

### Tag

The [documentation of this tag](https://twig.symfony.com/doc/2.x/tags/include.html) is misleading. It states that :

> The include statement includes a template and returns the rendered content of that file

but what it really does is **output** the rendered content of that file.

In your case, you use the function but forget to output its value. To fix you're issue, you can either use output delimiters (`{{ include('/maintenance') }}`) or use the tag instead of the function (`{% include'/maintenance' %}`).

[The documentation of the `include` tag](https://twig.symfony.com/doc/2.x/tags/include.html) encourages us to prefer the former:

As of Twig 1.12, it is recommended to use the include function instead as it provides the same features with a bit more flexibility

# Solution

# TL;DR

Use `{{ include('/maintenance') }}`.

> **Comments:**
> **username_0**: I'm only using the free version of CraftCMS, so I don't believe I can create additional users. (It's my first site using Craft.) Any thoughts as to why my code isn't working when the environment isn't set to 'dev'? It would be good to know what's going awry for future reference, even though I'm reinventing the wheel.  
> **username_1**: You're right, using Craft Solo, you're stuck with a single user and might not want to share your password with everyone! Am I correct assuming the `site`is a global set having the following fields: `maintenanceMode` and `maintenanceIpAddress`?  
> **username_0**: Yup. All of the necessary config variables are present and correct.  
> **username_1**: Can't help you much more then, your code seems fine, except what I mentioned in my comment on your question.  
> **username_0**: This is a brilliantly formatted answer, but it unfortunately transpired this is issue is with the seemingly undocumented `{% exit %}` call.  

---

