After looking at the trying all of the recommendations I could find on this subject, my translations still do not work whatsoever.
/settings.py file
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'
LOCALE_PATHS = (
'/Users/samb/Projects/transtest/locale'
)
# Custom Languages
ugettext = lambda s: s
LANGUAGES = (
('de', ugettext('German')),
('en', ugettext('English')),
('fr', ugettext('French')),
('fr-CA', ugettext('French Canadian')),
)
SITE_ID = 1
# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True
# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
view.py
from django.shortcuts import render_to_response
from django.template import RequestContext
def trans(request):
return render_to_response('index.html', context_instance=RequestContext(request))
my template file (index.html)
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
<html>
<head>
<title>translations</title>
</head>
<body>
{% for l in LANGUAGES %}
{{ l }}<br />
{% endfor %}
{{ LANGUAGE_CODE }}<br />
{% trans "Welcome to my site" %}
</body>
</html>
po file (that has been compiled)
located at /Users/samb/Projects/transtest/locale/fr/LC_MESSAGES
#: transtest/templates/index.html:13
msgid "Welcome to my site"
msgstr "Please work"
I can never get the 'Welcome to my site' to work. The LANGUAGES and LANGUAGE_CODE variables in my template are all working (unless I 'Accept_language: fr_CA').
After reading all the other posts on this subject and still having the same problem, I feel like I must have a silly mistake, or am missing a vital step entirely. Any thoughts?
Update: This is how I am testing the translation:
telnet localhost 8000
Connected to localhost.
Escape character is '^]'.
GET /
Accept_language: fr
<html>
<head>
<title>Translations</title>
</head>
<body>
('de', u'Allemand')<br />
('en', u'Anglais')<br />
('fr', u'Fran\xe7ais')<br />
('fr-CA', u'French Canadian')<br />
fr<br />
Welcome to my site
</body>
</html>
Connection closed by foreign host.
I noticed that the languages are getting translated, but the 'Welcome to my site' is not.
The docs say here that LocaleMiddleware ...
... should come after SessionMiddleware, because LocaleMiddleware makes
use of session data. And it should come before CommonMiddleware
because CommonMiddleware needs an activated language in order to
resolve the requested URL.
Maybe it will help when you take account of this in your definition of the MIDDLEWARE_CLASSES.
Related
I have a multiple language app (Django 1.11) with a form to create new users. In this form, the error messages when the user send invalid input must come in Portuguese (pt-BR) or English (en-US) based on the selected language. The custom validations and some of the automatic Django messages for validations are well translated, but not the following: "The password is too similar to the username."; "This password is too short. It must contain at least 8 characters." and "This password is too common.". Actually, they are shown in Portuguese, since the LANGUAGE_CODE from settings.py is 'pt-BR'.
I was able to translate some of the automatic messages such "A user with that username already exists." with django.utils.translation.activate as in the following code.
from django.utils.translation import activate
activate(curr_lang)
But this wasn't enough to translate the validations from settings.AUTH_PASSWORD_VALIDATORS. I manually changed the LANGUAGE_CODE from 'pt-BR' to 'en-US' and was able to see the messages only in English. What is the best strategy to translate these messages? As far as I researched, setting LANGUAGE_CODE is not a option, since the results I find suggest the use of django.utils.translation.activate. Thanks in advance
After several tries, I think the solution was:
Add "django.middleware.locale.LocaleMiddleware" to MIDDLEWARE at settings.py (be careful with the order as explained at the documentation)
MIDDLEWARE = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
...
Add the LANGUAGES const also at settings.py after LANGUAGE_CODE, which has to contain the default language
LANGUAGE_CODE = 'pt-BR'
LANGUAGES = [
('pt-BR', 'Portuguese'),
('en-US', 'English'),
]
Use Django's default set_language method - on urls.py, add the following line:
urlpatterns = [
....
url(r'^i18n/', include('django.conf.urls.i18n')),
And, on the html file with the selection of language,
{% load i18n %}
{% load staticfiles %}
<form action="{% url 'set_language' %}" method="post">{% csrf_token %}
<input name="next" type="hidden" value="{{ redirect_to }}" />
<select name="language" id="curr_lang" class="select2-single" onchange="this.form.submit()">
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
<option value="pt-BR" title="Português" {% if LANGUAGE_CODE == 'pt-br' %}selected{% endif %}>{% static 'img/flags/br.png' %}</option>
<option value="en-US" title="English" {% if LANGUAGE_CODE == 'en-us' %}selected{% endif %}>{% static 'img/flags/us.png' %}</option>
</select>
</form>
On context_processor.py, define a function (I'm calling global_env) to be run at the end of every view. On settings.py, add 'your-application-name-here.context_processor.global_env' such as
TEMPLATES = [
...
'OPTIONS': {
'context_processors': [
'your-application-name-here.context_processor.global_env',
...
And, on context_processor.py, the function must have
def global_env(request):
from django.utils.translation import activate
curr_lang = request.session[LANGUAGE_SESSION_KEY]
activate(curr_lang)
# More code to render dictionary to views for non-default messages on page
....
I think these steps complete the translation of default form validation messages from Django without the need of custom validators.
But if I copy and paste that location into firefox, the template is there...
views.py:
def artists(request):
artists = Artist.objects.all()
template = loader.get_template('artists/index.html')
context = {'artists': artists,}
return HttpResponse(template.render(context, request))
index.html:
{% extends "site_base.html" %}
{% load i18n %}
{% block head_title %}pinax-project-account{% endblock %}
{% block body_class %}home{% endblock %}
{% block body_base %}
<section class="jumbotron">
<div class="container">
{% include "_messages.html" %}
<h1>{% blocktrans %}Welcome to<br>pinax-project-account{% endblocktrans %}</h1>
<p>
{% blocktrans %}
In addition to what is provided by the "zero" project, this project
provides thorough integration with django-user-accounts, adding
comprehensive account management functionality. It is a foundation
suitable for most sites that have user accounts.
{% endblocktrans %}
</p>
{% if not user.is_authenticated %}
{% url "account_login" as login_url %}
{% url "account_signup" as signup_url %}
<p>{% blocktrans %}You can Log In or Sign Up to try out the site.{% endblocktrans %}</p>
{% endif %}
</div>
</section>
<section>
<div class="container">
<h2 class="text-center">{% blocktrans %}What is Pinax?{% endblocktrans %}</h2>
<p class="lead">
{% blocktrans %}
<b>Pinax</b> is an open-source platform based on Django and
intended to provide a starting point for websites. It takes
care of the things that many sites have in common, so you can
focus on what makes your site different.
{% endblocktrans %}
</p>
<div class="feature-columns">
<div>
<i class="fa fa-cubes fa-3x"></i><br>
{% blocktrans %}
<b>Starter projects</b> provide project layout,
scaffolding, already integrated components and
ready-to-go code.
{% endblocktrans %}
</div>
<div>
<i class="fa fa-puzzle-piece fa-3x"></i><br>
{% blocktrans %}
<b>Reusable apps</b> provide common
infrastructure, back-end functionality,
and user-facing components.
{% endblocktrans %}
</div>
<div>
<i class="fa fa-tint fa-3x"></i><br>
{% blocktrans %}
<b>Themes</b> provide default templates and
stylesheets for quick prototyping and easy customization.
{% endblocktrans %}
</div>
</div>
</div>
</section>
<section>
<div class="container">
<p class="lead text-center">
{% blocktrans %}
See pinaxproject.com
for more information.
{% endblocktrans %}
</p>
</div>
</section>
{% endblock %}
Settings.py:
import os
PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__))
BASE_DIR = PACKAGE_ROOT
DEBUG = True
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": "dev.db",
}
}
ALLOWED_HOSTS = [
"localhost",
]
# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# On Unix systems, a value of None will cause Django to use the same
# timezone as the operating system.
# If running in a Windows environment this must be set to the same as your
# system time zone.
TIME_ZONE = "UTC"
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = "en-us"
SITE_ID = int(os.environ.get("SITE_ID", 1))
# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True
# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True
# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/media/"
MEDIA_ROOT = os.path.join(PACKAGE_ROOT, "site_media", "media")
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = "/site_media/media/"
# Absolute path to the directory static files should be collected to.
# Don"t put anything in this directory yourself; store your static files
# in apps" "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = os.path.join(PACKAGE_ROOT, "site_media", "static")
# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = "/site_media/static/"
# Additional locations of static files
STATICFILES_DIRS = [
os.path.join(PROJECT_ROOT, "static", "dist"),
]
STATICFILES_STORAGE = "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = [
"django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
]
# Make this unique, and don't share it with anybody.
SECRET_KEY = "#t_)=9g2nssm4!6rw^vq(1_sqbnxi4zky--b8!crlvp(f1r=ol"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [
os.path.join(PACKAGE_ROOT, "templates"),
os.path.join(BASE_DIR, 'templates/'),
'/home/shawn/Workspace/WebSites/artCollective/ac3/ac3/templates/ac3/',
],
"APP_DIRS": True,
"OPTIONS": {
"debug": DEBUG,
"context_processors": [
"django.contrib.auth.context_processors.auth",
"django.template.context_processors.debug",
"django.template.context_processors.i18n",
"django.template.context_processors.media",
"django.template.context_processors.static",
"django.template.context_processors.tz",
"django.template.context_processors.request",
"django.contrib.messages.context_processors.messages",
"account.context_processors.account",
"pinax_theme_bootstrap.context_processors.theme",
],
},
},
]
MIDDLEWARE = [
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.auth.middleware.SessionAuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "ac3.urls"
# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = "ac3.wsgi.application"
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.messages",
"django.contrib.sessions",
"django.contrib.sites",
"django.contrib.staticfiles",
# theme
"bootstrapform",
"pinax_theme_bootstrap",
# external
"avatar",
"account",
"pinax.eventlog",
"pinax.webanalytics",
# project
"ac3",
"artists",
]
# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"filters": {
"require_debug_false": {
"()": "django.utils.log.RequireDebugFalse"
}
},
"handlers": {
"mail_admins": {
"level": "ERROR",
"filters": ["require_debug_false"],
"class": "django.utils.log.AdminEmailHandler"
}
},
"loggers": {
"django.request": {
"handlers": ["mail_admins"],
"level": "ERROR",
"propagate": True,
},
}
}
FIXTURE_DIRS = [
os.path.join(PROJECT_ROOT, "fixtures"),
]
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
ACCOUNT_OPEN_SIGNUP = True
ACCOUNT_EMAIL_UNIQUE = True
ACCOUNT_EMAIL_CONFIRMATION_REQUIRED = False
ACCOUNT_LOGIN_REDIRECT_URL = "home"
ACCOUNT_LOGOUT_REDIRECT_URL = "home"
ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 2
ACCOUNT_USE_AUTH_AUTHENTICATE = True
AUTHENTICATION_BACKENDS = [
"account.auth_backends.UsernameAuthenticationBackend",
]
I have
spent hours on what should have a trivial solution. Django is looking in the correct location for the template, why can it not be rendered?
Try to remove slash after templates from settings.py in
os.path.join(BASE_DIR, 'templates')
I encountered the same issue, and finally resolved it. If you created the html file in notepad;
copy and paste what you have in the notepad file into a WordPad file.
save as...then select a plain text file in the drop down bar
Goodluck!
After spending too many hours on this, StackOverflow is for the rescue.
I configured my settings.py as below:
...
TIME_ZONE = 'Europe/Berlin'
LANGUAGE_CODE = 'de'
LANGUAGES = (
('en', u'English'),
('de', u'German'),
('fr', u'French'),
)
USE_I18N = True
USE_L10N = True
MIDDLEWARE_CLASSES = (
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
)
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.request',
'django.core.context_processors.static',
'django.contrib.messages.context_processors.messages',
)
...
In my base.html file, I have a form as below:
<form action="/i18n/setlang/" method="post">
{% csrf_token %}
<input name="next" type="hidden" value="/" />
<select name="language">
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}">{{ language.name_local }} ({{ language.code }})</option>
{% endfor %}
</select>
<input type="submit" value="Go" />
</form>
My urls.py:
urlpatterns = patterns('',
url(r'^i18n/', include('django.conf.urls.i18n')),
url(r'^$', 'MainApp.views.index'), #root
)
In the same base.html file, I have on top {% load i18n %} and in the body, I have a sample {% trans "This is the title." %}. Before running the server, I did:
django-admin.py makemessages -l de
django-admin.py makemessages -l fr
The sample text above was picked up by makemessages, and I provided the respective translations for msgstr. After that, I did django-admin.py compilemessages. The command ran nicely and generated the .mo files in the respective locale folders.
I run the server and the the form does not work. From a another StackOverflow post, I was hinted to remove the #, fuzzy lines, which I did. What am I doing wrong?
Thanks!
You should put the LocaleMiddleware after the SessionMiddleware in your MIDDLEWARE_CLASSES:
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
....
)
The order of middleware classes is important. The LocaleMiddleware uses session data to detect the user language, so it must come after the SessionMiddleware. It is also mentioned in the docs here https://docs.djangoproject.com/en/1.3/topics/i18n/deployment/#how-django-discovers-language-preference
Let's hope this works for you!
I'm trying to use django-localeurl in one of my project, but following the docs I just get an Error. What I want, is make work this code in the template:
{% load i18n %}
{% load localeurl_tags %}
{% get_available_languages as LANGUAGES %}
{% get_current_language as LANGUAGE_CODE %}
{% for lang in LANGUAGES %}
{% ifequal lang.0 LANGUAGE_CODE %}
<li class="selected">{{ lang.1 }}</li>
{% else %}
<li>{{ lang.1 }}</li>
{% endifequal %}
{% endfor %}
it's from: http://packages.python.org/django-localeurl/usage.html
I got this error
Caught AssertionError while rendering: URL must start with SCRIPT_PREFIX:
The problem is in this line:
<li>{{ lang.1 }}</li>
request.path is an empty string. but why? in the browser I can see 127.0.0.1/hu/, so If I'm right It should contain /hu/.
I created a brand new project just with django 1.3 and django-localeurl in the virtual environment, for simplicity.
My settings.py looks like (the important parts as I know):
LANGUAGES = (
('hu', 'Hungarian'),
('en', 'English'),
('sk', 'Slovakian'),
)
LANGUAGE_CODE = 'hu'
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
# 'django.template.loaders.eggs.Loader',
)
MIDDLEWARE_CLASSES = (
'localeurl.middleware.LocaleURLMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
)
TEMPLATE_CONTEXT_PROCESSORS = (
"django.contrib.auth.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.request",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.static",
"django.contrib.messages.context_processors.messages",
)
INSTALLED_APPS = (
'localeurl',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
# Uncomment the next line to enable the admin:
# 'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
)
What Am I missing?
Edit 1:
I can put the request.path manually to the context:
def main(request):
return render_to_response( 'base.html', {'rpath': request.path})
than I use rpath in the template instead of request.path, but, but.... request.path should contain something, because of django.core.context_processors.request in the TEMPLATE_CONTEXT_PROCESSORS.
The problem was not related to localeurl, with the following view works:
return render_to_response( 'base.html', {}, context_instance = RequestContext(request))
I thought putting django.core.context_processors.request into TEMPLATE_CONTEXT_PROCESSORS do the job, but not.
Locale URL middleware hacks request.path I think what you're looking for is request.path_info
In your view, when returning a response, specify the context_instance like this:
from django.shortcuts import render_to_response
from django.template.context import RequestContext
return render_to_response('base.html',{'object':object},context_instance=RequestContext(request))
I used django 1.2 before and didn't have any problem switching language... In my template i have this...
<form action="/i18n/setlang/" method="post" class="forms">
{% csrf_token %}
<input name="next" type="hidden" value="/next/page/" />
<select name="language" id="select_langauge" class="m_show hide">
{% for lang in LANGUAGES %}
{% if lang.0 != '' %}
<option value="{{lang.0}}">{{lang.1}}</option>
{% endif %}
{% endfor %}
</select>
This was working fine with django 1.2. But since upgraded to Django 1.3 this does not work. I can see that LANGUAGE_CODE changes, but the actual language output is not what I was expecting.
However, when i restart django server, it shows correct language. What am i missing???
I have this in my settings.py
LANGUAGE_CODE = 'en-us'
SITE_ID = 1
USE_I18N = True
gettext = lambda s: s
LANGUAGES = (
('', gettext('Please select')),
('en', gettext('English')),
('ko', gettext('Korean')),
)
USE_L10N = True
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.middleware.locale.LocaleMiddleware',
)
I figured out.
To change language dynamically, using ugettext_lazy() fixed the problem. (Before I was using ugettext).
Reference: https://docs.djangoproject.com/en/1.3/topics/i18n/internationalization/#lazy-translation