Permalink
Browse files

Readme updated. Version number updated. Code cleanup.

  • Loading branch information...
1 parent d2bd08d commit 082651ccdab5ce6d621068c89785e02528f16d66 @brocaar committed Dec 27, 2011
View
@@ -3,8 +3,8 @@ Django URL internationalization
This Django app makes it possible to prefix URL patterns with the active
language and to make URL patterns translatable by using gettext. As well this
-package contains a patch for the ``LocaleMiddleware`` so it is able to activate
-the right language (based on the language-prefix in the requested URL).
+package contains a middleware which is able to activate the right language
+(based on the language-prefix in the requested URL).
.. note::
@@ -13,10 +13,7 @@ the right language (based on the language-prefix in the requested URL).
included in Django 1.4 (thanks to Jannis Leidel and Russell Keith-Magee for
their feedback and reviewing the patch).
-
- In the 0.6 version of this package, I rewrote the API so that it will match
- with the upcoming Django 1.4 version. You can read more about this in the
- `Django documentation (dev) <http://docs.djangoproject.com/en/dev/topics/i18n/internationalization/#specifying-translation-strings-in-url-patterns>`_.
+ Django documentation: `Internationalization: in URL patterns <https://docs.djangoproject.com/en/dev/topics/i18n/translation/#internationalization-in-url-patterns>`_.
Translating URL patterns
@@ -60,20 +57,50 @@ the URL in the active language. Example::
'/nl/nieuws/categorie/recent/'
+Reversing in templates
+----------------------
+
+If localized URLs get reversed in templates they always use the current
+language. To link to a URL in another language use the ``language`` template
+tag. It enables the given language in the enclosed template section::
+
+ {% load i18nurls i18n %}
+
+ {% get_available_languages as languages %}
+
+ {% trans "View this category in:" %}
+ {% for lang_code, lang_name in languages %}
+ {% language lang_code %}
+ <a href="{% url category slug=category.slug %}">{{ lang_name }}</a>
+ {% endlanguage %}
+ {% endfor %}
+
+
+See also: `Reversing in templates <https://docs.djangoproject.com/en/dev/topics/i18n/translation/#std:templatetag-language>`_.
+
+
Installation
------------
* Install the ``django-i18nurls`` package (eg: ``pip install django-i18nurls``).
* Add ``i18nurls`` to your ``settings.INSTALLED_APPS``.
-* Add ``django.middleware.locale.LocaleMiddleware`` to your ``settings.MIDDLEWARE_CLASSES``
- (if it is not already there, make sure it comes before the ``CommonMiddleware``).
+* Add ``i18nurls.middleware.LocaleMiddleware`` to your
+ ``settings.MIDDLEWARE_CLASSES`` (make sure it comes before the
+ ``CommonMiddleware``).
Changelog
---------
+v0.7
+~~~~
+
+* ``{% language %}`` template-tag implemented (thanks to Harro van der Klauw).
+* ``LocaleMiddleware`` class is not patched anymore (Issue #3).
+* ``i18n_patterns`` is not patched anymore.
+
v0.6.1
~~~~~~
View
@@ -1,4 +1,2 @@
-# Import modules to apply the monkeypatches
-from i18nurls import i18n
+# Apply the monkeypatches
from i18nurls import urlresolvers
-from i18nurls import middleware
View
@@ -9,7 +9,3 @@ def i18n_patterns(prefix, *args):
if not settings.USE_I18N:
return pattern_list
return [LocaleRegexURLResolver(pattern_list)]
-
-
-from django.conf.urls import i18n
-setattr(i18n, 'i18n_patterns', i18n_patterns)
View
@@ -3,50 +3,48 @@
from django.conf import settings
from django.core.urlresolvers import get_resolver
from django.http import HttpResponseRedirect
-from django.middleware.locale import LocaleMiddleware
+from django.middleware.locale import LocaleMiddleware as DjangoLocaleMiddleware
from django.utils import translation
from django.utils.cache import patch_vary_headers
-from i18nurls.monkeypatch import monkeypatch_class
from i18nurls.urlresolvers import LocaleRegexURLResolver
language_code_prefix_re = re.compile(r'^/([\w-]+)/')
-class I18NLocaleMiddleware(LocaleMiddleware):
-
- __metaclass__ = monkeypatch_class
-
+
+class LocaleMiddleware(DjangoLocaleMiddleware):
+
def process_request(self, request):
language_code = self.get_language_from_path(request.path_info)
-
+
if not language_code:
language_code = translation.get_language_from_request(request)
-
+
translation.activate(language_code)
request.LANGUAGE_CODE = translation.get_language()
-
+
def process_response(self, request, response):
language_code = translation.get_language()
translation.deactivate()
-
+
if (response.status_code == 404 and
not self.get_language_from_path(request.path_info)
and self.is_language_prefix_patterns_used()):
return HttpResponseRedirect(
'/%s%s' % (language_code, request.get_full_path()))
-
+
patch_vary_headers(response, ('Accept-Language',))
if 'Content-Language' not in response:
response['Content-Language'] = language_code
return response
-
+
def is_language_prefix_patterns_used(self):
for url_pattern in get_resolver(None).url_patterns:
if isinstance(url_pattern, LocaleRegexURLResolver):
return True
return False
-
+
def get_language_from_path(self, path):
regex_match = language_code_prefix_re.match(path)
if regex_match:
View
@@ -1,5 +1,6 @@
def monkeypatch_class(name, bases, namespace):
- # Source: http://mail.python.org/pipermail/python-dev/2008-January/076194.html
+ # Source:
+ # http://mail.python.org/pipermail/python-dev/2008-January/076194.html
assert len(bases) == 1, "Exactly one base class required"
base = bases[0]
for name, value in namespace.iteritems():
View
@@ -1,30 +1,27 @@
-import os
-
-from django.core.urlresolvers import clear_url_caches
from django.conf import settings
+from django.core.urlresolvers import clear_url_caches
from django.test import TestCase
-from django.utils.translation import activate
class BaseTestCase(TestCase):
-
+
def _update_setting(self, key, value):
if not key in self.old_settings:
self.old_settings[key] = getattr(settings, key)
setattr(settings, key, value)
-
+
def setUp(self):
clear_url_caches()
-
+
self.old_settings = {}
-
+
self._update_setting('DEBUG', True)
self._update_setting('TEMPLATE_DEBUG', True)
-
+
self._update_setting('ROOT_URLCONF',
'i18nurls.tests.urls'
)
-
+
self._update_setting('MIDDLEWARE_CLASSES', (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
@@ -33,12 +30,12 @@ def setUp(self):
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
))
-
+
self._update_setting('LANGUAGES', (
('nl', 'Dutch'),
('en', 'English'),
))
-
+
def tearDown(self):
for key in self.old_settings:
setattr(settings, key, self.old_settings[key])
@@ -5,13 +5,13 @@
class PrefixTest(BaseTestCase):
-
+
def test_not_prefixed_url(self):
activate('en')
self.assertEqual(reverse('not-prefixed'), '/not-prefixed/')
activate('nl')
self.assertEqual(reverse('not-prefixed'), '/not-prefixed/')
-
+
def test_prefixed_url(self):
activate('en')
self.assertEqual(reverse('prefixed'), '/en/prefixed/')
@@ -20,7 +20,7 @@ def test_prefixed_url(self):
class TranslationTest(BaseTestCase):
-
+
def test_url(self):
activate('en')
self.assertEqual(reverse('news'), '/en/news/')
@@ -29,71 +29,84 @@ def test_url(self):
class NamespaceTest(BaseTestCase):
-
+
def test_namespace(self):
activate('en')
self.assertEqual(reverse('users:register'), '/en/users/register/')
activate('nl')
- self.assertEqual(reverse('users:register'), '/nl/gebruikers/registeren/')
+ self.assertEqual(
+ reverse('users:register'), '/nl/gebruikers/registeren/')
class RedirectTest(BaseTestCase):
-
+
def test_en_redirect(self):
- response = self.client.get('/users/register/', HTTP_ACCEPT_LANGUAGE='en')
+ response = self.client.get(
+ '/users/register/', HTTP_ACCEPT_LANGUAGE='en')
self.assertEqual(response.status_code, 302)
self.assertEqual(response.has_header('location'), True)
- self.assertEqual(response['location'], 'http://testserver/en/users/register/')
-
+ self.assertEqual(
+ response['location'], 'http://testserver/en/users/register/')
+
response = self.client.get(response['location'])
self.assertEqual(response.status_code, 200)
-
+
def test_en_redirect_wrong_url(self):
- response = self.client.get('/gebruikers/registeren/', HTTP_ACCEPT_LANGUAGE='en')
+ response = self.client.get(
+ '/gebruikers/registeren/', HTTP_ACCEPT_LANGUAGE='en')
self.assertEqual(response.status_code, 302)
self.assertEqual(response.has_header('location'), True)
- self.assertEqual(response['location'], 'http://testserver/en/gebruikers/registeren/')
-
+ self.assertEqual(
+ response['location'],
+ 'http://testserver/en/gebruikers/registeren/'
+ )
+
response = self.client.get(response['location'])
self.assertEqual(response.status_code, 404)
-
+
def test_nl_redirects(self):
- response = self.client.get('/gebruikers/registeren/', HTTP_ACCEPT_LANGUAGE='nl')
+ response = self.client.get(
+ '/gebruikers/registeren/', HTTP_ACCEPT_LANGUAGE='nl')
self.assertEqual(response.status_code, 302)
self.assertEqual(response.has_header('location'), True)
- self.assertEqual(response['location'], 'http://testserver/nl/gebruikers/registeren/')
-
+ self.assertEqual(
+ response['location'],
+ 'http://testserver/nl/gebruikers/registeren/'
+ )
+
response = self.client.get(response['location'])
self.assertEqual(response.status_code, 200)
-
+
def test_nl_redirects_wrong_url(self):
- response = self.client.get('/users/register/', HTTP_ACCEPT_LANGUAGE='nl')
+ response = self.client.get(
+ '/users/register/', HTTP_ACCEPT_LANGUAGE='nl')
self.assertEqual(response.status_code, 302)
self.assertEqual(response.has_header('location'), True)
- self.assertEqual(response['location'], 'http://testserver/nl/users/register/')
-
+ self.assertEqual(
+ response['location'], 'http://testserver/nl/users/register/')
+
response = self.client.get(response['location'])
self.assertEqual(response.status_code, 404)
class ResponseTest(BaseTestCase):
-
+
def test_en_url(self):
response = self.client.get('/en/users/register/')
self.assertEqual(response.status_code, 200)
self.assertEqual(response['content-language'], 'en')
self.assertEqual(response.context['LANGUAGE_CODE'], 'en')
-
+
def test_nl_url(self):
response = self.client.get('/nl/gebruikers/registeren/')
self.assertEqual(response.status_code, 200)
self.assertEqual(response['content-language'], 'nl')
self.assertEqual(response.context['LANGUAGE_CODE'], 'nl')
-
+
def test_wrong_en_prefix(self):
response = self.client.get('/en/gebruikers/registeren/')
self.assertEqual(response.status_code, 404)
-
+
def test_wrong_nl_prefix(self):
response = self.client.get('/nl/users/register/')
self.assertEqual(response.status_code, 404)
View
@@ -1,16 +1,36 @@
-from django.conf.urls.i18n import i18n_patterns
from django.conf.urls.defaults import patterns, include, url
from django.utils.translation import ugettext_lazy as _
from django.views.generic import TemplateView
+from i18nurls.i18n import i18n_patterns
urlpatterns = patterns('',
- url(r'^not-prefixed/$', TemplateView.as_view(template_name='i18nurls/dummy.html'), name='not-prefixed'),
- url(r'^news/$', TemplateView.as_view(template_name='i18nurls/dummy.html'), name='news-no-i18n'),
+ url(
+ r'^not-prefixed/$',
+ TemplateView.as_view(template_name='i18nurls/dummy.html'),
+ name='not-prefixed'
+ ),
+ url(
+ r'^news/$',
+ TemplateView.as_view(template_name='i18nurls/dummy.html'),
+ name='news-no-i18n'
+ ),
)
urlpatterns += i18n_patterns('',
- url(r'^prefixed/$', TemplateView.as_view(template_name='i18nurls/dummy.html'), name='prefixed'),
- url(_(r'^news/$'), TemplateView.as_view(template_name='i18nurls/dummy.html'), name='news'),
- url(_(r'^users/'), include('i18nurls.tests.user_urls', namespace='users')),
+ url(
+ r'^prefixed/$',
+ TemplateView.as_view(template_name='i18nurls/dummy.html'),
+ name='prefixed'
+ ),
+ url(
+ _(r'^news/$'),
+ TemplateView.as_view(template_name='i18nurls/dummy.html'),
+ name='news'
+ ),
+ url(
+ _(r'^users/'),
+ include('i18nurls.tests.user_urls',
+ namespace='users')
+ ),
)
@@ -4,5 +4,9 @@
urlpatterns = patterns('',
- url(_(r'register/$'), TemplateView.as_view(template_name='i18nurls/dummy.html'), name='register'),
+ url(
+ _(r'register/$'),
+ TemplateView.as_view(template_name='i18nurls/dummy.html'),
+ name='register'
+ ),
)
Oops, something went wrong.

0 comments on commit 082651c

Please sign in to comment.