Seitaridis
Seitaridis

Reputation: 4529

Obtain the first part of an URL from Django template

I use request.path to obtain the current URL. For example if the current URL is "/test/foo/baz" I want to know if it starts with a string sequence, let's say /test. If I try to use:

{% if request.path.startswith('/test') %}
    Test
{% endif %} 

I get an error saying that it could not parse the remainder of the expression:

Could not parse the remainder: '('/test')' from 'request.path.startswith('/test')'
Request Method: GET
Request URL:    http://localhost:8021/test/foo/baz/
Exception Type: TemplateSyntaxError
Exception Value:    
Could not parse the remainder: '('/test')' from 'request.path.startswith('/test')'
Exception Location: C:\Python25\lib\site-packages\django\template\__init__.py in   __init__, line 528
Python Executable:  C:\Python25\python.exe
Python Version: 2.5.4
Template error

One solution would be to create a custom tag to do the job. Is there something else existing to solve my problem? The Django version used is 1.0.4.

Upvotes: 14

Views: 17970

Answers (6)

tulsluper
tulsluper

Reputation: 1987

I use context processor in such case:

*. Create file core/context_processors.py with:

def variables(request):
        url_parts = request.path.split('/')
        return {
            'url_part_1': url_parts[1],
        }

*. Add record:

'core.context_processors.variables',

in settings.py to TEMPLATES 'context_processors' list.

*. Use

{{ url_part_1 }}

in any template.

Upvotes: 0

TheOne
TheOne

Reputation: 11159

Instead of checking for the prefix with startswith, you can get the same thing by checking for membership with the builtin in tag.

{% if '/test' in request.path %}
    Test
{% endif %} 

This will pass cases where the string is not strictly in the beginning, but you can simply avoid those types of URLs.

Upvotes: 29

Ferran
Ferran

Reputation: 15013

You can use the slice filter to get the first part of the url

{% if request.path|slice:":5" == '/test' %}
    Test
{% endif %} 

Cannot try this now, and don't know if filters work inside 'if' tag, if doesn't work you can use the 'with' tag

{% with request.path|slice:":5" as path %}
  {% if path == '/test' %}
    Test
  {% endif %} 
{% endwith %} 

Upvotes: 62

Fábio Diniz
Fábio Diniz

Reputation: 10353

From the Philosophy section in this page of Django docs:

the template system will not execute arbitrary Python expressions

You really should write a custom tag or pass a variable to inform the template if the path starts with '/test'

Upvotes: 0

payne
payne

Reputation: 14177

You can't, by design, call functions with arguments from Django templates.

One easy approach is to put the state you need in your request context, like this:

def index(request):
    c = {'is_test' : request.path.startswith('/test')}
    return render_to_response('index.html', c, context_instance=RequestContext(request))

Then you will have an is_test variable you can use in your template:

{% if is_test %}
    Test
{% endif %}

This approach also has the advantage of abstracting the exact path test ('/test') out of your template, which may be helpful.

Upvotes: 3

Bernhard Vallant
Bernhard Vallant

Reputation: 50796

You can not pass arguments to normal python functions from within a django template. To solve you problem you will need a custom template tag: http://djangosnippets.org/snippets/806/

Upvotes: 6

Related Questions