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

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)

Related

Display language icons in Django template

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.

how to pass language between templates in django admin

I 'm overriding django-admin templates to add a language choice links.
I added this:
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<a href="/{{ language.code }}{{ request.get_full_path|slice:'3:' }}"
class="{% if language.code == LANGUAGE_CODE %}selected{% endif %}"
lang="{{ language.code }}">
{{ language.name_local }}
</a>
{% endfor %}
in both base_site.html and login.html.
They work fine
The problem is that I always get the default language in the dashboard.
For example:
If I choose Frensh in the login page, the login page gets translated into frensh but after I login, I find the dashboard and other pages in the default language.
How can I fix this, in order to display the dashboard in the language chosen from the login page
I finally fixed it.
I changed the href in the login.html as follows:
<a href="/{{ language.code }}{{ request.get_full_path|slice:'3:23' }}{{ language.code }}/admin/"
Infact, the login url is as follows : /fr/admin/login/?next=/fr/admin/
so I need to keep in mind the next page url.
I just needed to change the language code in the actual page slice:'3:' and in the next page slice:':23'.

Django csrf forbidden on url variation

Hi I have an html template for switching languages on my site:
<form action="{{ SITE_URL }}i18n/setlang/" name="postlink" method="post">{% csrf_token %}
<ul class="lang">
<li class="lang">
{% for lang in LANGUAGES %}
{% if lang.0 != LANGUAGE_CODE %}
<input type="hidden" name="language" value="{{ lang.0 }}">
<a class="active" href=# onclick="submitPostLink()">{{ lang.1 }}</a>
{% else %}
{{ lang.1 }}
{% endif %}
{% if forloop.last %}{% else %} | {% endif %}
{% endfor %}
</li>
</ul>
</form>
All this works fine on the dev server and in production and in production at the normal url of www.mysite.com/project/
However, if I try project.mysite.com or mysite.com.project I get my home page as normal but changing the language brings up the 403 Forbidden failure.
Do I need to define the root url variations I need for setlang somewhere?
Any help much appreciated.
Since these urls are running on different subdomains, you should check the domain setting for the CSRF cookie CSRF_COOKIE_DOMAIN: https://docs.djangoproject.com/en/1.3/ref/contrib/csrf/#subdomains

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.