My head could not click how to translate numbers in django translation. It is not possible to translate by string id. I could print 2020 like:
{% translate '2' %}{% translate '0' %}{% translate '2' %}{% translate '0' %}
Obvioulsy, It is not the way. So, I am missing something. I would want something like:
{% translate "2020"|number %} # May be ?? It should be that easy right?
It should be that, translation from 0 to 9.
Django doesn't have this functionality (yet), but you can achieve the same by creating a custom template tag. You can read the whole documentation of creating the tag here, Custom template tags and filters.
By this way, you can translate Arabic Numerals (or anything) to any form, all you need is a mapper dict and a function that converts things by using the mapper dict.
We need to have a dict that has the source numerals as keys and target numeral as values. In this case, I assume you need to translate from Arabic numerals to nepali numerals
So, I have created a simple mapper using dict and converted the receiving value to something else using the translate_nepal_numeral(...) function.
from django import template
from django.template.defaultfilters import stringfilter
NUMBER_MAP = {
"0": "०",
"1": "१",
"2": "२",
# and so on
}
register = template.Library()
#register.filter()
#stringfilter
def translate_nepal_numeral(value):
try:
return "".join([NUMBER_MAP[char] for char in value])
except KeyError:
return value
Then in your template,
{% load custom_numerals %}
{{ "2010"|translate_nepal_numeral }}
Examples
In [3]: translate_nepal_numeral("2020")
Out[3]: '२०२०'
In [4]: translate_nepal_numeral("2120")
Out[4]: '२१२०'
In [5]: translate_nepal_numeral("2120a")
Out[5]: '2120a'
Notes
If you are passing a non-numeral, this function will return the input
Related
I'm struggling to get my templatetag to work. I believe it's the syntax or the way i'm calling app_filters. Forgive me i'm learning web application development so if my logic is off please correct me. My goal is to pass a collection of check boxes on one template to a new one filtered at a different level report_id is the collection of each check box.
I have an array in my view from my GET.getlist call below
checkedlist = request.GET.getlist('report_id')
reportlist = QvReportList.objects.filter(report_id__in= checkedlist, active = 1).values_list('report_name_sc',flat = True)
print (checkedlist)
print (reportlist)
args = {'retreivecheckbox': checkedlist}
return render(request,'accounts/requestaccess.html', args)
When I print my array the console displays it correctly, this example is if there was two check boxes selected:
['88', '89']
<QuerySet ['Common Data Model Reconciliation Load', 'LEJR BPCI IV - ICS Baseline']>
I've created the following templatetag called app_filters defined as:
from django import template
register = template.Library()
#register.filter
def get_list(querydict, itemToGet ):
return querydict.getlist(itemToGet)
Now i'm trying to get my template to display what's in my console but as individual rows/indexes dependent upon user selections. I'm told get_list will do that for me. I've also tried get_at_index. I.E. I want to see retreivecheckbox as
88
89
and not [88,89]
Using the following template my app prints correctly, however, all on one row as 88 89.
{% for app in retreivecheckbox %}
{{ app }}
{% endfor %}
When I try several variations of the following my template displays nothing. Why doesn't my get_list break my array into indexed lines?
{% load app_filters %}
{% for app in retreivecheckbox|get_list:report_id %}
{{ app }}
{% endfor %}
My book example shows it as
{% for app in retreivecheckbox|get_list:"report_id" %}
However, when I use double or single quotes it gives me the following error:
'QuerySet' object has no attribute 'getlist'
Using {{ request.GET|get_list:"report_id" }} prints the list out as [88,89] [88,89]
I've tried all sorts of different variations, but its not displaying as I want it to or it won't display. I've been trying print '\n'.join(map(str, list_of_ints)), it works except the 4 items is still one check box, instead of 4.
Thanks to Daniel for his clarification, this was easily solved by using list tags in HTML. I was over thinking the problem.
Looks like a question that should be already covered, but after spending some time, I did not find how to check that a variable is numeric in Django template.
Something like
{% if my_var.isnumeric %}
# do something
{% endif %}
UPDATE
As I learnt from the below discussion, there seems to be no built-in tag to check this, and we end up having to create our own template tag.
Assuming that "numeric" means "contains only digits" (and no decimal point, no minus sign, etc.)
Custom filter is your best bet:
from django import template
register = template.Library()
#register.filter(is_safe=True)
def is_numberic(value):
return "{}".format(value).isdigit()
Docs about custom template filters: https://docs.djangoproject.com/en/1.9/howto/custom-template-tags/
Usage in templates:
{% load your_custom_lib %}
...
{% if something|is_numberic %}...
If you consider integers as numeric (positive and negative), then the function becomes:
try:
int("{}".format(value))
except ValueError:
return False
else:
return True
In case "numeric" means "integer or float", then use float instead of int. But note that this will also recognize -12E3 as numeric, because:
>>> -12E3
-12000.0
Does this work ?
{{ value|divisibleby:"1" }}
EDIT: Nope, raises an exception if a string is given.
I have the following in a template -
<tes:productiondate>{% now "Y-m-d" %}T{% now "H:i:s" %}-{{{% now "u" %}|truncatechars:4}}</tes:productiondate>
It's giving me an error
Could not parse some characters: |{% now "u" %}||truncatechars:4
{% now "u" %} does display correctly the problem is that by default it displays 6 characters and I only want it to display 4 characters.
I'm realizing that truncatechars it's the right way to do it because I don't want the "..." so how do I go about shortening the string of 6 characters to be only 4?
You can't apply a filter to template tag's output. In trunk version of django {% now %} tag can save formatted time to variable:
{% now "u" as msec %}{{ msec|truncatechars:4 }}
But in the current stable django (1.7.2) the as keyword is not supported.
So you have to write custom template tag. It is easy:
import datetime
from django import template
register = template.Library()
#register.simple_tag
def microseconds(format_string):
return datetime.datetime.now().strftime('%f')[:4]
template.html
{{list.report.description|default:"No description available"|slice:"45" }}{% if list.report.description|length > 45 %}...{% endif %}
1.This is slicing if character entered more than 45.
2.It produce problem while creating new report,if no description is given,it should display the default text as "No description available" but instead it is displaying the text along with 3 dots.
2.No problem if the field is saved with empty,it is displaying default as "No description available".
Thanks
Although I am not entirely sure why your code isn't working, it's the "wrong" thing to do anyhow.
Try the truncatechars method instead: https://docs.djangoproject.com/en/dev/ref/templates/builtins/#truncatechars
{{ value|truncatechars:9 }}
If value is Joel is a slug, the output will be Joel i....
For Django 1.3 or older, use the following templatetag: http://djangosnippets.org/snippets/444/
from django import template
register = template.Library()
#register.filter
def truncatechars(s, num):
"""
Truncates a word after a given number of chars
Argument: Number of chars to truncate after
"""
length = int(num)
string = []
for word in s.split():
if len(word) > length:
string.append(word[:length]+'...')
else:
string.append(word)
return u' '.join(string)
I have a generic delete view that includes a confirmation question as a translated string containing one placeholder. I would like to interpolate it like this:
<p class="text-error">
{% message % object %}
</p>
Variable message contains a string like: "Do you want to remove user %s?".
How can I use string interpolation in templates?
You can use the following dictionary with strings:
strings = { 'object': 'word' }
as follows:
{{ strings|stringformat:message }}
with the stringformat filter. Note that the leading % is dropped from the string (see the documentation for more details).
Finally I made a custom filter:
from django.template.base import Library
register = Library()
#register.filter
def interpolate(value, arg):
"""
Interpolates value with argument
"""
try:
return value % arg
except:
return ''