Due to the datamodel changes in Translatable
from 2.2 to trunk,
providing "untranslatable" properties gets harder - we used to
store all translatable
columns in a separate database table, now
all columns are existent on all translations, as a translation
is just another entry to the original table, together with a certain
"Locale" value. There's a good overview on different datamodels
for model translations on http://www.gsdesign.ro/blog/multilanguage-database-design-approach/
We basically choose to change the datamodel to make decoration
and augmentation of SQL queries more straightforward - the
fact that Translatable was build very much like Versioned turned
out to be a negative impact - they got in each other's way too often,
and the double table rewriting in DataObjectDecorator->augmentSQL()
got very complicated.
See http://open.silverstripe.com/ticket/3722 for detailed
introduction to the problem of global translation properties.
Couple of ways to tackle this below.
Goal should be to have a translated ORM record
that can be used as any other record in the system
without any additional developer effort.
1. Self Joins
Mix in the global properties into a translated record,
either by an additional LEFT JOIN, or at construction time
through a separate query. We'd have to make
sure the ORM doesn't save back these original values
to the database though...
2. ORM-level fallbacks: DataObject
Basically, I'm thinking about loading a fallback record
together with every translatable record we load. If a property
is marked as untranslatable, it would get it from the fallback
instead. If we load two full fledged DataObject
records for each call, that means a lot more processing and
3. ORM-level fallbacks: Array
If we just load an array of fallback values,
we're still talking about two full sets of queries, but less
in-memory impact. The disadvantage of fallback
arrays is that they don't act like a full-fledged ORM record,
meaning dynamic getters etc. will behave differently.
4. Separating out translatable columns
to a new database table which gets automatically joined.
Would be architectually the cleanest approach, but
we've been there with 2.2, it didn't work out for reasons
outlined above, so assuming we don't want to go back
full circle this is not an option ;)
5. Duplicating global properties to every translated
record on every save. Depending on your amount
of languages, this will dramatically increase the
amount of writes to the database, and means redundant
data. Upside is that we can use the translated records
just as any other record in the ORM without special
cases for the reads.
Ideas? Comments? Please continue discussion here
on the mailinglist, as opposed to fragmenting it to the
Ingo Schommer | Senior Developer
Phone: +64 4 978 7330 ext 42