2009-09-01 21 views
8

En una aplicación multilenguaje con tablas de búsqueda, ¿cuál es la mejor forma de manejar las traducciones?¿Cuál es la mejor manera de manejar I18N en tablas de búsqueda?

Por ejemplo, para una tabla de búsqueda de país, un usuario de EE. UU. Debe ver los nombres de los países en inglés, ya que un alemán debería ver los nombres en alemán. Pero aún así, sus identificaciones deberían ser las mismas.

se me ocurre lo siguiente:

  • Añadir una tabla de búsqueda diferente para cada idioma
  • uso una sola tabla de búsqueda con varias entradas para el mismo país que enarbole el pabellón de acuerdo con su lenguaje.
  • Deshacerse de todas las tablas de búsqueda y hacer todas las búsquedas por código de programa
  • [Cualquier otra idea que no había pensado en?]

Respuesta

8

La gran pregunta aquí es - puede traducciones puede ser alterado por fin usuarios?

Si la respuesta es "NO", los paquetes de recursos son más fáciles y rápidos de usar que las tablas. En lugar de texto real, sus tablas contendrán la clave de recursos (o podría usar la clave principal para ese propósito si es de texto en lugar de numérica) y el paquete de recursos apropiado contendrá la traducción.

Si la respuesta es "SÍ", debe almacenar las traducciones en la base de datos. Sin embargo, he encontrado que el enfoque más fácil en este escenario es imitar la funcionalidad anterior del paquete de recursos en la base de datos, p. tener una sola tabla con columnas "locale", "resource key", "resource value" que todas las demás tablas usarán para buscar texto localizado real.

3

Presentación disyuntiva de la programación. Internamente, use ID para todo; cuando se presenta a los usuarios, presente datos localizados.

1

Hice una aplicación multilingüe una vez. Todo tenía que ser multilingüe, incluido el contenido que los usuarios ingresaban, y también tenía que ser fácil hacer una traducción sobre este contenido.

Ahora, si es solo para texto estático, la mayoría recomiendan los archivos xml de recursos para hacer esto. Creo que esto es soportado por el framework .NET bastante bien.

Si tiene que ser dinámico, luego hice una estructura de tabla de

resourcestrings Tabla resourceId GUID PK cultureCode cadena PK de texto Cadena

Esto entonces me permitió TODO cascada de leer en el código de la cultura también. Así que si alguien tenía un código de cultura de es-es, que podía hacer una consulta donde hice

SELECT FROM ResourceStrings 
WHERE resourceId = <AND ID> AND cultureCode IS IN ('en','en-us') 
ORDER BY cultureCode DESC 

De esta manera el código de la cultura más largo sería volver primero y ser el más específico. Ahora lo recomendaría ÚNICAMENTE si permite que los usuarios ingresen texto y lo traduzcan. Lo necesitaba porque el contenido debía ser multilingüe y la aplicación en sí.

0

Echa un vistazo a algo así como Adobe Source Libraries 'xstring estructuras de datos y algoritmos. La localización allí se maneja con una identificación para la cadena, así como el contexto que detalla la localización. Las tablas de localización se pueden almacenar en XML y las cadenas se localizan en el tiempo de ejecución en función del contexto de tiempo de ejecución (idioma, país, plataforma, etc.) Aunque el código en sí funciona, no lo consideraría calidad de producción. Sin embargo, los conceptos son sólidos.

1

En mi proyecto actual (un CMS personalizado escrito en django), nuestra solución para modelos I18N se basa en este fragmento de ejemplo: http://www.djangosnippets.org/snippets/855/, que amplié para ser más útil en plantillas e integrado en la interfaz de administración.

Básicamente, cada tipo de contenido tiene dos tablas: una con los campos comunes (como la categoría de artículos) y otra con contenido traducible (título, cuerpo, slug, etiqueta única utilizada en la url, etc.). Obviamente, hay una relación entre muchos entre el modelo común y el modelo de traducción. Aquí está el ejemplo, el autor da:

