LocaleMiddleware not selecting requested available language - django

I am having trouble making django.middleware.locale.LocaleMiddleware set Chinese language as per the cookies/header I specify in the request.
After some debugging, I have narrowed it down to the the following function, which rejects it
django.utils.translations.trans_real.check_for_language
all_locale_paths returns only django's locales, which do not contain 'cn'. My apps are packaged and installed separately from the project itself, and they provide their own 'cn' language files, which get discovered successfully, but since their locale directories are not specified in LOCALE_PATHS, the middleware does not check them.
What is the best approach to avoid this problem? I am not adding the LOCALE_PATHS, as the app locations differ based on the different environments the project is deployed. I could import the app, and find the paths from it, but that seems like an overkill.

Django uses ISO-639 language codes (not country codes), which is also what browsers use in their Accept-Language headers.
The language code for Chinese is "zh", in Django both variants "zh_Hans" and "zh_Hant" are supported. "cn" isn't a language code for Chinese.

Related

How and where should I put a version number in my Django project?

I'm making a Django project consisting of several apps and I want to use a version number for the whole project, which would be useful for tracking the status of the project between each time it comes to production.
I've read and googled and I've found how to put a version number for each django app of mine, but not for a whole project.
I assume that the settings.py (in my case it would be base.py, because the settings are inherited for each environment: developmente, pre-production, production) would be the ideal file for storing it, but I would like to know good practices from other Django programmers, because I haven't found any.
Thank you in advance
I don't think I've ever needed to do this, but the two obvious choices would be either the settings file, as you state, or alternatively the __init__.py in the main project app.
You don't need it to relate to django, you can tag a commit in your source control to provide a marker of a particular version (as well as a separate branch for releases).
From the docs for git tagging
Git has the ability to tag specific points in history as being important. Typically people use this functionality to mark release points (v1.0, and so on).
You could use the same versioning number system as google if you so wish which relates to
year.month.day.optional_revision # i.e 2016.05.03 for today
Doing this would make it easier to track back to previous versions since it won't be overwritten in source code by newer version numbers.

Mac App Development: How to select app language while installing?

I am currently developing a Mac app using C++.
In this app, we have provided language selections for users.
But for some resource files, users can change it while using the app. So I want the the language version of the resource files to be chosen during installation and can not be changed after installation.
I have tried to package the app as a .pkg file using packagemaker and iceberg, but I can not find a way to provide a dialog to let users choose language.
For example, when I use iceberg to package a Mac App, it provides those options:
Settings/Documents/Scripts/plugins/Files
I can not find any way to give a language selection for end users.
So, my question is, how can I implement this requirement?
As a rule, this just is not done. On the Mac, and within iOS, there is a nearly thirty-year history of supporting a single binary with multiple user interface languages. The reason that there are few, if any, tools that support installation of just one is that it is considered to be against e way the platform is supposed to work.
Consider, just as an example, a computer in a lab in Quebec where it is not uncommon to have a mix if students speaking English and French. In is case, lab computers installed with just French would be useful only to users who speak Frennche, as changing the language to English for a new user (at login for example) would result in your application continuing to run in French.
With few exceptions, Applications should contain all languages available and gracefully handle language changes during use (often waiting until they are restarted to change the interface language, but your tactic may very).

How to force Django internationalization with languages not part of the official Django project?

