Opened 5 years ago

Closed 5 years ago

Last modified 4 years ago

#15168 closed (wontfix)

feature request - New setting

Reported by: zay2 Owned by: nobody
Component: Internationalization Version: master
Severity: Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

My request:
Please add another settings option like:
DISCOVER_LANGUAGE, which is set to True by default.

My problem:
I have site in 5 languages (et, en, ru, lv, lt), default language is set to 'et'. My browser (like 75% browsers used by estonians) is in english though. For that reason django sets default language to 'en' when i visit my site for the first time. Many people in small countries use browsets which have english as their default language. Reason behind this is that the programs have either not been translated to english or the translation or vocabulary used are horrible. You cant expect all those people to know that they should go and set their browser accept language to something other than en-us.

My solution:
create setting option which allows us to turn off that accept headers based language detection. For now im forced to comment that part of the code out, cause estonians simply want to see their damn pages in estonian:P

Alan.

Change History (8)

comment:1 Changed 5 years ago by russellm

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to wontfix
  • Status changed from new to closed

Its unclear why a new setting is required here.

HTTP Header based language detection is performed by the Locale middleware; if you don't want the behavior that is implemented... don't use that middleware. Just remove it, or provide a different middleware.

If you're referring to a different piece of code, you'll need to provide more specific details than "that part of the code". Regardless, this doesn't seem to me like something that should be handled as a setting.

comment:2 Changed 5 years ago by zay2

Look- I need the middleware. The middleware works just fine. Its just this one specific piece of code in django.utils.translation.trans_real get_language_from_request that does not provide the desired results. Like i explained in Original Post, language discovery, based on accept headers shows pages in undesired language on first visit.

For that reason forementioned method looks like that in my django install, right now:

def get_language_from_request(request):
    """
    Analyzes the request to find what language the user wants the system to
    show. Only languages listed in settings.LANGUAGES are taken into account.
    If the user requests a sublanguage where we have a main language, we send
    out the main language.
    """
    global _accepted
    from django.conf import settings
    globalpath = os.path.join(os.path.dirname(sys.modules[settings.__module__].__file__), 'locale')
    supported = dict(settings.LANGUAGES)

    if hasattr(request, 'session'):
        lang_code = request.session.get('django_language', None)
        if lang_code in supported and lang_code is not None and check_for_language(lang_code):
            return lang_code

    lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME)

    if lang_code and lang_code not in supported:
        lang_code = lang_code.split('-')[0] # e.g. if fr-ca is not supported fallback to fr

    if lang_code and lang_code in supported and check_for_language(lang_code):
        return lang_code

    '''
    accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
    for accept_lang, unused in parse_accept_lang_header(accept):
        if accept_lang == '*':
            break

        # We have a very restricted form for our language files (no encoding
        # specifier, since they all must be UTF-8 and only one possible
        # language each time. So we avoid the overhead of gettext.find() and
        # work out the MO file manually.

        # 'normalized' is the root name of the locale in POSIX format (which is
        # the format used for the directories holding the MO files).
        normalized = locale.locale_alias.get(to_locale(accept_lang, True))
        if not normalized:
            continue
        # Remove the default encoding from locale_alias.
        normalized = normalized.split('.')[0]

        if normalized in _accepted:
            # We've seen this locale before and have an MO file for it, so no
            # need to check again.
            return _accepted[normalized]

        for lang, dirname in ((accept_lang, normalized),
                (accept_lang.split('-')[0], normalized.split('_')[0])):
            if lang.lower() not in supported:
                continue
            langfile = os.path.join(globalpath, dirname, 'LC_MESSAGES',
                    'django.mo')
            if os.path.exists(langfile):
                _accepted[normalized] = lang
                return lang
    '''

    return settings.LANGUAGE_CODE

I would need to comment that part of code out from each new django version without that setting. With setting check, if i want to use that accept headers based lang discovery, commenting out would be unnecessary.

Did that make it clearer? Why would i want or need to write whole new languagemiddleware if all i need is one method out of the way?

Thanks,
Alan.

comment:3 Changed 5 years ago by zay2

  • Resolution wontfix deleted
  • Status changed from closed to reopened

comment:4 Changed 5 years ago by bpeschier

