Ranteando en varios idiomas, the easy way

Angel Velásquez
@angvp
angvp@archlinux.org
Rant
"Es un monólogo o un discurso largo, dado por una persona cuando está molesta o irritada"
(traducción de wikipedia)


Como perder 20 kilos en 2 semanas con HERBALIFE

Antes de empezar...
- Hablo rápido, pero puedo ir más pausado si me lo piden.
- Los rants de los ejemplos fueron suavizados para cumplir el código de conducta.
- La charla se refiere a i18n de contenido que está en la DB
- En caso de aburrimiento .. banquen un poco que hay pizza al final! :)
Un poco de contexto
Route Atlas es una herramienta creada para ayudar a los viajeros a planificar sus recorridos dándole toda la información posible (de manera escrita, visual y audiovisual) de los sitios más impresionantes de América del Sur.

Route Atlas
Los contenidos del sitio están disponibles en 3 idiomas .. (Español, Inglés, Portugués de Brasil).

El problema

- Requiere cambios en los modelos (y migraciones en algunos casos).
- Agrega más complejidad para lo que ya funcionaba en 1 idioma.
- El framework de i18n que trae Django no alcanza :(
¿Y cómo resolvemos este problema?
- Agregando 1 campo por columna x idioma en la tabla (django-modeltranslation)
- Creando una tabla que tenga todas las traducciones (django-hvad, django-klingon)
- Manejando las traducciones en un archivo .po (django-dbgettext)

Las soluciones

- django-hvad
- django-modeltranslation
- django-dbgettext
- django-klingon (nuestra propia cosecha)
- ... etc
django-hvad
(+):
- Usa el ORM de Django
- Incluye admin
- Se mantiene al día el desarrollo
(-):
- Requiere cambios en la definición del modelo
- La integración con DRF es inexistente
https://github.com/kristianoellegaard/django-hvad
django-modeltranslation
(+):
- Muy simple de acceder
- No requiere un admin especial
- Se mantiene al día el desarrollo
(-):
- Genera las traducciones en la misma tabla de origen añadiendo columnas según campo a traducir e idioma
- Requiere que se hagan migraciones por cada idioma o campo a traducir.
- La cobertura de tests es mala
https://github.com/deschler/django-modeltranslation
django-dbgettext
(+):
- Simple
- Se podría mantener control de versiones sin muchísimo esfuerzo
- Se maneja como un archivo de traducciones
(-):
- Requiere instalar otra aplicación para administrar catálogos de traducciones (rosetta, etc)
- Requiere compilación de mensajes con cada cambio
- El desarrollo está estancado
https://bitbucket.org/drmeers/django-dbgettext/wiki/browse/
django-klingon
(+):
- Simple
- Integración con el backend de cache que esté en la app
- Integración con admin de Django
- Integración con DRF2 en otra app (y pronto DRF3)
- Desarrollo activo
(-):
- Requiere cambios mínimos en la definición del modelo (no genera migrations)
- Un poco verde (Faltan contributors :()
https://github.com/RouteAtlas/django-klingon/
Klingon en acción

settings.py
...
_ = lambda s: s
LANGUAGES = (
('es', _('Español')),
('it', _('Italiano')),
('en', _('Inglés')),
)
DEFAULT_LANGUAGE = 'es'
KLINGON_DEFAULT_LANGUAGE = DEFAULT_LANGUAGE
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django_extensions',
'klingon',
'rant',
)
models.py
from autoslug import AutoSlugField
from django.db import models
from klingon.models import AutomaticTranslation
class Category(models.Model, AutomaticTranslation):
name = models.CharField(max_length=100)
description = models.TextField()
#klingon begin
translatable_fields = ('name', 'description')
class Meta:
verbose_name_plural = 'Categories'
def __str__(self):
return self.name
class Rant(models.Model, AutomaticTranslation):
category = models.ForeignKey(Category)
title = models.CharField(max_length=100)
description = models.TextField()
slug = AutoSlugField(populate_from='title')
# klingon begin
translatable_fields = ('title', 'description', 'slug')
translatable_slug = 'slug'
def __str__(self):
return self.titleadmin.py
from django import forms
from django.contrib import admin
from rant.models import Category, Rant
from klingon.admin import TranslationInline, TranslationInlineForm, create_translations
class RichTranslationInlineForm(TranslationInlineForm):
widgets = {
'CharField': forms.TextInput(attrs={'class': 'klingon-char-field'}),
'TextField': forms.Textarea(attrs={'class': 'klingon-text-field'}),
'SlugField': forms.TextInput(attrs={'readonly': 'readonly', 'disabled':
'disabled'}),
}
class RichTranslationInline(TranslationInline):
form = RichTranslationInlineForm
class CategoryAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'description', 'translations_link')
search_fields = ['name', 'description']
inlines = [RichTranslationInline]
actions = [create_translations]
class RantAdmin(admin.ModelAdmin):
list_display = ('id', 'title', 'slug', 'translations_link')
search_fields = ['title', 'description']
inlines = [RichTranslationInline]
actions = [create_translations]
admin.site.register(Category, CategoryAdmin)
admin.site.register(Rant, RantAdmin)Live Demo!
(casi siempre fallan) :( crucemos los dedos :D
¡GRACIAS!
Angel "qbasic" Velasquez
angvp@archlinux.org
@angvp (twitter, github)
https://github.com/angvp/klingonexample
Ranteando en varios idiomas, the easy way
By Angel Velásquez
Ranteando en varios idiomas, the easy way
Charla para la Django Meetup 4 @ RouteAtlas
- 527