I'm trying to activate Django translations in a language that is not yet part of the Django distribution. I'm more than happy to do Django translations in that language from now on, but since I need it now, I'd like to know if it's possible to activate a certain language even though the admin panel and Django messages have not yet been translated (since I don't need that).
I would like to not fiddle with the django installation, unless absolutely necessary.
If I set the LANGUAGES variable in settings.py to the following, for example:
LANGUAGES = (
('en', _('English')),
('de', _('German')),
)
then it works fine and I can choose either German or English, with my own custom translations. If I do the following, however:
LANGUAGES = (
('en', _('English')),
('af', _('Afrikaans')),
)
then the language in neither the session nor the cookie can be set to the af value, and it remains on en. I would think it would be possible to use af translations where available (as defined in my application locale files), then fall back to the en values otherwise? How does one do this?
From the Django docs:
Django does not support localizing
your application into a locale for
which Django itself has not been
translated. In this case, it will
ignore your translation files. If you
were to try this and Django supported
it, you would inevitably see a mixture
of translated strings (from your
application) and English strings (from
Django itself). If you want to support
a locale for your application that is
not already part of Django, you’ll
need to make at least a minimal
translation of the Django core.
That's quite irritating though, I wouldn't mind having a mixture of English and translated strings. But, at least it can be done, even though it is with quite some trouble.

How Do Search Engines See A Localized Django Site?

I have a Django site that uses the localization middleware in combination with gettext and the trans/blocktrans template tags to show visitors different pages depending on the preferred language in their user agent string (which seems to be the standard way of doing things in Django).
This works great for supported languages (currently only Spanish, English, and German with more coming). If I set the preferred language in my browser to a different language, I get the pages for that translation. However, I have no idea how it appears for search engines.
When a search engine crawls a site, does it typically have a preferred language in its agent string? Will German spiders get the German site and will Spanish ones get the Spanish site, or will they just get the default English site that's displayed when a user has no language set? Does this vary by search engines and is there a "standard way" of doing things that individual crawlers may or may not stick to?
bots typically do not have accept-language setting in the http header. which means that django will service your default language.
Regional search engines can have bots with accept-language set to whatever they prefer, but you cannot rely on that.
It is best to have different pages for each language. such as http://your.website.com/english/
and then in your middleware set up a redirect to the right language page if a specific accept-language is present.
Don't rely on what the search engine may do in this regard. You want all versions to be crawled. To achieve that:
Have different URLs for the different language versions.
Make sure the search engines can find the different versions.
Overall, I believe that the way I did it on my homepage is close to ideal in regard to both search engines and regular users:
When a user arrives at, e.g. brazzy.de/index.php, the site tries to determine the language from cookie (if present) or browser settings (Accept-language header), defaults to English, and does not redirect
Every page has links to the different language versions of that page (IMO the most important factor for user convenience, and also makes sure search engines can easily find the different versions).
These links lead to e.g. brazzy.de/en/index.php, which is in my case rewritten to brazzy.de/index.php?lang=en - this ensures that search engines see distinct URLs for the different language versions.
Visiting such a subdirectory sets the language cookie to that language
The pages without a language-specific URL (i.e. where the language depends on client data) use e.g. <link rel="canonical" href="/en/"> to tell the search engine at which language-specific URL that page can be found.
Use XML sitemaps to further make sure search engines can find all pages and all different language versions.
use hreflang meta tag but make sure you use different urls for different languages. even better, use different domain extension (example.de, example.es) in conjunction with Django sites framework.

django -- application subdirectory site/app1/app2/app3

If you were to write an app for a site, but wanted to make the app plug&play so you can just drop it in any Django project, set the main URL and there you go, how would you do that if you wanted to keep all the other required utility apps included in your portable app.
Example:
site/
site/site-app1
site/templates/site-app1
site/util-app1
site/util-app2
site/util-app3
Note: that the site-app1 makes the use of all three util-apps. It works great in this manner. But now, you decide to send the app to someone, but just that app with all its dependencies.
If we could package and send the apps like this?:
site/site-app1
site/site-app1/template
site/site-app1/util-app1
site/site-app1/util-app2
site/site-app1/util-app3
Then you just send site-app1 and everything goes with it.
Is there a way to make portable with utility apps as subdirctories?
Note: the idea is that we don't want to send the whole project, but one site-app within
the project only.
There have been a few presentations about reusable django apps, so search around. These should get you going:
Developing reusable apps. pdf and video
Django Templates: The Power of Inheritance
The presentations #Gerry links to are good sources of general info. To answer your question more directly, there isn't a way to package one app inside of another one (EDIT sorry, this is just plain wrong. You can put one app inside of another one's namespace, and it works just fine. It's an odd thing to do though: you're implying that the one app is a part of the other one; if that's true they'd be easier to use as a single app. So I'd still recommend one of the below options). AFAICT your options are:
If possible, make those external dependencies optional (i.e. enhanced functionality if util_app1 is available, fallback behavior if it isn't). This is how many apps behave with respect to, say, django-tagging or django-mailer.
Roll all the functionality into a single app. Depending how much code you actually depend on from the utility apps, if the dependencies are absolutely necessary for your app to function, this might be the best option to make things easy on your users.
Package and distribute all the apps separately and note the dependencies both in the documentation and in the setup.py install_requires. If all the apps are independently useful, this approach may be best. If they aren't all independently useful, why are they all separate apps?
Django applications can be made portable by adhering to certain practices. Ofcourse, these are not mandated
Application Location
The convention is to add applications in an apps/ directory, and to modify the manage.py (and eventually the apache config) to include
import sys
from os.path import abspath, dirname, join
PROJECT_ROOT = abspath(dirname(__file__))
sys.path.insert(0, join(PROJECT_ROOT, "apps"))
Your directory structure will look something like
site
site/apps/
site/apps/app1/
site/apps/app2/
Templates
Templates are located in the templates directory in the application. The convention is not to force the user to copy them in any other location. Eventually the user can have global templates to override the ones in the application.
Settings
Keep all default settings in a local file within the app directory. The settings would be overridden by the global settings. The local settings file will have the following structure..
from django.conf import settings
def get(key, default):
return getattr(settings, key, default)
SETTING_1 = get('SETTTING_1', 10)
These conventions should cover most major issues.