I'm adding internationalization to my Django project. The idea of how it should work is the following:
When a user enters "/" i.e. the "homepage" we try to get his/her
language preferences from our session. If it's not our default
language (EN), we redirect the user to the local version, like /ES/,
/RU/, /CN/, etc
If we have no such session data, we check Accept-Language and
redirect the user to the local version if we support such
If we don't support user's Accept-Language OR if it's EN - we don't
redirect user! we just show the "default language"
I.e. all "not default languages" should have their prefixes, but default one won't. Why the default language should have a prefix, right? )))
The issue is, I can't figure out how to set this logic. If I set prefix_default_language=False to disable the /EN/ prefix for default language, it also disables the "not default" redirect. I found a package that solves the problem: https://github.com/st4lk/django-solid-i18n-urls#behaviour settings.SOLID_I18N_USE_REDIRECTS = True but it doesn't work in Django 2+
I can't believe I'm the only one hating the default language prefixes )) Although I could not find any solution with both redirect and no prefix for the default language. Hope someone will advice something here đ
Related
I would like to use the same views for different supported languages.
For exemple I have the default language and the english.
In my main urls:
url(r'^posts/', include('posts.urls')), #for default language
url(r'^en/posts/', include('posts.urls')), #for english
The urls file of my posts app is like this:
url(r'^newpost/$', views.PostFormView.as_view(), name='add'),
url(r'^favorite/$', views.favorite, name='favorite'),
so, for example, both www.mysite.com/posts/add and www.mysite.com/en/posts/add send to the same view PostFormView and according to the url if it contains "/en/" or not I send the content in the right language.
However, the issue is with the redirect or revers sends always to the default language. For example 'posts:add' sends always to "www.mysite.com/posts/add" because I have url(r'^posts/', include('posts.urls')) before url(r'^en/posts/', include('posts.urls'))
are there any ways to use the same view for two different urls. Or, how can I handle multiple languages website? Do we have to duplicate all the apps for all the supported languages?
This is a long subject and it's not easy to cover everything but i'll try to cover as much as i can:
1 - Use django Internationalization and localization:
Django has a built-in function for multi language websites:
Internationalization and localization
2 - Use a single URL with different GET request:
You can add a GET request in your urls like : site.com/posts?lang=en. And try this in your views:
language = request.GET.get('lang')
and then pass the right template for this language.
example:
LANG_LIST = ['en', 'fa', 'fr']
if language.lower() in LANG_LIST:
template = '{}/posts/post.html'.format(language.lower())
else:
template = 'en/posts/post.html'
or you can use a single template with different language texts and just pass the language to the template and decide there.
Note: You should add users language to their session so you can retrieve the language even without a GET request.
Here is the docs for sessions:
How to use sessions | Django documentation | Django
Also you can add language to your users profile and retrieve the language from there. I recommend using both profile language and user sessions.
3 - Different urls (Your way):
I'm not a fan of this way of handling multi language websites really, but if you really need to do it this way then here you go:
You need different names for your urls lile posts_en, posts_fr and etc so you can redirect to the right page url.
You should get the page url in your view and check for language your using. You can do something like this: request.path.split('/').
Then you should check the language and decide which template to render just like option #2
There can be so many problems with this way of handling multiple languages so i don't think you should go with this one over the other two options.
I have following question
Item level Fallback is enabled in âSitecore.LanguageFallback.configâ and fallback/default language is âenâ
Languages configured in site : en, de, el, es, fr, it, ja, pt, zh
Scenario: We try to access the site with Russian(ru) or any other language which we have not configured in sitecore . The site still loads without any error, but no contents are fetched, as the language is not configured the fallback to English language doesnât working.
Does sitecore loads the page for all the valid languages available irrespective of languages we configure under system/languages. If Yes, then should we explicitly handle in our code to restrict this behavior or fallback to English? Or is there a way we can handle this through configuration.
This is the expected behaviour unfortunately, Sitecore will load for all languages regardless of whether you have them enabled/configured in the CMS.
You need to handle this yourself in code. On possible option is to use a similar processor to this by John West and override the StripLanguage processor.
public override void Process(PreprocessRequestArgs args)
{
if (args != null
&& args.Context != null
&& !string.IsNullOrWhiteSpace(args.Context.Request.FilePath))
{
string prefix = WebUtil.ExtractLanguageName(
args.Context.Request.FilePath);
if ((!string.IsNullOrWhiteSpace(prefix))
&& !this._validLanguages.Contains(prefix.ToLower()))
{
return;
}
}
base.Process(args);
}
By simply not stripping out the language code when interpreting request URLs, Sitecore will try resolve the item it will not find a matching ru item under your home and therefore throw as 404 as you would expect it to. (You could also redirect the user to the default language at this stage instead).
The slight down side to this is that the languages are specified in config and any changes would require a deployment. Depending on your exact requirements, you could read these in from an Item specified in the Sitecore tree if you require it to be more dynamic.
Your language fallback is not setup correctly. Read the manual at the Sitecore site.
To have a Russian version falling back to English, you need to create a Russian language (it will appear in the Languages list as in your screenshot). On that item, you can fill the Fallback Language field. Set that to English. This defines the fallback language.
In order to have your items use the item fallback (which is what you want if you don't want to create versions in Russian) you must enable that on your items. The easiest way to do so is set it in the standard values of the templates. The checkbox Enable Item Fallback must be checked for the fallback mechanism to work.
I have a Django form that uses a 'forms.URLField' like local_url1 = URLField(label="First Local URL", required=False). If a user inputs something like 'https://www.google.com' then the field validates without error.
However, if the user puts 'www.google.com' the field fails validation and the user sees an error. This is because the layout of a URL is scheme://host:port/absolute_path and the failing URL is missing the scheme (e.g. https), which Django's URLFieldValidation expects.
I don't care if my users include the scheme and nor should my form. Unfortunately, the error from django is completely useless in indicating what is wrong, and I've had multiple users ask why it says to enter a valid URL. I'm also certain I've lost paying customers because of this.
Is there a way to have all the other validation of a URL take place, but ignore the fact that the scheme is missing? At the very least, can I change the error message to add something like "Did you include http?". I've attempted implementing my own URLField and URLFieldValidation, but unless that's the path I have to take, then that is a different StackOverflow question.
I'm using Django 1.7, by the way. Thanks for any help!
URL/URI scheme list to validate against. If not provided, the default
list is ['http', 'https', 'ftp', 'ftps']. As a reference, the IANA Web
site provides a full list of valid URI schemes.
If the valid URI schemes provided by IANA web are not what you are looking for, then I suggest you create your own field validator.
Remember that URLField is a subclass of the CharField. and since www.something.com is ok with you, then It's simple to add a regular expression to the regular CharField that checks if the pattern is correct or not.
A regular expression like this for example will validate against www and http://. so with or without http or https.
((?:https?\:\/\/|www\.)(?:[-a-z0-9]+\.)*[-a-z0-9]+.*)
www.google.com -- OK
http://www.google.com -- OK
https://www.google.com -- OK
http://google.com -- OK
https://google.com -- OK
However, this will not complain about blahwww.domain.com
so you might enhance it as you like.
I'm looking for a way to detect user language. I set my default language as 'en_US', and I translated my site for 'pt_BR'. How can I switch the language and show 'pt_BR' version for Brazilians and 'en_US' for the rest of the world?
I read these documentation links:
https://docs.djangoproject.com/en/dev/topics/http/sessions/
https://docs.djangoproject.com/en/1.7/topics/i18n/translation/
I believe that maybe I'll have to take this information from user cookies or browser preferences, but how can I do this?
Furthermore, how can I test different languages? I have to change my browser language? OS language? Use a proxy?
Every user's HTTP request contains in header parameter Accept-Language.
Example would be:
user_langs = request.META.get('HTTP_ACCEPT_LANGUAGE', ['en-US', ])
Try to add navigator.language to your post data and resolve it in your view.
http://www.w3schools.com/jsref/prop_nav_language.asp
As you can see, django-pagination has polish (pl) translations - https://github.com/ericflo/django-pagination/tree/master/pagination/locale but I dont know, how to set polish language for django-pagination? (default english)
This should happen automatically.
Check your django settings if USE_I18N is set to True and if your LANGUAGE_CODE is set to pl.
For further information take a look at the django localization page. You can find a more detailed documentation of how the translation in django works here.
There's also a list of language codes, I guess pl should be correct.
You can either change the language setting of your browser, which will send the appropriate headers with each request and trigger the translation to be used, or you can provide a language setting selection so the user can choose their language.
You can roll your own code to provide this interface or use django-user-accounts.
You also might want to check that you have the appropriate middleware installed as described in this documenation.