How can check for a specific URL in jinja2 within html files and then render different html files based on what URL I am currently at?
For eg.
# if {{ request.path == /siteID/ }}
{% include "file1.html" %}
# if {{ request.path == /siteID/abcde/ }}
{% include "file2.html" %}
Current logic I have which I feel is not very good:
<!-- ..... bunch of html lines .... -->
{% if request.path|length > 8 and request.path.startswith('/siteID/') and request.path[8:].strip('/').split('/')|length == 1 %}
{% include "file2.html" %}
{% else %}
{% include "file1.html" %}
{% endif %}
<!-- ..... bunch of html lines .... -->
Also how do I scale this if I want to do something in the future like:
# if {{ request.path == /siteID/abcde/uvwxyz }}
{% include "file3.html" %}
Since you want to scale this later, don't do this in the template. Put the logic into a view function, then pass a variable to the render function that stores the name of the template you want to include. E.g.:
def the_view(request):
if request.path == '/siteID/abcde/':
template = 'file1.html'
elif request.path == '/siteID/fgh/':
template = 'file2.html'
else:
template = 'file_default.html'
return render(request, 'base.html', {'template_to_include': template})
Then in your base.html template put this dynamic import line somewhere:
{% include template_to_include %}
Related
while writing an application in django, I've encountered a problem. I want to make page-number links, with current page not being a link. So in template I do this:
{% for i in pages %}
{% if i == curr_page %} {{ i }}
{% else %} {{ i }}
{% endif %}
Only problem? Jinja doesn't seem to notice two numbers being equal. I've changed the 2nd line to {% if i != curr_page %} {{i}}!={{curr_page}} and got "... 5!=6 6!=6 7!=6 ...".
What should I do?
Because they are not of same data type. In your view, cast them to int before passing to context dict.
pages = list(map(int, pages))
curr_page = int(curr_page)
I am building a chatbot. There are few child templates like login.html, messages.html, transaction.html, etc. I want to append these templates in base.html dynamically. I am extending base.html in all these templates. My problem is only one template is rendered at a time. Is there any solution for appending these templates one after another? I have used {%include%} but it's a static approach. I need dynamic.
printer.py looks like -
#app.route('/respond', methods=['GET','POST'])
def respond_def():
message = request.form['message_input']
if message == "l":
return render_template('printer/login.html')
elif message == "t":
return render_template('printer/transactionID.html')
base.html looks like -
//some code here
<li>
{% block template %}{% endblock %}
</li>
//some code here
message.html looks like -
{% extends "base.html" %}
{% block template %}
<div> Message template called </div>
{% endblock %}
I resolved it.
I made a list of templates in printer.py and then appended those templates in base.html whenever user asked for it.
printer.py
dictionary = []
// append name of template in this whenever needed.
return render_template('printer/base.html', dictionary=dictionary)
base.html
{% for d in dicts %}
{% set template = 'printer/' + d + '.html' %}
// can add conditions for different templates
{% include template %}
{% endfor %}
Imagine a directory specified in pages' front matter:
---
...
assets: "/assets/<project-name>"
...
---
How can one determine the number of files in the assets' sub-directories? For example:
{% assign img_dir = page.assets | append: "img/" %}
{% if <files-in-img_dir>.length > 1 %}
// Render multiple images
{% else %}
// Render single images
{% end if %}
As of right now I'm using something like below, but I would like to be able to optimize (imports, build, etc.) based on the number of assets to render.
{% for asset in site.static_files %}
{% if asset.path contains img_dir %}
// Render
{% endif %}
{% endfor %}
Thanks.
I am trying to get Django user's group in HTML for an if tag. This is what I tried:
{% ifequal user.groups.all.0 'ABC' %}
{% endif %}
But this is not working. What other way is there?
Try this:
{% for group in request.user.groups.all %}
{% if group.name == 'ABC' %}{% endif %}
{% endfor %}
Or
{% if request.user.groups.all.0.name == 'ABC' %}{% endif %}
You have to access the current user object from the request context variable. For this, make sure that django.template.context_processors.request is in your template settings.
request.user.groups.all.0 returns a Group model object, so you have to compare against the name field.
I think you will have to use a little Python here. For example, a custom template tag:
#register.filter(name='has_group')
def has_group(user, group_name):
return user.groups.filter(name=group_name).exists()
And in your template:
{% if request.user|has_group:"ABC" %}
...
{% endif %}
(Source: http://www.abidibo.net/blog/2014/05/22/check-if-user-belongs-group-django-templates/)
But maybe you should actually use permissions here.
https://docs.djangoproject.com/en/1.8/topics/auth/default/#authentication-data-in-templates
Edit: Here is a more complete example of the custom template tag:
settings.py:
INSTALLED_APPS = [
...
'yourapp',
...
]
Filesystem:
yourproject/
manage.py
yourproject/
settings.py
wsgi.py
...
yourapp/
__init__.py
templatetags/
__init__.py
yourapp_extras.py
...
yourapp_extras.py:
from django import template
register = template.Library()
#register.filter(name='has_group')
def has_group(user, group_name):
return user.groups.filter(name=group_name).exists()
Template:
{% load yourapp_extras %}
{% if request.user|has_group:"ABC" %}
...
{% endif %}
To get a more thorough understanding of this, I highly recommend reading Django's excellent documentation.
<h1>{{ user.groups.all.0 }}</h1>
{% if user.groups.all.0.name == 'Team2' %}
<h1>YES</h1>
{% else %}
<h1>NO</h1>
{% endif %}
Here, the user.groups.all.0 gives you the first group assigned to the user.
For eg. if the logged in user has groups assigned to him as- 'Team2', 'Programmer', 'Beginner'.
Then {{user.groups.all.0}} will print Team2.
I've used it to print and check the logged in user's group in html template.
OR
{% if request.user|has_group:"mygroup" %}
<h1>Has group mygroup</h1>
{% endif %}
Also works fine in django v1.11. This will check if the current user has 'mygroup' assigned to it or not.
However you'll need to add
from django import template
from django.contrib.auth.models import Group
register = template.Library()
#register.filter(name='has_group')
def has_group(user, group_name):
group = Group.objects.get(name=group_name)
return True if group in user.groups.all() else False
inside a group_check.py in below file structure
--app
|templates
|templatetags
|-- group_check.py
I want to render the “Tags:” label only if the post has actual tags. When I write
{{post.tags | size}}
I get the number of tags. However, if I put it in an {% if %} condition:
{% if post.tags | size != '0' %}
it always yields true. I worked around this problem with
{% capture tagsize %}{{post.tags | size}}{% endcapture %}
{% if tagsize != '0' %}
but it seems very ugly. Is there a better way to do this?
Note: I use GitHub Pages, so using a plugin – other than being an overkill – is not an option. My Jekyll version is 2.0.4 as specified here as of date.
By default {{ post.tags }} == empty array.
As we cannot do {% if post.tags != [] %}, we just add array: [] in _config.yml.
We can now do :
{% if post.tags != site.array %}
Do something
{% endif %}
tag size returns an integer and not a string so you should compare against 0 and not '0'
{% if page.tags.size != 0 %}
<!-- some code to render tags -->
{% endif %}