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
-~----------~----~----~----~------~----~------~--~---

Reply via email to