True is False and False is True

Hello,

I have a very simple tag:

@register.simple_tag(takes_context=True)
def is_homepage(context):
    request = context['request']
    return request.path == '/' or request.path == ''

This is not working: (the code inside if block is not showing when I’m browsing http://127.0.0.1:8000):

{% if is_homepage %}
...            
{% endif %}

This is working:

{% if not is_homepage %}
...
{% endif %}

This is driving me crazy! Someone please explain what is going on!

Did you load your registered tag in your template?

Something like that:

{% load is_homepage %}

{% is_homepage as on_homepage %}

{% if on_homepage %}
...
{% endif %}

Ok, I see it now - {% if ... %} is the tag. The parameter to the if tag is expected to be either a literal string or a context variable, not another tag.

That’s why it’s not working, and why you need to use as as described in the previous comment.

Install django-fastdev. If you have that installed you will get a nice crash page telling you that you accessed a variable that does not exist.

For the actual solution: What you want here is a context processor. Not a template tag.

Thanks. Ken’s answer was correct and it works now. The variable does exist and context processor is an entirely different thing.

I know it’s a different thing. It’s also the appropriate thing in this situation. Your code currently has two lines (the load and the as call to the tag) that are wholly redundant and honestly wrong. This is not what tags are for. (Also, give credit where credit is due, it was aneftas solution, not Kens).

The appropriate solution is just {% if request.path == ‘/’ %} and it will work without tag or processor but one of the use cases of tags is conditional rendering of the template like what {% if %} is doing. I just wanted my own condition here and it works as I expected.

And Ken explained why as is needed.

True. Just checking the path directly is probably sufficient in this case.

but one of the use cases of tags is conditional rendering of the template

Well… yea, if you create a new tag like {% if_homepage %}, but you created a tag that returns a bool. That doesn’t make much sense and is a misuse of tags.

{% if forloop.first %} returns a boolean.

No. It does not. forloop.first is a boolean, but {% if %} renders it’s content if the expression is truthy. The distinction is quite important. If {% if forloo.first %} returned a boolean, then:

{% for x in y %}
{% if forloop.first %}
{% endfor %}

would print True once. It does not. It’s in fact a syntax error and will not parse.