Esempio n. 1
0
def redirect_to_best_locale(request: HttpRequest, translations: List[str]) -> HttpResponseRedirect:
    # Note that translations is list of locale strings (eg ["en-GB", "ru", "fr"])
    lang = get_best_translation(translations, get_accept_languages(request))
    response = HttpResponseRedirect("/" + "/".join([lang, split_path(request.get_full_path())[1]]))
    # Add the Vary header to avoid wrong redirects due to a cache
    response["Vary"] = "Accept-Language"
    return response
Esempio n. 2
0
def redirect_to_locale(request, locale, permanent=False):
    redirect_class = HttpResponsePermanentRedirect if permanent else HttpResponseRedirect
    response = redirect_class(
        "/" + "/".join([locale, split_path(request.get_full_path())[1]]))
    # Add the Vary header to avoid wrong redirects due to a cache
    response["Vary"] = "Accept-Language"
    return response
def test_split_path(path, result):
    res = split_path(path)
    assert res == result
Esempio n. 4
0
def render(request, template, context=None, **kwargs):
    """
    Same as django's render() shortcut, but with l10n template support.
    If used like this::

        return l10n_utils.render(request, 'myapp/mytemplate.html')

    ... this helper will render the following template::

        l10n/LANG/myapp/mytemplate.html

    if present, otherwise, it'll render the specified (en-US) template.
    """
    context = {} if context is None else context

    # Make sure we have a single template
    if isinstance(template, list):
        template = template[0]

    # Every template gets its own .lang file, so figure out what it is
    # and pass it in the context
    context['template'] = template
    context['langfile'] = get_lang_path(template)
    context['template_source_url'] = template_source_url(template)

    # Get the available translation list of the current page
    context.setdefault('translations', {})
    context['translations'].update(translations_for_template(template))

    # Look for localized template if not default lang.
    if hasattr(request, 'locale') and request.locale != settings.LANGUAGE_CODE:

        # Redirect to one of the user's accept languages or the site's default
        # language (en-US) if the current locale not active
        if not template_is_active(template, get_locale(request)):
            # Use the default (en-US) template to render instead of redirecting
            # if the template is not localized yet but the content itself is
            # localized. This is useful especially for legal documents where the
            # content is translated in the external legal-docs repository.
            if context.get('localized', False):
                return django_render(request, template, context, **kwargs)

            matched = None

            # Look for the user's Accept-Language HTTP header to find another
            # locale we can offer
            for lang in get_accept_languages(request):
                if template_is_active(template, lang):
                    matched = lang
                    break

            # Check for the fallback locales if the previous look-up doesn't
            # work. This is useful especially in the Spanish locale where es-ES
            # should be offered as the fallback of es, es-AR, es-CL and es-MX
            if not matched:
                for lang in get_accept_languages(request):
                    lang = settings.FALLBACK_LOCALES.get(lang)
                    if lang and template_is_active(template, lang):
                        matched = lang
                        break

            # If all the attempts failed, just use en-US, the default locale of
            # the site
            if not matched:
                matched = settings.LANGUAGE_CODE

            response = HttpResponseRedirect('/' + '/'.join(
                [matched, split_path(request.get_full_path())[1]]))

            # Add the Vary header to avoid wrong redirects due to a cache
            response['Vary'] = 'Accept-Language'

            return response

        # Render try #1: Look for l10n template in locale/{{ LANG }}/templates/
        l10n_tmpl = '%s/templates/%s' % (request.locale, template)
        try:
            return django_render(request, l10n_tmpl, context, **kwargs)
        except TemplateDoesNotExist:
            pass

        # Render try #2: Look for locale-specific template in app/templates/
        locale_tmpl = '.{}'.format(request.locale).join(splitext(template))
        try:
            return django_render(request, locale_tmpl, context, **kwargs)
        except TemplateDoesNotExist:
            pass

    # Render try #3: Render originally requested/default template
    return django_render(request, template, context, **kwargs)
Esempio n. 5
0
def test_split_path(path, result):
    res = split_path(path)
    assert res == result
Esempio n. 6
0
def check_split_path(path, result):
    res = split_path(path)
    eq_(res, result)