I think the behaviour you are after is really specific and should not be included; you are basically saying "I want to ignore this 1 language when it is not set in a cookie". Removing Accept-Language headers would mean first time visitors which have set it to Russian for example would get Estonian, which is probably also not ideal.

In your case I would extend the LocaleMiddleware to mirror that; check the HTTP_ACCEPT_LANGUAGE in META before handing it to the LocaleMiddleware-superclass and rewrite English to Estonian (META is mutable iirc).

comment:5 Changed 5 years ago by lrekucki

  • Resolution set to wontfix
  • Status changed from reopened to closed

Please don't reopen tickets marked as "won't fix" by core developers without prior discussion on django-developers mailing list.

As for the ticket itself, the middleware does exactly what I would except, both as a programmer and a user. I have my browser set to 'en-US' locale, because I prefer so (although I'm a polish speaking person). Without the detection, I would get your site in Estonian, which is probably jibberish to me.

Also, your need seems very specific, so I don't think it mandates a settings. You can make your own middleware based on the one in core.

comment:6 follow-up: Changed 5 years ago by zay2

You see things from your point of view, so lets give it one more shot:

1) Browsers/Op systems are not available in many small languages and therefore the speakers of languages like estonians have to use browsers/systems in english and their browsers are therefore in english - they may not desire it.

2) Those users do not know how to change their browsers language - you got to know that you and are are HUGE minority - perhaps only 5% of users know that they CAN change their browser language. Even less people know how and want to change it.

3) those 95% of people who dont know that they CAN change their browser language or know how to, usually visit pages, which are in their own language (the language that they speak every day, not the language their browser is set to).

4) I want to make pages that can be seen in default language - the language that the target audience of the page uses.

Now im not saying - "i want to ignore this 1 language when it is not set in a cookie"(quoting bpeschier). Im saying that i want the page be in language used by target audience. I cant do this with this accept headers based language discovery

"In your case I would extend the LocaleMiddleware to mirror that; check the HTTP_ACCEPT_LANGUAGE in META before handing it to the LocaleMiddleware-superclass and rewrite English to Estonian "(quoting bpeschier) - There already is default language setting - it just does not work in all cases.

"Without the detection, I would get your site in Estonian, which is probably jibberish to me."(quoting lrekucki). Well in such cases - You are not the target audience.

Ask your parents or grandparents, if they know what browser accept headers or if they can change those. This probably is irrelevant if they come from english speaking (or other countries which's languages are spoken by millions and millions of people) countries, since they never need to do anything like this anyway. Parents & grandparents in countries like Estonia, Latvia, Lithuania and so on, dont know about the accept headers or such either. But in most cases, their browsers are in english and they dont even know that this could be a problem.

Now we are making the websites for our customers and our customers are supposed to know their target audience. If we cant deliver the website which its target audience can see in its default language then something is wrong. I fixed this wrong by commenting out undesired code. Not very DRY. getting everybody, who face similar problem, extending their middleware is also not very DRY. Why would all those people have to repeat themselves? I still say that such setting option would be best way to solve this.

If i cant change your mind about this - so be it. If im gonna be the only one to see sanity in this, then so be it - i know how to fix this. Just thought, that this would be nice minor improvement. Moving discussion to dev's

comment:7 in reply to: ↑ 6 Changed 5 years ago by bpeschier

Replying to zay2:

Now im not saying - "i want to ignore this 1 language when it is not set in a cookie"(quoting bpeschier). Im saying that i want the page be in language used by target audience. I cant do this with this accept headers based language discovery

"In your case I would extend the LocaleMiddleware to mirror that; check the HTTP_ACCEPT_LANGUAGE in META before handing it to the LocaleMiddleware-superclass and rewrite English to Estonian "(quoting bpeschier) - There already is default language setting - it just does not work in all cases.

The default language is defined as the language to fall back to when no suitable language can be found and since you have an English translation, there is a suitable one according to definitions. Making settings which breaks this behaviour is not in the interest of Django or developers using it (just another setting in an already long list).

Instead of introducing a setting which is hardly used, a solution could be to refactor get_language_from_request into two distinct parts; this means you only have to override a very small function in LocaleMiddleware, which would not call the detection based on headers. It would not be hard to create a patch for this.

comment:8 Changed 4 years ago by jacob

  • milestone 1.3 deleted

Milestone 1.3 deleted

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