2009/4/24 Marc Garcia <garcia.m...@gmail.com>: > Hi folks, [...] > Any feedback will be appreciate.
Hi, first I must say I'm very happy this proposal got selected, specially for the content translation support part. This is a pony a lot of people want, I'm one of those. I have developed several multilingual sites and had the opportunity to use and experiment with some solutions out there like trans-db and django-multilingual and lately I have been thinking about a different approach I would like to share with you for your consideration. I created a google project a while ago to implement this as a 3rd party app but didn't had much time for it (http://code.google.com/p/django-pluggable-model-i18n/), the code is *very* incomplete just the definition and extra table creation is implemented. ------------------------------------------------------------------------------- Definition/Syntax ================= This section deals with how to tell django that a model needs translation support and its configuration, for example which fields are translatable. I'm calling this the translation definition for a model. # How to define translations I think translation shouldn't be defined in the model class. This is one of the main reasons why I'm not completely happy with solutions like tras-db and django-multilingual they both define the translation in the model class (using custom models fields or an inner Translation class) since we are translating models and creating extra tables this might sound ok but this brings some limitations we should avoid. Model translations should be completely optional in django. When an app is distributed with model translation support the developers (those who use the app) should be able to decide if they want to use the shipped translations, override them with their own (with some possible limitations) or not using them at all. And it should be great if we could also add translation support to apps with no translation support. I think an admin like registration aproach is an excelent way of defining translations, for example for the following model: ----- class Item(models.Model): slug = models.SlugField() title = models.CharField(max_length=50) description = models.CharField(max_length=150) ----- the translation definition and registration could be something like this: ----- from django.db.models import translation class ItemTranslation(translation.ModelTranslation): fields = ('description', 'title') # This is probably the only required option db_table = 'item_translations' default_language = 'es' translation.register(Item, ItemTranslation) ----- There are many other options that could be useful to have besides db_table and default_language (which is explained below). # How to load translation definitions Definitions should be loaded automatically (if USE_I18N is True of course) for each installed app if an app_name.translations module exists (like admin does), but also e should have a way to override (or disable) them, so we need to load form other modules. Here a template loaders like logic works very well, we just need cupple of extra settings and default loaders: TRANSLATION_LOADERS = ( 'django.db.models.translation.loaders.app_module', # loads translations from app_name.translations 'django.db.models.translation.loaders.setting_module_list', # loads translations from the modules in TRASLATION_MODULES ) TRANSLATION_MODULES = ( 'project.translation_overrides.app1.translations', 'project.translation_overrides.app2.translations', ) Database storage ================ This section deals with how to store the translations in the database. Generally we have three approaches: 1- Use a single extra table where all the translations for all models are stored. 2- Use an extra table for each model with translations. 3- Use additional columns in the model table. The 2nd has the best balance between scalability, efficiency and maintainability, if we design it well from the beginning. # The model table In the model table, the table that is always created for each model, should have columns for all the fields, even for translatable fields. For example, this is something django-multilingual doesn't do, it also implements the 2nd aproach but it just creates the columns for the non translatable fields in the model table and then attibutes are created for translatable models instances, query lookups are modified and it gets hackish and makes it imposible to have optional translations. The main table created for a model should be exactly the same when even if its a translatable model or not. # The translation table The extra translation table for a model should only be created if a translation is registred for that model and it should be registred as a django model, using runtime model creation (http://www.pointy-stick.com/blog/2007/05/11/runtime-model-creation-django/) It will have all the columns for the translatable fields plus two extra columns the FK to the item being translated and the language, the translation model explicitly defined should look something like this (using the prev example): ----- class ItemTranslation(models.Model): language = models.CharField(db_index=True) model = models.ForeignKey(Item, related_name='translations') title = models.CharField(max_length=50) description = models.CharField(max_length=150) ----- # What is stored in the main table translatable columns Each translatable model has a default language, optionally it can be specified in the translation definition (as you saw above) or a global setting default will be used (or LANGUAGE_CODE as a last resource) this value is tells django the language of the content stored on the model table (for the translatable fields), so if we need a field translation in the default language no joins are needed and we have a clear fallback if a translation is not found in a given language. Data access =========== This section deals with how to access to stored translations. # Accessing from instances Model instances can access translations using the field (for the default language, but read below about this) or the translation model: ----- item.desciption item.translations.get(language='es').desciption ----- We could add some more readeable methods: ----- item.get_desciption_translation(None) item.get_desciption_translation('es') ----- # Accessing from queries If we want to lookup a field name we should be able to specify its language, for example: ----- Item.objects.filter(description___es__contains='text') ----- If no language is specified: ----- Item.objects.filter(description__contains='text') ----- It should default to the model's default language (but keep reading). # Request language defaults We could use the request language (as django-multillingual does) as the default language in queries and field access on instances instead of the model's default language, so: ----- item.description Item.objects.filter(description__contains='text') ----- both could use the request language wich seems also as a nice default for templates, queries in vies and for adding translation support to 3rd party apps. ------------------------------------------------------------------------------- I know this is not the best time to discuss this but I think it can help marc's research while 1.1 is being finished. Good luck marc! Regards, -- Gonzalo Saavedra --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-developers@googlegroups.com To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/django-developers?hl=en -~----------~----~----~----~------~----~------~--~---