Currently I'm using Flask and Jinja2 in combination with Babel. So far everything is working great.
The only problem I'm facing is when using links in a translated text. Let's say we have the following in HTML:
<p>You can change this in your settings.</p>
How would I use this in combination with babel?
I had been thinking of the following code, but this gives issues when the order of words is not the same in the translated language.
<p>{{ _("You can change this in your "){{ _("settings").</p>
Another idea was to put the entire HTML into the string to be translated but then I cannot use string escaping anymore.
What is the preferred way to do this?
I was looking for a solution to this and came across this excellent page.
You can add links by using the string substitution that is available for jinja2 variables. Here is an example:
{{ _("You can change this in your %(open)ssettings%(close)s.", open='' % user_id, close='')|safe }}
Your .po file will then have an entry like this:
msgid "You can change this in your %(open)ssettings%(close)s."
msgstr ""
Related
I'm quite new to using Django, so please be gentle, if this is a stupid question.
I'm trying to play with some stock-information in Python/Django. I'm getting the stock-rates from Yahoo Finance (with urllib). Whenever I get some stock-information, then I will get it like this (yep, it's one long string):
[b'Date,Open,High,Low,Close,Volume,Adj Close\n2014-12-01,26.16,26.22,25.85,26.02,48967100,25.54\n2014-11-28,26.80,26.90,26.44,26.49,31185200,26.00\n2014-11-26,26.89,26.97,26.78,26.87,19289700,26.38\n2014-11-25,27.01,27.03,26.84,26.86,28028000,26.37\n']
I then send it to a template with Django, using
to_be_returned = RequestContext(request, [[DICTIONARY_WITH_VARIABLE]])
and then
return HttpResponse(template.render(to_be_returned)
Is there a way, to get Django to beautify the long string for me? So I don't have to manipulate the string and replace all \n with <br />, in order for me to be able to read it easier? And what does the [b' ... '] mean (that contains the entire result?
Thanks for your assistance.
Use the linebreaksbr template filter:
{{ my_string_with_n|linebreaksbr }}
b'...' is a python3 byte string literal.
You do not attached a template.
Wrap out tag with
<pre></pre>
You can add html tag to the strings that you write in the response
For example :
response2.write('</br></br>List of Courses : ')
I have a field in database description that system will save HTML code in it.
and I have a search system that works with Q:
Post.objects.filter(Q(name__icontains=keyword) | Q(description__icontain=keyword))
It works fine but the problem refers to it when user searchs for example '<strong>' or 'strong' it will returns the rows that have '<strong>' word in them but it shouldn't consider the HTML tags.
So how to search a value in HTML content with Django ORM that don't consider HTML tags?
I'd probably add a second field called stripped_description and use django's striptags filter to strip out html tags, and have django search on that field. It should still find the row you need to recall the actual description field containing the HTML code, should you need to display that as a result, but that's the only means I've used to "ignore" html tags.
You can or probably should look into a proper search function using haystack, my favorite search engine to use with it is whoosh (pip install whoosh) if you are not doing hardcore search functions. You can define your content to be indexed like this:
{{ object.title }}
{{ object.description|strip_tags }}
It's fairly easy to setup, and once you have done it, setting up for the next project would be in minutes.
I think it's a good action:
from django.utils.html import strip_tags
rows = Post.objects.filter(Q(name__icontains=keyword) | Q(description__icontain=keyword))
if rows:
for j,i in enumerate(rows):
if keyword not in strip_tags(i.name) and keyword not in strip_tags(i.description):
del rows[j]
return render(request,'posts.html',{'rows':rows})
Fetching data from db with filter.
Strip tags the results and then filtering them again.
I have a little problem understanding what an expression like {{ something.render() | safe }} does .
From what I have seen, without the safe keyword it outputs the entire html document, not just the true content.
What I would like to know, is what it actually does, how it functions .
The safe filter explicitly marks a string as "safe", i.e., it should not be automatically-escaped if auto-escaping is enabled.
The documentation on this filter is here.
See the section on manual escaping to see which characters qualify for escaping.
Normally text is HTML-escaped (so <b> would be written out as <b>, which would render as <b>).
When you put |safe after something, you're telling the template engine that you have already escaped the text yourself, i.e. "it's safe to render this directly". So it will not do that encoding for you.
For more information: http://jinja.pocoo.org/docs/templates/#html-escaping
For anyone coming here looking to use the safe filter programmatically: wrap it in a markupsafe.Markup class, on which Jinja2 depends on.
Expanding on #data's answer, here's an example of using markupsafe.Markup:
import markupsafe
vals = {}
vals["name"] = markupsafe.Markup("<b>Duck</b>, Donald")
html = template.render(vals)
The resulting HTML will show Donald's last name in bold wherever the template contains {{name}}.
You can go this way
post.body is the variable that is getting the data from the database or any file.
{{ post.body | safe }}
I hope you will get it.
I've noticed that my template is rendering my model.CharField and model.TextField without any excess whitespace.
For example, if I enter data such as...
This is a test
to see what happens.
The rendered object field will appear as...
This is a test to see what happens.
Is this an intentional feature of Django or have I missed some filter or parameter somewhere?
I've checked the field itself with some debug code (print object.field) and it does contains the extra whitespace, so the problem is in the rendering side.
How can I allow the user to enter paragraphs of data in TextFields? How can I preserve the whitespace that the user may have entered?
As you can see even in StackOverflow your spaces do not display, this is from the source of your question:
This is a test
to see what happens.
Will save in the database as:
This is a test\n\n\nto see what happens.
You have to problems when rendering as html:
Extra spaces between words are stripped on display by the browser, unless it is between <pre></pre> tags
Linebreaks will be rendered as plain text linebreaks, which do not display in the browser unless between <pre></pre> tags.
For spaces, you can use such a template filter to replace them with their html entity equivalent: .
To convert database linebreaks in HTML linebreaks, use linebreaksbr built-in filters. For example, if {{ foo }} is: test\nbar, then {{ foo|linebreaksbr }} will render: test<br />bar
Create a "templatetags" folder in some of your apps with an __init__.py file in it.
Save the snippet for example in someapp/templatetags/replace_tag.py
Load the template filter in the template as such {% load replace_tag %}
Combine replace and linebreaksbr as such: {{ foo|linebreaksbr|replace:" "," " }}
You can also make your own template filter that will process the text into the HTML you need. In any case, refer to the custom template filter documentation for complete information.
I've a problem from many years.
The problem is a long text not separated by white spaces in a div. No wrap is applied and it breaks all layout.
How can I fix in django in a good way?
This is what I see:
As I understand the question it is HTML-side problem, not django-side. For HTML solution look How to word wrap text in HTML?. If you still want to wrap text in python code, textwrap.wrap will help you.
Also there is convenient template tag for this: wordwrap. It uses django.utils.text.wrap function which seems more suitable for using in Django projects.
This was bugging me as the built-in word-wrap template tag should have just worked. Instead use this...
{{ value|wordwrap:50|linebreaksbr }}
or
{{ value|wordwrap:50|linebreaks }}
depending if you want <br> or <br> and <p> tags
I don't know if it helps, but an approach could be creating a new filter based on truncatewords filter.
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#truncatewords
Code looks very simple:
def truncate_filter(value, maxlen):
if len(value) <= maxlen:
return value
return value[:maxlen-2] + '..'
Another ideia is using: {{ username|stringformat:".10s" }} to truncate in 10 characters.
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#stringformat