2012-11-29 9 views
14

Ho un multi-lingua Django app esistente che sto porting su Django 1.4. Il supporto I18n è attualmente basato su alcuni brutti hack, mi piacerebbe farlo usare i moduli i18n integrati di Django.Django lingua predefinita i18n senza percorso prefissi

Un vincolo è che io non voglio cambiare gli URL che sono già in atto. Questo sito è attivo da un po 'e ci sono collegamenti esterni ad esso che non voglio rompere o reindirizzare. Lo schema di URL funziona così: il contenuto inglese è alla radice del sito, mentre altri linguaggi utilizzano prefissi nel nome di dominio:

gli URL inglesi:

/ 
/articles/ 
/suggestions/ 

gli URL spagnoli:

/es/ 
/es/articulos/ 
/es/sugerencias/ 

ho le pagine tradotte che lavorano con i moduli i18n Django 1,4 s, ma davvero, davvero, davvero vuole mettere tutti gli URL inglese sotto/it /. Ho provato un paio di hack diversi, tra cui la definizione di URL non internazionalizzato per la versione inglese:

def build(callback): 
    return callback('', 
    url(_(r'^$'), home.index, name="home"), 
    url(_(r'^articles/$'), content.article_list, name='article_list'), 
    url(_(r'^suggestions/$'), suggestions.suggestions, name='suggestions'), 
) 

urlpatterns = build(patterns) 
urlpatterns += build(i18n_patterns) 

Questo rende gli URL risolvere correttamente, ma il tag {% url%} faccia risoluzione inversa non funziona .

Qual è il modo migliore per realizzare non prefissati gli URL in lingua inglese?

+0

solo una questione: è il vostro '_' la versione non-pigro fo gettext? vale a dire 'da django.utils.translation importazione ugettext come _' –

+0

No, è la versione pigro: django.utils.translation.ugettext_lazy –

+0

si può provare con la versione non pigro e vedere se funziona? –

risposta

9

UPDATE: Leggi risposta soffietto, Django 1.10 supporta nativamente

Ho affrontato questo problema e risolto in questo modo:

  • Creato un'alternativa i18n_patterns che non prefisso lingua principale sito (definito in settings.LANGUAGE_CODE).

  • creato un middleware alternativo che utilizza solo il linguaggio prefissi URL per attivare la lingua corrente.

Non ho visto alcun effetto collaterale utilizzando questa tecnica.

Il codice:

# coding: utf-8 
""" 
Cauê Thenório - cauelt(at)gmail.com 

This snippet makes Django do not create URL languages prefix (i.e. /en/) 
for the default language (settings.LANGUAGE_CODE). 

It also provides a middleware that activates the language based only on the URL. 
This middleware ignores user session data, cookie and 'Accept-Language' HTTP header. 

Your urls will be like: 

In your default language (english in example): 

    /contact 
    /news 
    /articles 

In another languages (portuguese in example): 

    /pt/contato 
    /pt/noticias 
    /pt/artigos 

To use it, use the 'simple_i18n_patterns' instead the 'i18n_patterns' 
in your urls.py: 

    from this_sinppet import simple_i18n_patterns as i18n_patterns 

And use the 'SimpleLocaleMiddleware' instead the Django's 'LocaleMiddleware' 
in your settings.py: 

    MIDDLEWARE_CLASSES = (
    ... 
     'this_snippet.SimpleLocaleMiddleware' 
    ... 
    ) 

Works on Django >=1.4 
""" 

import re 

from django.conf import settings 
from django.conf.urls import patterns 
from django.core.urlresolvers import LocaleRegexURLResolver 
from django.middleware.locale import LocaleMiddleware 
from django.utils.translation import get_language, get_language_from_path 
from django.utils import translation 


class SimpleLocaleMiddleware(LocaleMiddleware): 

    def process_request(self, request): 

     if self.is_language_prefix_patterns_used(): 
      lang_code = (get_language_from_path(request.path_info) or 
         settings.LANGUAGE_CODE) 

      translation.activate(lang_code) 
      request.LANGUAGE_CODE = translation.get_language() 


class NoPrefixLocaleRegexURLResolver(LocaleRegexURLResolver): 

    @property 
    def regex(self): 
     language_code = get_language() 

     if language_code not in self._regex_dict: 
      regex_compiled = (re.compile('', re.UNICODE) 
           if language_code == settings.LANGUAGE_CODE 
           else re.compile('^%s/' % language_code, re.UNICODE)) 

      self._regex_dict[language_code] = regex_compiled 
     return self._regex_dict[language_code] 


def simple_i18n_patterns(prefix, *args): 
    """ 
    Adds the language code prefix to every URL pattern within this 
    function, when the language not is the main language. 
    This may only be used in the root URLconf, not in an included URLconf. 

    """ 
    pattern_list = patterns(prefix, *args) 
    if not settings.USE_I18N: 
     return pattern_list 
    return [NoPrefixLocaleRegexURLResolver(pattern_list)] 

Il codice di cui sopra è disponibile su: https://gist.github.com/cauethenorio/4948177

+0

'da django.conf.urls importare patterns' non esiste – PvdL

+1

@PvdL per le versioni più recenti di Django si dovrebbe utilizzare la soluzione nativa: https://docs.djangoproject.com/en/1.10/topics/i18n/translation/# prefisso-in-url-pattern –

+2

Grazie, completamente trascurato il kwarg di 'i18n_patterns (* urls, prefix_default_language = True)' – PvdL

11

Django 1.10 lo supporta in modo nativo.Come si dice nel documento:

i18n_patterns (* URL, prefix_default_language = True)

Questa funzione può essere utilizzata in un URLconf radice e Django automaticamente anteporre al codice lingua attiva corrente tutti i modelli di URL definiti all'interno di i18n_patterns().

L'impostazione prefisso_alfabeto predefinito su False rimuove il prefisso dalla lingua predefinita (LANGUAGE_CODE). Questo può essere utile quando si aggiungono traduzioni al sito esistente in modo che gli URL correnti non cambino.

Fonte: https://docs.djangoproject.com/en/1.10/topics/i18n/translation/#language-prefix-in-url-patterns