Display language icons in Django template - django

I want to display language icons instead of names in Django template.
My code looks like this:
{% load static i18n %}
{% get_current_language as CURRENT_LANGUAGE %}
{% get_available_languages as AVAILABLE_LANGUAGES %}
{% get_language_info_list for AVAILABLE_LANGUAGES as languages %}
<div id="language">
{% for language in languages %}
<ul>
<li>
<a href="/{{ language.code }}/"
{% if language.code == LANGUAGE_CODE %} class="active"{% endif %}>
{{ language.name|slice:":3" }}
</a>
</li>
</ul>
{% endfor %}
</div>
Is there any possible ways to achieve that goal or I have to try different ways?
solution for that was to change that rows to this:
<a href="/{{ language.code }}/"
{% if language.code == LANGUAGE_CODE %} class="active"{% endif %}>
<img src="/static/images/{{ language.name }}.png" alt="Geo">
</a>
And you have to place icons in static folder with the language names for english -> English and so on.

The harder part is assembling your set of country flag images together somewhere.
The easy part is using your language context to get an <img> reference, for example
<img ... src="somewhere/{{language.name|slice:":3"}}.gif" >
You might want to take a look at the django-countries package. Use it, or use it for ideas.

Related

Django URL Translation - Stay on the same page when changing language

I developped a Django app with i18n for urls as well.
That look really nice but when changing the language I would like to stay on the same/previous page.
What is the best way of doing that ?
Basically to get the new url I need to do a reverse on the name of the previous page after having changed the language and do a redirect but how can I know the url name of the previous page?
Edit:
A solution that came from a collegue:
Calculate a next parameter for each language using request.resolver_match.
For each language : activate(language) + reverse('{app_name}:{url_name}', args, kwargs) using request.resolver_match elements
Do you see a better idea?
After change language with django-modeltranslation redirecting to home ?
If you want to redirect to the same page, you can replace this part of code:
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
<div class="languages">
<p>{% trans "Language" %}: </p>
<ul class="languages">
{% for language in languages %}
<li>
<a href="/{{ language.code }}/
{% if language.code == LANGUAGE_CODE %} class="selected"{% endif %}>
{{ language.name_local }}
</a>
</li>
{% endfor %}
</ul>
</div>
to:
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
<div class="languages">
<p>{% trans "Language" %}: </p>
<ul class="languages">
{% for language in languages %}
<li>
<a href="/{{ language.code }}/{{request.get_full_path|slice:"4:"}}"
{% if language.code == LANGUAGE_CODE %} class="selected"{% endif %}>
{{ language.name_local }}
</a>
</li>
{% endfor %}
</ul>
</div>
Attention please:
<a href="/{{ language.code }}/
replaced to <a href="/{{ language.code }}/{{request.get_full_path|slice:"4:"}}"
Two options for you:
Option 1
If you use the form from the documentation then will take you which brings you back to the page you were on.
Option 2
When changing the language you could use the referrer header, HTTP_REFERER , and redirect back to where you came from
# Change the language
# ... code ...
# Redirect back to where we came from
redirect_to = request.META.get('HTTP_REFERER', reverse('default-redirect-page'))
return HttpResponseRedirect(redirect_to)

Django caching in a custom context processor

