2012-11-29 39 views
14

Tôi có một ứng dụng Django đa ngôn ngữ hiện có mà tôi đang chuyển sang Django 1.4. I18n hỗ trợ hiện đang dựa trên một số hacks xấu xí, tôi muốn làm cho nó sử dụng mô-đun i18n tích hợp của Django.Ngôn ngữ mặc định Django i18n không có tiền tố đường dẫn

Một hạn chế là tôi không muốn thay đổi các url đã có sẵn. Trang web này đã hoạt động được một lúc và có các liên kết bên ngoài với trang web mà tôi không muốn phá vỡ hoặc chuyển hướng. Đề án url làm việc như thế này: Nội dung tiếng Anh là cội rễ của trang web, trong khi các ngôn ngữ khác sử dụng tiền tố trong tên miền:

url tiếng Anh:

/ 
/articles/ 
/suggestions/ 

url Tây Ban Nha:

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

Tôi đã có các trang dịch làm việc với các mô-đun i18n của Django 1.4, nhưng nó thực sự, thực sự, thực sự muốn đặt tất cả các url tiếng Anh dưới/en /. Tôi đã thử một vài hacks khác nhau, bao gồm cả việc xác định các url phi quốc tế hóa cho phiên bản tiếng Anh:

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) 

Điều này làm cho các url giải quyết đúng cách, nhưng {% url%} thẻ để làm độ phân giải ngược lại không hoạt động .

Cách tốt nhất để hoàn thành các url tiếng Anh không có tiền tố là gì?

+0

chỉ là một câu hỏi: nó là '_' phiên bản không lười biếng của bạn fo gettext? tức là 'từ django.utils.translation nhập ugettext dưới dạng _' –

+0

Không, đó là phiên bản lười: django.utils.translation.ugettext_lazy –

+0

bạn có thể dùng thử phiên bản không lười và xem nó có hoạt động không? –

Trả lời

9

UPDATE: Đọc câu trả lời dưới đây, Django 1.10 hỗ trợ nó natively

tôi phải đối mặt với vấn đề này và giải quyết theo cách này:

  • tạo một sự thay thế i18n_patterns mà không tiền tố ngôn ngữ chính trang web (được xác định trong settings.LANGUAGE_CODE).

  • Tạo một phần mềm trung gian thay thế chỉ sử dụng ngôn ngữ tiền tố URL để kích hoạt ngôn ngữ hiện tại.

Tôi không thấy bất kỳ tác dụng phụ nào khi sử dụng kỹ thuật này.

Mã:

# 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)] 

Đoạn mã trên có sẵn trên: https://gist.github.com/cauethenorio/4948177

+0

'từ các mẫu nhập django.conf.urls' không tồn tại – PvdL

+1

@PvdL cho các phiên bản django mới hơn, bạn nên sử dụng giải pháp gốc: https://docs.djangoproject.com/en/1.10/topics/i18n/translation/# ngôn ngữ-tiền tố-trong-url-pattern –

+2

Cảm ơn, hoàn toàn bỏ qua các kwarg của 'i18n_patterns (* url, prefix_default_language = True)' – PvdL

11

Django 1.10 hỗ trợ nó nguyên bản.Khi họ nói trong doc:

i18n_patterns (* url, prefix_default_language = True)

Chức năng này có thể được sử dụng trong một URLconf gốc và Django sẽ tự động thêm vào trước mã ngôn ngữ hoạt động hiện tại để tất cả các mẫu url được xác định trong phạm vi i18n_patterns().

Đặt tiền tố_default_language thành False sẽ xóa tiền tố khỏi ngôn ngữ mặc định (LANGUAGE_CODE). Điều này có thể hữu ích khi thêm bản dịch vào trang web hiện tại để các URL hiện tại sẽ không thay đổi.

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

Các vấn đề liên quan