In this project I'm working with (I'm very new to Django), there are custom tags i.e. {{ custom_tag }} that a previous developer created.
In the HTML file, I find myself doing the following block of conditional logic many times in the same HTML file.
{% if custom_tag == "Blog Tag" %}
Blog
{% elif custom_tag == "About Tag" %}
About
{% else %}
etc...
{% endif %}
Are there ways that I can replace all of that conditional logic into something like {{ custom_tag|pretty }} or {{ pretty_custom_tag }}?
You can write your own criting a custom filter which would let you use {{ custom_tag|tag_pretty }}: https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
For example:
from django import template
from django.template.defaultfilters import stringfilter
register = template.Library()
#register.filter
#stringfilter
def pretty_tag(value):
return value.rpartition(" ")[0]
Related
I am trying to add a list of category tags in the sidebar of my Wagtail blog index page. The code below does work, but unfortunately it iterates through the posts and lists all the tags as individual tags, which I ultimately end up with duplicate tags. I built my blog from the Wagtail demo and since it doesn't use Views like I am used to, I am not sure where to add .distinct('tags').
Template
{% for b in blogs %}
{% for tag in b.tags.all %}
<li> <i class="glyphicon glyphicon-tag"></i> {{ tag }}<span>{{ tag }}</span>
{% if not forloop.last %} {% endif %}
</li>
{% endfor %}
{% endfor %}
Any logic that would normally go in a view function, can go in the page model's get_context method:
from django.contrib.contenttypes.models import ContentType
from taggit.models import Tag
class BlogIndex(Page):
# ...
def get_context(self, request):
context = super(BlogIndex, self).get_context(request)
blog_content_type = ContentType.objects.get_for_model(BlogPage)
context['tags'] = Tag.objects.filter(
taggit_taggeditem_items__content_type=blog_content_type
)
return context
(the tag-fetching code here is adapted from some internal Wagtail code.)
How can I access an attribute of an object using a variable? I have something like this:
{% for inscrito in inscritos %}
{% for field in list_fields_inscrito %}
{{inscrito.field}} //here is the problem
{% endfor %}
{% endfor %}
For example Inscrito have: inscrito.id, inscrito.Name and inscrito.Adress and I only want to print inscrito.id and inscrito.Name because id and Name are in the list_fields_inscrito.
Does anybody know how do this?
You can write a template filter for that:
myapp/templatetags/myapp_tags.py
from django import template
register = template.Library()
#register.filter
def get_obj_attr(obj, attr):
return getattr(obj, attr)
Then in template you can use it like this:
{% load myapp_tags %}
{% for inscrito in inscritos %}
{% for field in list_fields_inscrito %}
{{ inscrito|get_obj_attr:field }}
{% endfor %}
{% endfor %}
You can read more about writing custom template tags.
Fixed answer for non string attributes
The selected answer don't cover cases where you need to access non string attributes.
If you are trying to access an attribute that isn't a string, then you must use this code:
from django import template
register = template.Library()
#register.filter
def get_obj_attr(obj, attr):
return obj[attr]
For this, create a folder named templatetags on your app's folder, then create a python file with whatever name you want and paste the code above
inside.
Inside your template load your brand new filter using the {% load YOUR_FILE_NAME %}, be sure to change YOUR_FILE_NAME to your actual file name.
Now, on your template you can access the object attribute by using the code bellow:
{{ PUT_THE_NAME_OF_YOUR_OBJECT_HERE|get_obj_attr:PUT_THE_ATTRIBUTE_YOU_WANT_TO_ACCESS_HERE }}
I am wondering if we could use django filter as a variable where a python method formatting text can set the filter value which can be rendered by the template
The usual way filter works is like this
{{ html_text | safe }} or {{ plain_text | linebreaks }}
I want to set the values for filters 'safe'/'linebreaks' in a variable and render it like this
{{ text | filter_variable }}
Researched online, but couldn't figure it out, any help would be appreciated.
I second what Chris Pratt said, but I'd do it like this:
from django.template import defaultfilters
#register.filter
def apply_filter(value, filter):
return getattr(defaultfilters, filter)(value)
that way it works for any filter.
You can't do that, but you can create a custom filter that accepts a parameter:
from django.template import defaultfilters
#register.filter
def apply_filter(value, filter):
if filter == 'safe':
return defaultfilters.safe(value)
if filter == 'linebreaks':
return defaultfilters.linebreaks(value)
else:
# You might want to raise an exception here, but for example purposes
# I'll just return the value unmodified
return value
Then, in your template:
{{ text|apply_filter:filter_variable }}
This works if you have a few filters:
{% ifequal filter_variable 1 %}{{ text|safe }}{% endifequal %}
{% ifequal filter_variable 2 %}{{ text|linebreaks }}{% endifequal %}
{% ifequal filter_variable 3 %}{{ text|yourfilter }}{% endifequal %}
im doing something with feedparser: i have a templatetag for display "news" in my home page, but , how ill limit the feedparser result?
inclusion tag
from django.template import Template, Library
import feedparser
register = Library()
#register.inclusion_tag('rss_render.html')
def rss_render(object): #RSS URL "object"
rss = feedparser.parse(object)
return {'rss': rss}
template
<ul>
{% for r in rss.entries %}
<li> {{ r.title }}</li>
{% endfor %}
</ul>
Take this Django snippet for example.
You can use Django's slice template tag:
{% for r in rss.entries|slice:":10" %}
http://docs.djangoproject.com/en/dev/ref/templates/builtins/#slice
In a Django template, is there a way to get a value from a key that has a space in it?
Eg, if I have a dict like:
{"Restaurant Name": Foo}
How can I reference that value in my template? Pseudo-syntax might be:
{{ entry['Restaurant Name'] }}
There is no clean way to do this with the built-in tags. Trying to do something like:
{{ a.'Restaurant Name'}} or {{ a.Restaurant Name }}
will throw a parse error.
You could do a for loop through the dictionary (but it's ugly/inefficient):
{% for k, v in your_dict_passed_into_context %}
{% ifequal k "Restaurant Name" %}
{{ v }}
{% endifequal %}
{% endfor %}
A custom tag would probably be cleaner:
from django import template
register = template.Library()
#register.simple_tag
def dictKeyLookup(the_dict, key):
# Try to fetch from the dict, and if it's not found return an empty string.
return the_dict.get(key, '')
and use it in the template like so:
{% dictKeyLookup your_dict_passed_into_context "Restaurant Name" %}
Or maybe try to restructure your dict to have "easier to work with" keys.
You can use a custom filter as well.
from django import template
register = template.Library()
#register.filter
def get(mapping, key):
return mapping.get(key, '')
and within the template
{{ entry|get:"Restaurant Name" }}