jagi / meteor-astronomy

Model layer for Meteor
https://atmospherejs.com/jagi/astronomy
MIT License
604 stars 66 forks source link

Best i18n approach? #617

Open Lukasvo opened 7 years ago

Lukasvo commented 7 years ago

Hi jagi,

What do you think would be the best approach to translate my application based on Astronomy? Both hard-coded strings and database entries should be translated.

One approach might be to use the tap:i18n package with its db extension. The db structure looks like this:

{
    name: "Nikola Tesla",
    born: 1856,
    place_of_birth: {
        country: "Austrian Empire",
        city: "Smiljan"
    },
    i18n: {
        ru: {
            name: "Ни́кола Те́сла",
            place_of_birth: {
                country: "Австрийская империя",
                city: "Смилян"
            }
        }
    }
}

I've got two questions to implement this with Astronomy:

  1. When I use the find() method on an Astronomy class, the collection doesn't get translated. Invoking find() on the original collection does work correctly. Would this also be possible with the Astronomy class?
  2. How would I code the i18n field? I tried making a Union that recursively checks for documents that contain Strings only, but nesting Unions does not seem to work.

Any advice would be welcome. Thanks in advance!

Cheers! Lukas

lukejagodzinski commented 7 years ago

Hi @Lukasvo,

From what I see, it's gonna be a hard thing to do. You would have to create your own Astronomy module that handles i18n. It would be a lot of work. The class schema would be quite complex and all the operations would be hard to do. Depending on what for you want to use Astronomy I would recommend the following solution for that.

  1. Create Astronomy schema like a document would not be i18n
    name: String,
    born: Number,
    place_of_birth: { // Object or PlaceOfBirth class
    country: String
    city: String
    }
  2. Fetch documents using TapI18n way of doing things
  3. Transform documents by yourself using the transform option:
    tap_i18n_collection.i18nFind(selector, {
    transform(doc) {
    return new YourAstronomyClass(doc);
    }
    });
  4. Validate your documents using Astronomy:
    astroDoc.validate();
  5. Save your doc using TapI18n:
    const rawDoc = astroDoc.raw();
    // convert rawDoc to some translation data
    tap_i18n_collection. updateTranslations(translationData);

It's still a lot of work to do so it's not the best solution but should work. The best one would be creating dedicated Astronomy module for i18n but it would be a lot of work to do and i18n applications are not so common.

Lukasvo commented 7 years ago

Alright, thank you for your quick reply! I think creating a dedicated Astronomy module is a bit overambitious for my programming skills, so I'll try using the described method.

lukejagodzinski commented 7 years ago

Ok great, let me know if you have any problems with this approach

Lukasvo commented 7 years ago

Hi all

I've experimented somewhat with i18n. The transform function was a good idea, jagi, but I decided to move it to the Collection creation so I could also use Astronomy helpers etc. on the server.

export const Reservations = new TAPi18n.Collection('reservations', {
    transform(doc) {
        return new Reservation(doc);
    }
});

Note that classes using inheritance won't work properly with this approach (they'll be instances of the parent class). A switch case choosing the right constructor based on the doc's typeField is a possible solution.