Data Representation

 

We will need to make, at a minimum, this alteration to the cards table:

cards

+ lang

+ translatee_id

 

The basic idea is that if a card is a translation of another card, it will have that card's id as its translatee id.  If not, it will have its own id as a translatee_id.

 

To spell it out a bit, here's how the data would look in the four patterns:

 

  • Universal: lang is null

  • Monolingual/Mapped: lang is non-null. there is only one card per translatee_id. The complexity of translation type of names composed of different types deserves its out subsection: (in the case of mapped plus cards, cards in all the others languages are virtual)

  • Strict/Free: language is non-null. First card is its own translatee every additional translation has but same translatee_id.
    Note that we may need an additional field to flag out-of-date translations.

 

Representation Details

Here are some representational invariants and constraits to help define the data structures:

  • translatee_id is not null
  • if lang is null, there are no other translators (besides itself)
  • translatee_id is used whenever we need the card with all its translations (Maybe the idea of the languag type General when the language is not specified (yet), which could be used in memory Card objects, but not in cards)
  • language is unique within the scope of a translatee_id
  • no chains, the translatee card is always its own translatee
  • type_id, left_id, right_id are be considered General it that it will always be the translatee_id of the type card.

Name related constraints:

  • We have A+B exists => A exists and B exists.  This has implications for languages where the card with name and left, right, type references doesn't exist for a particular language and we do have tranlations for all parts of the name (and therefore the whole name).
  • Such are card will exist?, but there might not be content for the requested language.  UI has to deal with this, representationally this is a card that exists and has content, but no translated content. Developer interface for UI code will signal this state and the UI handles per mode.

Question: is a lang going to be a card or a new model?

How are these translation classes represented?  Is it connected to the lang model and by extension a property of tha name and content?  Maybe it just isn't represented at this level except by lang = NULL

Database references

 

For starters, I would propose these principles:
 
(assumes that translatee is the original and can have many translators)
  • never use the id of a translator card in a type_id, left_id, or right_id reference. Always use the original/translatee
  • however, do use the specific translatee id in card_references
 
Why the difference?  A link in a card can actually be pointing to one language or another.  The other fields are still referring specifically to the same group of cards, and it's cleanest to identify those with a single id.
 
Lets dig into the language on links more.  Presumably, the language of a cardname in an inclusion or link is tied up generally with the interpretation of contextual names.  It will look up the names in the language context of the content card, which doesn't have to be the translatee.  If it hits within the content language, then it will have that as its language and the translation class from the card it finds.  *structure rules will take some more thought.  My Universal class User card should have a *structure content that is language specific.
 
Let's play with a case or two, assuming for now that all applicable language rules are set to "translatable". Say you first created a Company type in English and then made a translation to Firma in German.
 
name, lang, id, translatee_id
Company, en, 1, 1
Firma, de, 2, 1
 
Then you created a company in German (assume for now that company names are language specific)
 
name, lang, id, translatee_id, type_id
Aldi, de, 3, 3, 1
 
That final "1" is the thing to notice.  It's the id of the original type card -- not the translation.
 
 
You might also find it weird that in "original" cards, I use the id (rather than null) as the translatee_id.  This is debatable, but I like the idea that you can just do this: 
select * from cards where translatee_id = 1 
...to get all the name variants (and not need special handling for the original in every query).  I suspect you can use that as a subquery in WQL's reference handling  to distinguish between language-specific and non-language-specific needs.
 
 
~~~~~~~
 
So far, this seems fairly plausible, and I'm starting to feel like I may need to thank you not only for not killing me, but also for saving us a hell of a lot of work.  But before I get prematurely exuberant, I'd say the next step would be to go through a bunch of sample wikirate cards and figure out how we'd represent both the rules and the data.
 
 

English in the Codebase

 

This proposal does not give much attention to handling multiple languages in hard-coded content, like text on buttons, error messages, etc.  That’s largely because it’s a very common problem with lots of helpful libraries / methodologies.

 

My expectation is that we’ll roughly follow the pattern of localization files, and that we’ll do this via “coded card content”, in which code is connected to a card via a codename.  This approach is nice because it avoids having to do code migrations with each update, but allows room for wagneers to break away from the codebase if they so desire by removing the card’s codename.

 

Singularization

 

Currently Wagn handles singularizing card names with an english-specific algorithm, but this algorithm applies to all cardnames regardless of their language.  In the new system, we can introduce Language Specific Key Generation.

 

Implementation

 

The proposal as it stands would involve a lot of work, including reworking:

 

  • the database

  • name processing

  • routing

  • WQL

  • caching

  • inclusion processing

  • links

  • a little bit of everything else

 

Existing Wagns

 

We would probably need to make a configuration option to allow existing (and future) wagns to remain monolingual, but we also need an upgrade path for those wishing to to make use of the functionality. The good news is the data migration can be kept very simple.