Multilanguage comment

134 views
Skip to first unread message

POKOLI I PUNTO

unread,
Dec 6, 2011, 5:29:27 AM12/6/11
to mezzani...@googlegroups.com
Hello All,

I'm trying to add multi-language support on mezzanine, so will explain my thoughts:

Like commented on a github issue[1] the intention is:
  • Define available languages in the regular LANGUAGES setting.
  • Enable a way to declare which fields of which methods are translatable. A setting with a list of paths seems a good idea.
  • Dynamically create a field on each model for each language (title_es,title_en,title_jp).  Patch each model to save and retrieve the correct translated value. 
  • Something that sets the user/admin language to be able to render the view on the current language. In the admin zone, what would be better: To show one field for each language or to show only the current language and let the admin change the language? I like more the firsts approach.
Moreover I'm thinking in implement those thinks too:
  • Determine which language is accepted by the users tought HTTP_ACCEPT_LANGUAGE
  • Define a default language for those users that any of the HTTP_ACCEPT_LANGUAGE isn't available.

Any thoughts?

[1] https://github.com/stephenmcd/mezzanine/issues/106


POKOLI I PUNTO

unread,
Dec 7, 2011, 5:37:32 AM12/7/11
to mezzani...@googlegroups.com
Hi,

Al 06/12/11 11:29, En/na POKOLI I PUNTO ha escrit:
Hello All,

I'm trying to add multi-language support on mezzanine, so will explain my thoughts:

Like commented on a github issue[1] the intention is:
  • Define available languages in the regular LANGUAGES setting.
  • Enable a way to declare which fields of which methods are translatable. A setting with a list of paths seems a good idea.
  • Dynamically create a field on each model for each language (title_es,title_en,title_jp).  Patch each model to save and retrieve the correct translated value.
I've created a metaclass that dinamically creates a field foreach language. You can see it in: [2]

To define the translated fields of a model you have to:

  1. add __metaclass__ = TranslatableBase in the model to translate
  2. add a translatable_fields in the Meta of models. This is a tuple with the name of the fields to translate.
For example:

class BlogPost(Displayable,Ownable,RichText):
   
    __metaclass__ = TranslatableBase
   
    translatable = models.CharField(_("translatable"), max_length=100, default='')

    class Meta:
        translatable_fields = ["translatable"]


Then if you migrate the db with South it would create a field for each language in the DB.

Problems I've found:
  • Not being able to translate inherited fields. The Mettaclass is not able to found the field in the model. I think that I've some mistake in the code. Any help would be apreciated.
Test, comments would be gratefully apreciated.

[2] https://github.com/pokoli/mezzanine/commit/46d88e53cef6bf325e72e66193e81992eeb626e3

Stephen McDonald

unread,
Dec 7, 2011, 5:38:18 PM12/7/11
to mezzani...@googlegroups.com
Looks good so far!

One improvement I can think of would be to use the approach in mezzanine.boot to add the fields to models - that would mean not requiring the (Python) metaclass which would be a simpler API and could prevent metaclass conflicts down the track.

Another idea in the same vein as mezzanine.boot would be to put all the translatable fields into a setting rather than on inner (Django model) Meta classes. This has some pros and cons so I'm not sure if it's a better approach, merely something to think about it.

Pros:
- Users can change the translatable fields without needing to modify Mezzanine or any third party apps.
- One single config point for defining an entire project's translatable fields.

Cons:
- Having the translatable fields declared on Meta classes could be considered more explicit.

With regard to south, I think you've described the same issue that I talked about in field injection caveats, eg: yes the migrations get created, but the migrations get created for apps that the developer shouldn't modify. Here's an example:

- Developer installs Mezzanine
- Developer adds new languages to their settings module
- Developer runs schemamigration on Mezzanine's apps
- Migrations get created inside Mezzanine rather than the project

We can get away with this in some regard with the field injection functionality, as it's an optional extra tool that can be used for customising models. It isn't core functionality and comes with appropriate warnings. I don't think translatable content fits this bill - if it gets added it'll be a core feature. Again I still don't have a solution for this. I feel like there might need to be an approach where migrations get created, then copied to the project somehow.
--
Stephen McDonald
http://jupo.org

POKOLI I PUNTO

unread,
Dec 12, 2011, 7:24:48 AM12/12/11
to mezzani...@googlegroups.com
I See your point of view and I like your Pros list. However, it's difficult to implement this behaviour (at least for me). I'm not able to get the correct field type (django.db.models.fields.* or subclass) to copy the field in the model at this point. It warms me that the field doesn't exists.

Attached is the diff im working on.

So any help or comments would be appreciated.



Al 07/12/11 23:38, En/na Stephen McDonald ha escrit:
translation.diff

Stephen McDonald

unread,
Dec 13, 2011, 12:46:39 AM12/13/11
to mezzani...@googlegroups.com
Really looking good.

I think you'll find the problem is that fields aren't directly accessible as members of their model classes. Each model has it's Meta class accessible as _meta, and the meta class contains a handful of ways of getting at the fields. Here's an example of the error as well as using get_field():

    >>> from mezzanine.blog.models import BlogPost
    >>> BlogPost.title
    Traceback (most recent call last):
      File "<console>", line 1, in <module>
    AttributeError: type object 'BlogPost' has no attribute 'title'
    >>> BlogPost._meta.get_field("title")
    <django.db.models.fields.CharField object at 0x109b7c4d0>

POKOLI I PUNTO

unread,
Dec 13, 2011, 5:09:35 AM12/13/11
to mezzani...@googlegroups.com
Thanks for your comments. I've successfully created the fields based on the LANGUAGE settings and a new I18N_FIELDS settings, which is an array of strings pointing to a field (f.e. mezzanine.blog.models.BlogPost.title).

I've pushed the code on https://github.com/pokoli/mezzanine/tree/translation

Next steps:
  • Create a widget to show to the user the active languages and the available language. (I start to work in it)
  • Add the possibility to save content in multi_language. Here I want to start a discussion. How  you would prefer to have the translatable fields in the admin zone? Show a field per language (f.e. show title_es, title_en and title_jp in the admin zone) or add a language widget to let the admin select the language which is working on and only write the content in the active language.


Al 13/12/11 06:46, En/na Stephen McDonald ha escrit:

Stephen McDonald

unread,
Dec 13, 2011, 2:45:49 PM12/13/11
to mezzani...@googlegroups.com
I'd say the most common user will only be interested in one language - so better to have a language selection button/menu/whatever in the admin header somehow, and make it switch language for the whole admin, showing only one language variation for any translatable field at any time.
Reply all
Reply to author
Forward
0 new messages