1

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 %}
<!DOCTYPE html>
<html lang="en"…

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.

  • 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' %}). – nstCactus Oct 6 '20 at 14:57
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:

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

  • 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 Oct 6 '20 at 14:32
  • 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 siteis a global set having the following fields: maintenanceMode and maintenanceIpAddress? – nstCactus Oct 6 '20 at 14:44
  • Yup. All of the necessary config variables are present and correct. – John Parker Oct 6 '20 at 14:49
  • 1
    Can't help you much more then, your code seems fine, except what I mentioned in my comment on your question. – nstCactus Oct 6 '20 at 14:59
  • This is a brilliantly formatted answer, but it unfortunately transpired this is issue is with the seemingly undocumented {% exit %} call. – John Parker Oct 7 '20 at 12:19
1

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 %}
<!DOCTYPE html>
<html lang="en">
…
</html>
{% endif %}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.