Esempio n. 7
0
def render(request, template, context=None, ftl_files=None, **kwargs):
    """
    Same as django's render() shortcut, but with l10n template support.
    If used like this::

        return l10n_utils.render(request, 'myapp/mytemplate.html')

    ... this helper will render the following template::

        l10n/LANG/myapp/mytemplate.html

    if present, otherwise, it'll render the specified (en-US) template.
    """
    # use copy() here to avoid modifying the dict in a view that will then
    # be different on the next call to the view.
    context = context.copy() if context else {}
    l10n = None
    ftl_files = ftl_files or context.get('ftl_files')
    locale = get_locale(request)

    # is this a non-locale page?
    name_prefix = request.path_info.split('/', 2)[1]
    nonlocale = name_prefix in settings.SUPPORTED_NONLOCALES

    # Make sure we have a single template
    if isinstance(template, list):
        template = template[0]

    if ftl_files:
        if isinstance(ftl_files, str):
            ftl_files = [ftl_files]

        ftl_files.extend(settings.FLUENT_DEFAULT_FILES)

        context['fluent_l10n'] = l10n = fluent_l10n([locale, 'en'], ftl_files)
    else:
        context['fluent_l10n'] = fluent_l10n([locale, 'en'],
                                             settings.FLUENT_DEFAULT_FILES)

    # Every template gets its own .lang file, so figure out what it is
    # and pass it in the context
    context['template'] = template
    context['langfile'] = get_l10n_path(template)
    context['template_source_url'] = template_source_url(template)

    # if `locales` is given use it as the full list of active translations
    if 'active_locales' in context:
        translations = context['active_locales']
        del context['active_locales']
    else:
        if l10n:
            translations = l10n.active_locales
        else:
            translations = translations_for_template(template)

        # if `add_active_locales` is given then add it to the translations for the template
        if 'add_active_locales' in context:
            translations.extend(context['add_active_locales'])
            del context['add_active_locales']

    context['translations'] = get_translations_native_names(translations)

    # Look for localized template
    if not nonlocale and getattr(request, 'locale', None):
        # Redirect to one of the user's accept languages or the site's default
        # language (en-US) if the current locale not active
        if request.locale not in translations:
            lang = get_best_translation(translations,
                                        get_accept_languages(request))
            response = HttpResponseRedirect(
                '/' +
                '/'.join([lang, split_path(request.get_full_path())[1]]))
            # Add the Vary header to avoid wrong redirects due to a cache
            response['Vary'] = 'Accept-Language'
            return response

        # Render try #1: Look for l10n template in locale/{{ LANG }}/templates/
        l10n_tmpl = '%s/templates/%s' % (request.locale, template)
        try:
            return django_render(request, l10n_tmpl, context, **kwargs)
        except TemplateDoesNotExist:
            pass

        # Render try #2: Look for locale-specific template in app/templates/
        locale_tmpl = '.{}'.format(request.locale).join(splitext(template))
        try:
            return django_render(request, locale_tmpl, context, **kwargs)
        except TemplateDoesNotExist:
            pass

    # Render try #3: Render originally requested/default template
    return django_render(request, template, context, **kwargs)
Esempio n. 8
0
def check_split_path(path, result):
    res = split_path(path)
    eq_(res, result)
Esempio n. 9
0
def render(request, template, context=None, **kwargs):
    """
    Same as django's render() shortcut, but with l10n template support.
    If used like this::

        return l10n_utils.render(request, 'myapp/mytemplate.html')

    ... this helper will render the following template::

        l10n/LANG/myapp/mytemplate.html

    if present, otherwise, it'll render the specified (en-US) template.
    """
    context = {} if context is None else context

    # Make sure we have a single template
    if isinstance(template, list):
        template = template[0]

    # Every template gets its own .lang file, so figure out what it is
    # and pass it in the context
    context['template'] = template
    context['langfile'] = get_lang_path(template)

    # Get the available translation list of the current page
    context.setdefault('translations', {})
    context['translations'].update(translations_for_template(template))

    # Look for localized template if not default lang.
    if hasattr(request, 'locale') and request.locale != settings.LANGUAGE_CODE:

        # Redirect to one of the user's accept languages or the site's default
        # language (en-US) if the current locale not active
        if not template_is_active(template, get_locale(request)):
            # Use the default (en-US) template to render instead of redirecting
            # if the template is not localized yet but the content itself is
            # localized. This is useful especially for legal documents where the
            # content is translated in the external legal-docs repository.
            if context.get('localized', False):
                return django_render(request, template, context, **kwargs)

            matched = None

            for lang in get_accept_languages(request):
                if template_is_active(template, lang):
                    matched = lang
                    break

            response = HttpResponseRedirect('/' + '/'.join([
                matched or settings.LANGUAGE_CODE,
                split_path(request.get_full_path())[1]
            ]))

            # Add the Vary header to avoid wrong redirects due to a cache
            response['Vary'] = 'Accept-Language'

            return response

        localized_tmpl = '%s/templates/%s' % (request.locale, template)
        try:
            return django_render(request, localized_tmpl, context, **kwargs)
        except TemplateDoesNotExist:
            # If not found, just go on and try rendering the parent template.
            pass

    return django_render(request, template, context, **kwargs)