I have a custom context processor which I use to generate a dynamic menu and a list of current apps, site-wide:
from portal.models import *
def base_items(request):
return {
...
'app_items': App.objects.filter(isonline=True),
'menu_items': MainMenu.objects.all().order_by('position'),
}
EDIT:
My template (note that many of these urls are outside of the Django framework and vary depending on language. Hence the need to hardcode them into the db fields:
<ul class="menu">
{% for item in menu_items %}
{% if LANGUAGE_CODE = "en-us" %}
<li><a title="{{ item.title_en }}" href="{{ item.url_en }}">{{ item.title_en }}</a>
<ul>
{% for subitem in item.submenu_set.all %}
<li><a title="{{ subitem.title_en }}" href="{{ subitem.url_en }}">{{ subitem.title_en }}</a></li>
{% endfor %}
</ul>
</li>
{% else %}
<li><a title="{{ item.title_es }}" href="{{ item.url_es }}">{{ item.title_es }}</a>
<ul>
{% for subitem in item.submenu_set.all %}
<li><a title="{{ subitem.title_es }}" href="{{ subitem.url_es }}">{{ subitem.title_es }}</a></li>
{% endfor %}
</ul>
</li>
{% endif %}
{% endfor %}
</ul>
My question is - how can I cache these results, which don't change very frequently?
I have tried the #cache_page decorator but I can see my pages still accessing the db for the menu items objects.
Any help much appreciated.
You can use django low level cache API. Note that you might have to cast the querysets to list.
Or, you could cache the template fragment that uses these querysets, because querysets are lazy.
Try to return lamdas expressions to your templates:
'app_items': lambda: App.objects.filter(isonline=True),
that way it does not get compiled/cached and works dynamically.

django - Invalid block tag: 'add_pinned_status', expected 'else' or 'endif'

I get the following error when serving my django application using Nginx+FastCGI
Invalid block tag: 'add_pinned_status', expected 'else' or 'endif'
Oddly, the site works just fine when I'm serving using the Django development server. It also works with Nginx most of the time, but the error randomly appears and reappears with refreshes. Any idea what the problem could be?
EDIT: Here's the code, just to clarify that there's NO hanging if statement.
{% extends 'master.html'%}
{% load thumbnail %}
{% load tags %}
{% block 'title' %}
{{ title }}
{% endblock %}
{% block 'content' %}
<div id="feed" class="content">
{% for book in books.object_list %}
<div class="book_preview">
<div class="thumbnail">
<a href="/book/{{ book.id }}/{{ book.get_slug }}/">
{% if book.cover_image %}
{% thumbnail book.cover_image "120" as im %}
<img src="{{ im.url }}" alt="Python for Software Design"/>
{% endthumbnail %}
{% else %}
<img src="{{ STATIC_URL }}default_thumb.jpg" alt="Python for Software Design"/>
{% endif %}
</a>
</div>
<div class="book_details">
<h2 class="book_title">
<a class="book_profile_link" href="/book/{{ book.id }}/{{ book.get_slug }}/">{{ book.title }}</a>
{% if user != book.uploader %}
<a class="shelf_adder {% add_pinned_status request book.pk %}" href="/shelf/{{ book.id }}/toggle/?next={{ request.get_full_path }}" title="Toggle shelf status"></a>
{% endif %}
</h2>
<h3 class="book_subtitle">
{% if book.subtitle %}
{{ book.subtitle }}
{% else %}
<a href='/book/{{book.id}}/edit/#subtitle'>Provide subtitle</a>
{% endif %}
</h3>
<h3 class="book_authors"> by {{ book.author.filter|join:", " }}</h3>
<div class="book_description">
{% if book.description %}
<p>
{{ book.description|truncatewords:25 }}
</p>
{% else %}
<p class="message">No description available. Create one.</p>
{% endif %}
</div>
<div class="book_links">
<a href="/book/{{ book.id }}/{{ book.get_slug }}/" class="book_profile_link" title="Book profile">
Book profile
</a>
<a href="http://{{ book.homepage }}" class="book_website_link" title="Book website" target="_blank">
Book website
</a>
</div>
<p>Points: {{ book.shelf_additions }}</p>
<div class="book_tags">
{% if book.topics.all %}
{% for topic in book.topics.filter %}
{{ topic }}
{% endfor %}
{% else %}
<a href="/book/{{ book.id }}/edit/#topics" title='Click to add'>no topics added☹</a>
{% endif %}
</div>
</div>
<div style="clear: both;"></div>
</div>
{% endfor %}
<div class="pagination">
{% if books.has_previous %}
previous
{% endif %}
<span class="current">
Page {{ books.number }} of {{ books.paginator.num_pages }}
</span>
{% if books.has_next %}
next
{% endif %}
</div>
</div>
{% endblock %}
The problem starts on the line after the if user != book.uploader statement, which as you can see is terminated with the appropriate endif. I suspect it may be some sort of timeout but I'm not entirely sure. Keep in mind, it works sometimes but randomly stops when using Nginx. It works flawlessly with the dev server.
Django gives that error when you have an unclosed templatetag. In this case an {% if ... %} templatetag.
As to why it only happens in certain scenarios, it might be inside a conditional tag itself, so it's not always processed, but I think Django processes the whole template despite what's going on conditionally or not. It might also be possible that there was some mistake in updating your production site and it's using a different/older version than your development site.
Regardless, the error is the error. Find the unclosed templatetag, and you'll solve it across the board.
UPDATE: The alternative is that the add_pinned_sites templatetag is undefined. Assuming it is in fact loaded in {% load tags %}, make sure that that templatetag library is available in all running environments, i.e. it literally exists on the server. If it is in fact there, make sure you completely reload your Nginx+FastCGI environment, or just reboot the server to be completely sure.
Is "tags" the actual name of the tag library that holds add_pinned_sites? Might be worth changing it to a clearer name-- just wondering if it's possible you're seeing import collisions between that and another tag library (like Django's built-in tags).

django right-to-left language with LANGUAGE_BIDI does not work

I am building a multi-language site with one of the languages "farsi":
Everything worked fine so far, but the right to left language "farsi/persian" is not aligned right, when beginning a next line of text. That means the next line is not aligned at the right as usual for right-to-left languages.
The translation work.
settings.py
gettext = lambda s: s
#default language should be german
LANGUAGE_CODE = 'de'
#LANGUAGE_CODE = 'en'
#LANGUAGE_CODE = 'fa'
LANGUAGES = (
#('fr', gettext('French')),
('de', gettext('German')),
('en', gettext('English')),
('fa', gettext('Farsi')),
#('pt-br', gettext("Brazil")),
)
language_chooser.html
{% load localeurl_tags %}
{% load i18n %}
{% load tabs %}
{% for lang in LANGUAGES %}
{% ifequal lang.0 LANGUAGE_CODE %}
<li class="active"><a>{{ lang.1 }}</a></li>
{% else %}
<!--
{% if LANGUAGE_BIDI %}
<li>The current language is bidirectional</li>
{% else %}
<li>The current language is <b>not</b> bidirectional</li>
{% endif %}
-->
<li class="{% ifactivetab "en" %}active{% else %}inactive{% endifactivetab %}">{{ lang.1 }}</li>
{% endifequal %}
{% endfor %}
in the base.html I also load:
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_current_language_bidi as LANGUAGE_BIDI %}
My django.po file for "farsi/persian" language looks like:
How can I manage this?
Solution:
After defining a new css class "article_right_aligned_language" with the attribute "text-align:right; direction:rtl" and modifying my base template as follows, it works now !!
<div {% if LANGUAGE_BIDI %} class="article_right_aligned_language" {% else %} class="article" {% endif %}>
{% block site_wrapper %}{% endblock %}
</div>
Text alignment is handled by CSS not Django. Set the text-align property on the container element:
.container.right-aligned-language {
text-align: right;
}
Then you can apply the class right-aligned-language to your container (or body tag for that matter) with a conditional statement in your template.
nowadays you should use in CSS:
direction: rtl
http://www.w3schools.com/cssref/pr_text_direction.asp
Use this instead please:
https://github.com/abbas123456/django-right-to-left
CSS is for style and not content.

Django Paginated Comments .. is there any existing solutions?

is there any existing pagination solution for Django contrib.comments?
What I need is just a simple paginated django comments, for the Basic Blog application (from the Django Basic Apps) I used, using a simple has_previous and has_next
I have copied the django.contrib.comments and tried modify the code but with no success. The code is pretty hard to understand (django/contrib/comments/templatetags/comments.py) because it consists of Node and Parser
here is my comments.html template I used for the Blog application:
{% load comments markup %}
{% get_comment_list for object as comment_list %}
{% if comment_list %}
<div class="comments g_7 left">
<a name="comments"></a>
<div class="subtitle">Comments</div>
{% for comment in comment_list %}
{% if comment.is_public %}
<div class="comment g_6" id="c{{ comment.id }}">
<div class="comment_name g_6">
<div class="comment_count right">
<a name="c{{ comment.id }}" href="{{ comment.get_absolute_url }}" {% ifnotequal comment.person_name null %}title="Permalink to {{ comment.person_name }}'s comment"{% endifnotequal %} class="comment_count">{{ forloop.counter }}</a></div>
Wrote by <strong>{% if comment.user_url %}{{ comment.user_name }}{% else %}{{ comment.user_name }}{% endif %}</strong> on {{ comment.submit_date|date:"F j, Y" }} - {{ comment.submit_date|date:"P" }}
</div>
<div class="comment_body g_6">{{ comment.comment|urlizetrunc:"60"|safe }}</div>
</div>
{% endif %}
{% endfor %}
<div class="clear"></div>
</div>
{% else %}
No comments yet.
{% endif %}
I think the problem lies in the get_comment_list templatetags :)
Thanks in advance
I think django-pagination might be what you're looking for.
http://code.google.com/p/django-pagination/ (screencast available)
Django also has a built in Pagination system
https://docs.djangoproject.com/en/dev/topics/pagination/