I have this conditional included in a layout file I use within others, using the extends feature in twig.

This is at the very top of _layouts/application.twig

{% if not currentUser %}
    {% redirect "login" %}
{% endif %}

I have this at the very top of account/index.twig

{% extends "_layouts/application" %}
{% set name = currentUser.getFullName() %}

If the user is not logged in, I expect it to redirect the user to the login page, as it contains the if not currentUser conditional at the very beginning of the extends file: _layouts/application.twig

I then copied and pasted the if not currentUser code and placed it above the extends call within the account/index.twig file (like seen below):

{% if not currentUser %}
    {% redirect "login" %}
{% endif %}

{% extends "_layouts/application" %}

and it works as I expect it to.

Why does it not work with the if conditional being included in _layouts/application.twig file that I include by using {% extends "_layouts/application" %}

  • Tested this quickly, and it seems to work for me both when I have the conditional in the layout and in the template. Just guessing here but, you wouldn't maybe be extending the login template with the same layout? That would probably generate an indefinite loop. Not sure how Craft/Twig would handle that. – André Elvan Oct 5 '16 at 17:41
  • no, its not a case of it being used within the login page. @AndréElvan in the file you called the extend file, can you put below the extend call this: {{ currentUser.id }}, make sure you're logged out before accessing that page. – Brad Oct 5 '16 at 20:18
  • Ah yeah, that'll create an twig error. Is that the problem? – André Elvan Oct 5 '16 at 20:45
  • @AndréElvan yes, I am trying to get it work within the file I am calling in the extends, instead of copying and pasting the if currentUser conditional into hundreds of templates. – Brad Oct 5 '16 at 20:48
  • 1
    Elaborated a bit on my answer. The actual error message would be useful though, since what you write ("can you put below the extend call this: {{ currentUser.id }}") would result in the error message "A template that extends another one cannot have a body.", which is completely unrelated to your question. :) – André Elvan Oct 5 '16 at 21:20

The issue here is that extends isn't the same thing, neither conceptually or technically, as an include. When you extend a template with a layout template, the template is "decorated" by the layout. So, what's happening is that the code in the layout is parsed after all of the code in the template.

Check out this article on straightupcraft explains the order of which things happen in Twig. In short:

1) All code in your template, except code inside blocks, gets processed.

2) All code in your layout, except code inside blocks, gets processed.

3) Code inside blocks gets processed.

So, what the solution to your problem is, depends on your setup. But, if your code that accesses currentUser is inside the block in your page template, the redirect should fire first. If you need to access currentUser outside of the blocks in your page template, you have to do the redirect there.

Your Answer

