I'm trying to conditionally show some content inside the layout file. In my entries I have a lightswitch field - to indicate which entries should be excluded. This all works fine when I can identify the entry. But on the homepage it's not able to identify the entry - I assume because it does not have a slug. Is there a better way to do this so it work on all entries and the homepage?

{% set last = craft.entries({ slug: craft.app.request.segments|last }) %}
{% for entry in last.all() %}
{% if entry.overlayPopup =='y' %}
  <!-- NO popup -->
{% else %}
  <!-- SHOW popup -->
  {% include "embeds/popup" %}
{% endif %}
{% endfor %}

1 Answer 1


Assuming you've configured your sections with URI formats, Craft will inject an entry variable into the global Twig context whenever the request URL matches an existing entry (this is true for the homepage or any entry with an URL).

This means that in cases where Craft is rendering an entry template (which is {% extend %}ing your layout file), there should already be an entry variable referencing the current entry in your Twig context and there is no need to manually query for that entry.

However, you might have other templates in your build that aren't entry templates, so there's a good idea to be defensive about whether or not the entry variable exists or not (and in cases where it doesn't, it's not an entry template and the logic is moot).

I don't really understand the {% if entry.overlayPopup =='y' %} conditional in your code; if overlayPopup is a Lightswitch field, it's either going to be true, false or null; never 'y'.

But, assuming you want to include the embeds/popup template if a) there is a entry matching the current request URL, and b) that entry has an enabled Lightswitch toggle field with the handle overlayPopup, your code can probably be simplified to this:

{% if entry is defined and entry.overlayPopup|default %}
    {% include "embeds/popup" %}
{% endif %}

Basically, the above code says "if there is an entry variable defined, and if that entry has an attribute/field overlayPopup, and if that overlayPopup field is true, include the embeds/popup template."

If you want the opposite; the embeds/popup template should be included if there isn't an entry or if the entry doesn't have that Lightswitch field enabled, that'd look like this:

{% if entry is not defined or not entry.overlayPopup|default %}
    {% include "embeds/popup" %}
{% endif %}

As a sidebar; I interpret your initial code as querying for one entry. Whenever you do that, you'll usually want to execute the query using .one() instead of .all(). Using .one(), you'll either get back a single entry (if there is one that matches your query), or a null variable (if there aren't any matching entries). Ie. not an array (that might be empty or not) which is always returned by .all() – meaning you'll avoid the redundant {% for %} loop.

Using .one(), your initial code could be refactored to this:

{% set entry = craft.entries.slug(craft.app.request.segments|last).one() %}
{% if entry and entry.overlayPopup|default %}
{% endif %}

But again, you shouldn't have to query for the entry from your layout file. Most likely, it'll be in your Twig context already, whenever the current URL matches an entry.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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