Esempio n. 10
0
def render(request, template, context=None, **kwargs):
    """
    Same as django's render() shortcut, but with l10n template support.
    If used like this::

        return l10n_utils.render(request, 'myapp/mytemplate.html')

    ... this helper will render the following template::

        l10n/LANG/myapp/mytemplate.html

    if present, otherwise, it'll render the specified (en-US) template.
    """
    context = {} if context is None else context

    # Make sure we have a single template
    if isinstance(template, list):
        template = template[0]

    # Every template gets its own .lang file, so figure out what it is
    # and pass it in the context
    context['template'] = template
    context['langfile'] = get_lang_path(template)

    # Get the available translation list of the current page
    context.setdefault('translations', {})
    context['translations'].update(translations_for_template(template))

    # Look for localized template if not default lang.
    if hasattr(request, 'locale') and request.locale != settings.LANGUAGE_CODE:

        # Redirect to one of the user's accept languages or the site's default
        # language (en-US) if the current locale not active
        if not template_is_active(template, get_locale(request)):
            # Use the default (en-US) template to render instead of redirecting
            # if the template is not localized yet but the content itself is
            # localized. This is useful especially for legal documents where the
            # content is translated in the external legal-docs repository.
            if context.get('localized', False):
                return django_render(request, template, context, **kwargs)

            matched = None

            # Look for the user's Accept-Language HTTP header to find another
            # locale we can offer
            for lang in get_accept_languages(request):
                if template_is_active(template, lang):
                    matched = lang
                    break

            # Check for the fallback locales if the previous look-up doesn't
            # work. This is useful especially in the Spanish locale where es-ES
            # should be offered as the fallback of es, es-AR, es-CL and es-MX
            if not matched:
                for lang in get_accept_languages(request):
                    lang = settings.FALLBACK_LOCALES.get(lang)
                    if lang and template_is_active(template, lang):
                        matched = lang
                        break

            # If all the attempts failed, just use en-US, the default locale of
            # the site
            if not matched:
                matched = settings.LANGUAGE_CODE

            response = HttpResponseRedirect('/' + '/'.join([
                matched,
                split_path(request.get_full_path())[1]
            ]))

            # Add the Vary header to avoid wrong redirects due to a cache
            response['Vary'] = 'Accept-Language'

            return response

        # Render try #1: Look for l10n template in locale/{{ LANG }}/templates/
        l10n_tmpl = '%s/templates/%s' % (request.locale, template)
        try:
            return django_render(request, l10n_tmpl, context, **kwargs)
        except TemplateDoesNotExist:
            pass

        # Render try #2: Look for locale-specific template in app/templates/
        locale_tmpl = '.{}'.format(request.locale).join(splitext(template))
        try:
            return django_render(request, locale_tmpl, context, **kwargs)
        except TemplateDoesNotExist:
            pass

    # Render try #3: Render originally requested/default template
    return django_render(request, template, context, **kwargs)
Esempio n. 11
0
def render(request, template, context=None, **kwargs):
    """
    Same as django's render() shortcut, but with l10n template support.
    If used like this::

        return l10n_utils.render(request, 'myapp/mytemplate.html')

    ... this helper will render the following template::

        l10n/LANG/myapp/mytemplate.html

    if present, otherwise, it'll render the specified (en-US) template.
    """
    # use copy() here to avoid modifying the dict in a view that will then
    # be different on the next call to the view.
    context = context.copy() if context else {}

    # Make sure we have a single template
    if isinstance(template, list):
        template = template[0]

    # Every template gets its own .lang file, so figure out what it is
    # and pass it in the context
    context['template'] = template
    context['langfile'] = get_lang_path(template)
    context['template_source_url'] = template_source_url(template)

    # if `locales` is given use it as the full list of active translations
    if 'active_locales' in context:
        translations = context['active_locales']
        del context['active_locales']
    else:
        translations = translations_for_template(template)
        # if `add_active_locales` is given then add it to the translations for the template
        if 'add_active_locales' in context:
            translations.extend(context['add_active_locales'])
            del context['add_active_locales']

    context['translations'] = get_translations_native_names(translations)

    # Look for localized template
    if hasattr(request, 'locale'):
        # Redirect to one of the user's accept languages or the site's default
        # language (en-US) if the current locale not active
        if request.locale not in translations:
            lang = get_best_translation(translations, get_accept_languages(request))
            response = HttpResponseRedirect('/' + '/'.join([
                lang,
                split_path(request.get_full_path())[1]
            ]))
            # Add the Vary header to avoid wrong redirects due to a cache
            response['Vary'] = 'Accept-Language'
            return response

        # Render try #1: Look for l10n template in locale/{{ LANG }}/templates/
        l10n_tmpl = '%s/templates/%s' % (request.locale, template)
        try:
            return django_render(request, l10n_tmpl, context, **kwargs)
        except TemplateDoesNotExist:
            pass

        # Render try #2: Look for locale-specific template in app/templates/
        locale_tmpl = '.{}'.format(request.locale).join(splitext(template))
        try:
            return django_render(request, locale_tmpl, context, **kwargs)
        except TemplateDoesNotExist:
            pass

    # Render try #3: Render originally requested/default template
    return django_render(request, template, context, **kwargs)