class Article(models.Model): 
    author = models.CharField(max_length = 40) 

class ArticleI18N(I18NModel): 
    title = models.CharField(max_length = 120) 
    body = models.TextField() 

creo que de esta manera, el diseño de base de datos está muy cerca del concepto de tener contenido con atributos comunes y campos traducibles.

Pero luego la parte difícil es permanecer SECO en su código, o terminará con un desastre de repetición cada vez que necesite manejar contenido traducible. Afortunadamente, la flexibilidad de Python fue de gran ayuda. Si su lenguaje de programación y entorno no permiten trucos similares (como la creación dinámica de subclases, Python metaclasses - algún tipo de gancho de herencia, etc.), este tipo de diseño de base de datos va a ser más una maldición una bendición.

Por lo tanto, tenga en cuenta el principio YAGNI. Si necesita traducciones dentro de sus modelos con menos complicaciones, he visto otras maneras efectivas, que son bien siempre y cuando se lo puede permitir la limitada flexibilidad y la falta de integridad conceptual de esas alternativas:

  • 1) utilizan columnas adicionales para cada columna y cada traducible idioma: title_en, title_fr, title_de, content_en, content_fr, content_de, ...
  • 2) serializar múltiples idiomas en una columna.
    Por ejemplo: title = "| ES | Bienvenido | FR | Bienvenue | DE | Willkommen"
    no me gusta que uno en particular, pero lo que importa realmente aquí es si se trata de integrar muy bien dentro de un entorno existente, que era el caso.
  • 3) A veces, el enlace entre el mismo contenido en diferentes idiomas no tiene que ser estricto. Creo que es el caso de los artículos en wikipedia: las traducciones son solo hipervínculos establecidos manualmente por los autores. Como consecuencia, esos enlaces son menos explotables por el software, pero lo que importa aquí es que un usuario pueda navegar.
1

Aquí hay una manera de hacerlo a nivel de base de datos.

Cuando tuve que hacer esto, rompí cada tabla de códigos en dos tablas. Uno de ellos contenía datos invariantes para el cultivo: la identificación interna del código, el código en sí, si el código era invariante para el cultivo, y posiblemente otras columnas (como categorías de clasificación/agrupación). El otro contenía datos específicos de la cultura: descripciones, códigos específicos de la cultura si correspondía, etc.

(Los códigos específicos de la cultura son un nido de avispas; no lo patees si no tienes que hacerlo. Puede ser un poco difícil entender que US y EU son el mismo código en diferentes idiomas. Sin embargo, hay países en los que puede ser políticamente inaceptable para hacer los usuarios de habla francesa utilizan US como su abreviatura de États-Unis. Bueno, un país.)

Tener una tabla de códigos de la cultura invariante permite establecer restricciones de clave externa entre éste y tablas principales que lo utilizan. La construcción de consultas específicas de la cultura es bastante sencillo:

SELECT m.*, c.Code, ISNULL(s.Description, lf.Message) 
FROM MainTable m 
JOIN FooCodeData c ON m.CodeID = c.ID 
LEFT JOIN CultureSpecificFooCodeData s ON s.CodeID = c.ID AND s.Culture = @Culture 
JOIN LookupFailure lf ON lf.Culture = @Culture 

Tenga en cuenta que si sus códigos son específicos de la cultura, que ni siquiera es necesario para unirse a FooCodeData en esa consulta, seleccionando s.Code lugar.

Tenga en cuenta también una debilidad inherente de este enfoque, como se muestra en LEFT JOIN y ISNULL en esa consulta: no puede crear una restricción para garantizar que exista una fila cultural específica para cada combinación de código/cultura. Para eso sirve LookupFailure: recibe el mensaje cultural específico que indica que no se ha ingresado el registro del código específico del cultivo para un código dado.

Cuestiones relacionadas