-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Content localization Proposal
geloescht edited this page Apr 18, 2016
·
4 revisions
var Article = new keystone.List('Article', {
autokey: { from: 'name', path: 'key', unique: true },
translation: true //to use built-in service
translation: require('custom-translation-service') //to inject a different service
});
Article.add({`
name: { type: String, required: true, translatable: true },
description: { type: String, translatable: true },
href: { type: String, translatable: false}`
});
There does not seem to be a way to implicitly set language on models in an opaque way, because keystone cannot determine from which request a model is accessed.
- Set language explicitly
-
+ Maximum backwards compatibility
-
- Transparent to developers, requires documentation
router.get('some-article', function(req, res) { context.list('Article').model.findOne({href: 'http://some.website/some/page'}).localize(req.language).exec(function(err, article) { res.end(article.name); }); }
- Wrap keystone features in "context" objects
-
+ Clean
-
+ Provides solution to other poblems as well, such as determining current user model for the request
-
- Might require restructuring of internals
-
- Transparent to developers, requires documentation
router.get('some-article', function(req, res) { var context = keystone.context(req); context.list('Article').model.findOne({href: 'http://some.website/some/page'}).exec(function(err, article) { res.end(article.name); }); // context should probably be chainable and be usable in different places var listContext = keystone.list('Article').context(req); var modelContext = keystone.list('Article').model.context(req); // keystone should provide a global context retrieving all language fields or a fallback language by default var globalContext = keystone; //context can also be contructed from manually supplied parameters var customContext = keystone.context({language: 'it'}); }
- Put all localized fields into one main document
- + no reference traversal
- + might be easily implemented with virtuals
- - big documents
- - growing documents
- ? impact on indexing
- store an embedded document per field with sub-fields per language (keyed by language code)
1. **language-code keys**
- **+** dead simple
- **-** bloat through many keys (on the good side, language codes are very short and compress well)
- **-** many projection criteria (one per translated field) when retrieving localised document
article_links:
{
_id: 'fhdsjfs',
href: 'http://some.website/some/page',
name:
{
en: 'Great Article',
de: 'Toller Artikel'
},
description:
{
en: 'This is the best article I've ever read!',
de: 'Das ist der beste Artikel, den ich jemals gelesen habe!'
}
}
2. **index-based language coding**
- **+** no key bloat
- **-** change in translated languages might require big database update
- **-** many projection criteria (one per translated field) if retrieving localized fields
- **?** impact on indexing
l10n:
{
languages: [ 'en', 'de' ]
}
article_links:
{
_id: 'fhdsjfs',
href: 'http://some.website/some/page',
name: [ 'Great Article', 'Toller Artikel' ],
description:[ 'This is the best article I've ever read!', 'Das ist der beste Artikel, den ich jemals gelesen habe!' ]
}
- store an embedded document per language with sub-fields per translatable field
- **+** quite simple
- **-** bloat through many keys (field keys can be any length, but compress well)
1. **language-code keys**
- **-** many projection criteria (one per translated field) if retrieving localized fields
article_links:
{
_id: 'fhdsjfs',
href: 'http://some.website/some/page',
l10n:
{
en:
{
name: 'Great Article',
description: 'This is the best article I've ever read!'
},
de:
{
name: 'Toller Artikel',
description: 'Das ist der beste Artikel, den ich jemals gelesen habe!'
}
}
}
1. **array with language tag**
- **+** simple projection criterion using $elemMatch
article_links:
{
_id: 'fhdsjfs',
href: 'http://some.website/some/page',
l10n:
[
{
language: 'en',
name: 'Great Article',
description: 'This is the best article I've ever read!'
},
{
language: 'de',
name: 'Toller Artikel',
description: 'Das ist der beste Artikel, den ich jemals gelesen habe!'
}
]
}
- Store different documents for each language (inside one or more extra collections)
- + no growing documents
- - additional overhead through referencing (when indexing on anything but the main _id)
- ? impact on indexing
- ? harder to implement
- one collection for translations and shared fields, indexed by group id
article_links:
{
group_id: 'fhdsjfs',
language: '',
href: 'http://some.website/some/page'
}
{
group_id: 'fhdsjfs',
language: 'en',
name: 'Great Article',
description: 'This is the best article I've ever read!'
}
{
group_id: 'fhdsjfs',
language: 'de',
name: 'Toller Artikel',
description: 'Das ist der beste Artikel, den ich jemals gelesen habe!'
}
- one collection for translations containing one document per language and main document
article_links:
{
_id: 'fhdsjfs',
href: 'http://some.website/some/page'
}
article_links_l10n:
{
article_links_id: 'fhdsjfs',
language: 'en',
name: 'Great Article',
description: 'This is the best article I've ever read!'
}
{
article_links_id: 'fhdsjfs',
language: 'de',
name: 'Toller Artikel',
description: 'Das ist der beste Artikel, den ich jemals gelesen habe!'
}
- one collection per language containing one document per main document
- **-** many collections
article_links:
{
_id: 'fhdsjfs',
href: 'http://some.website/some/page'
}
article_links_en:
{
article_links_id: 'fhdsjfs',
name: 'Great Article',
description: 'This is the best article I've ever read!'
}
article_links_de:
{`
article_links_id: 'fhdsjfs',
name: 'Toller Artikel',
description: 'Das ist der beste Artikel, den ich jemals gelesen habe!'
}
Home | Copyright © 2016 Jed Watson