Opened 5 years ago

Closed 5 years ago

#24122 closed New feature (fixed)

Redirect to translated url after setting language

Reported by: GwynBleidD Owned by: nobody
Component: Internationalization Version: master
Severity: Normal Keywords: set_language, i18n_patterns, translating urls
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When user change language using set_language view, we can redirect him either to url from 'next' post value or 'HTTP_REFERER' header. But if i18n_patterns is in use or urls are translated, user will be redirected to old url (if no next url) or we must provide new, translated url into next value which involves javascript when we want to have dropdown to select new language. This can cause:

  • language not changed if i18n_patterns is in use,
  • redirect to 404 or different page when urls are translated.

I'm proposing patch to translate url taken from 'next' or 'HTTP_REFERER' into new language:

def set_language(request):
    """
    Redirect to a given url while setting the chosen language in the
    session or cookie. The url and the language code need to be
    specified in the request parameters.

    Since this view changes how the user will see the rest of the site, it must
    only be accessed as a POST request. If called as a GET request, it will
    redirect to the page in the request (the 'next' parameter) without changing
    any state.
    """
    next = request.POST.get('next', request.GET.get('next'))
    if not is_safe_url(url=next, host=request.get_host()):
        next = request.META.get('HTTP_REFERER')
        if not is_safe_url(url=next, host=request.get_host()):
            next = '/'
    response = http.HttpResponseRedirect(next)
    if request.method == 'POST':
        lang_code = request.POST.get('language', None)
        if lang_code and check_for_language(lang_code):
            parsed = urlsplit(next)
            try:
                match = resolve(parsed.path)
            except Resolver404:
                pass
            else:
                activate(lang_code)
                try:
                    url = reverse("%s:%s" % (match.namespace, match.url_name) if match.namespace else match.url_name, args=match.args, kwargs=match.kwargs)
                except NoReverseMatch:
                    pass
                else:
                    next = urlunsplit((parsed.scheme, parsed.netloc, url, parsed.query, parsed.fragment))
                    response = http.HttpResponseRedirect(next)
            if hasattr(request, 'session'):
                request.session[LANGUAGE_SESSION_KEY] = lang_code
            else:
                response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code,
                                    max_age=settings.LANGUAGE_COOKIE_AGE,
                                    path=settings.LANGUAGE_COOKIE_PATH,
                                    domain=settings.LANGUAGE_COOKIE_DOMAIN)
    return response

I'm not sure if this is an bug report or new feature (for me, redirecting to 404 or not changing language is definetly a bug) so I left it uncategorized.
Fork on github: https://github.com/gbdlin/django
Old simmillar (not sure if same case, because of not much explanation from author) ticket: https://code.djangoproject.com/ticket/17569

Change History (4)

comment:2 Changed 5 years ago by Claude Paroz

Triage Stage: UnreviewedAccepted
Type: UncategorizedNew feature
Version: 1.7master

comment:3 Changed 5 years ago by Tim Graham

Triage Stage: AcceptedReady for checkin

comment:4 Changed 5 years ago by Claude Paroz <claude@…>

Resolution: fixed
Status: newclosed

In aa5ab11:

Fixed #24122 -- Redirected to translated url after setting language

Thanks gbdlin for the initial patch and Tim Graham for the review.

Note: See TracTickets for help on using tickets.
Back to Top