> wrote:
> If i need to search and order by localizable properties. Which would be a
> good model for localizable entities? Which options should I consider?
> On Monday, October 8, 2012 11:23:04 AM UTC+2, Oren Eini wrote:
>> That would work, sure.
>> On Mon, Oct 8, 2012 at 11:04 AM, Jesús López <jesus.lope...@gmail.**com>wrote:
>>> If i need to search and order by localizable properties. Which would be
>>> a good model for localizable entities? Which options should I consider?
I happen to have a proprietary CMS that supports multiple locales and I did it the way that I separated content by language. For me, it's never really very logical that you have ONE instance of product or text or article (or anything else) in multiple languages. If it's an article, then different language means another article. Different article, with its own ID etc. That allows for more flexibility - you might have hundreds of articles in English but only a dozen in Spanish for instance. If you implemented it the way you described above, it would look to the end user or someone who doesn't know the system well that there are hundreds of articles in each and every language. It also makes it harder to pull out only the ones that are in Spanish. You inevitably end up with a lot of "if" checks..
to sum it up, I like to branch it by culture into a tree like structure, which work especially well within web apps.
On Monday, October 8, 2012 11:04:44 AM UTC+2, Jesús López wrote:
> If i need to search and order by localizable properties. Which would be a > good model for localizable entities? Which options should I consider?
Thank you for sharing your approach. I agree that, in a CMS, having a sepparate document per language or culture makes sense. However I think there are many entities that are localizable. Perhaps the product example was not the best one. But products are break down into categories and subcategories, and it seems very clear to me that "Beverages" are the same category as "Bebidas" and they have to share the same document id.
On Tuesday, October 9, 2012 2:07:59 AM UTC+2, mare wrote:
> Jesus,
> I happen to have a proprietary CMS that supports multiple locales and I > did it the way that I separated content by language. For me, it's never > really very logical that you have ONE instance of product or text or > article (or anything else) in multiple languages. If it's an article, then > different language means another article. Different article, with its own > ID etc. That allows for more flexibility - you might have hundreds of > articles in English but only a dozen in Spanish for instance. If you > implemented it the way you described above, it would look to the end user > or someone who doesn't know the system well that there are hundreds of > articles in each and every language. It also makes it harder to pull out > only the ones that are in Spanish. You inevitably end up with a lot of "if" > checks..
> to sum it up, I like to branch it by culture into a tree like structure, > which work especially well within web apps.
> HTH
> On Monday, October 8, 2012 11:04:44 AM UTC+2, Jesús López wrote:
>> If i need to search and order by localizable properties. Which would be a >> good model for localizable entities? Which options should I consider?
>> On Monday, October 8, 2012 11:23:04 AM UTC+2, Oren Eini wrote:
>>> That would work, sure.
>>> On Mon, Oct 8, 2012 at 11:04 AM, Jesús López <jesus.lope...@gmail.**com>wrote:
>>>> If i need to search and order by localizable properties. Which would be >>>> a good model for localizable entities? Which options should I consider?
What would happen if you have a product or article or what have you... that did not have a translation? How would you be able to at least serve up a default language? I may be getting a project where I have to support multiple languages, so this is a very interesting conversation to me.
First I would create a well known document with language settings:
public class LanguageSettings { public string Id { get { return "WellknownDocuments/LanguageSettings"; } } public string DefaultLanguage { get; set; } public List<string> SupportedLanguages { get; set; } public static LanguageSettings Instance { get; set; } }
To show products to the user you can use a view model that projects localized properties in the current language.
It would be great to have a mapper or something that simplifies things like this:
public class ProductViewModel { public string Id { get; set; } public decimal UnitPrice { get; set; } public string Name { get; set; } public string Description { get; set; } public ProductViewModel(){} public ProductViewModel(Product product, string languageCode) { this.Id = product.Id; this.UnitPrice = product.UnitPrice; Product.Localized lp = null; if (product.LocalizedProperties != null) { if (!product.LocalizedProperties.TryGetValue(languageCode, out lp)) { if (!product.LocalizedProperties.TryGetValue(LanguageSettings.Instance.Default Language, out lp)) { lp = product.LocalizedProperties.Select(kv => kv.Value).FirstOrDefault(); } } } if (lp != null) { this.Name = lp.Name; this.Description = lp.Description; } } }
There is a problem with searching, though. If there is no translation you will not find anything. But searching for the default language would probably return no results either.
Perhaps you could make sure that every localizable entity have a translation in every supported language.
On Tuesday, October 9, 2012 9:03:37 AM UTC+2, Troy wrote: > What would happen if you have a product or article or what have you... > that did not have a translation? How would you be able to at least serve up > a default language? I may be getting a project where I have to support > multiple languages, so this is a very interesting conversation to me.
"Perhaps you could make sure that every localizable entity have a translation in every supported language."
This is probable a wrong assumption, not a very realistic one.
What you have to think about is how those entities will be used, what use cases/scenario you want to support? For instance, I agree that the Product example might be bad. It is unlikely that you would need all the localizations in one place for a webstore since it is very likely a webstore for different country will be based on a different domain, it will follow different business rules etc. so it makes sense to dedicate a website/web application to one country.
On the other hand, if building like a company presentation website where you want to display company information to global visitors and give them the ability to switch for instance between English, Spanish and Russian site, it might make sense to say that there will always have to be a default culture for which every entity has content - that makes sense otherwise you would be serving up nothing;)
Then when the default language content is finished you might want to have the ability to export those entities, hand them over to translators and import them back in. That's why I said I'd have them as separate entities. They represent 1:1 the content that's similar to the original language but it's a copy of it. You want to be able to simply add or remove it. What happens if you want to remove a supported culture?
It will be a pain to go through all the entities and remove/empty their culture strings. It is much easier to have a culture identifier on the entity and then store it as such
en/article/1/about-us
sl/article/2/o-nas
You end up branching the content. When you only have "en/..." and you want to localize it, you take everything and translate it. When you want to remove a localization you just get rid of the branch and remove that language as supported.
To sum it up, I like your LanguageSettings file but I don't like the approach you did in ProductViewModel.
On Tuesday, October 9, 2012 9:36:42 AM UTC+2, Jesús López wrote:
> Yes,
> This is something that we need to deal with.
> First I would create a well known document with language settings:
> public class LanguageSettings
> {
> public string Id { get { return "WellknownDocuments/LanguageSettings"; } > }
> public string DefaultLanguage { get; set; }
> public List<string> SupportedLanguages { get; set; }
> public static LanguageSettings Instance { get; set; }
> }
> To show products to the user you can use a view model that projects > localized properties in the current language.
> It would be great to have a mapper or something that simplifies things > like this:
> public class ProductViewModel
> {
> public string Id { get; set; }
> public decimal UnitPrice { get; set; }
> public string Name { get; set; }
> public string Description { get; set; }
> public ProductViewModel(){}
> public ProductViewModel(Product product, string languageCode)
> {
> this.Id = product.Id;
> this.UnitPrice = product.UnitPrice;
> Product.Localized lp = null;
> if (product.LocalizedProperties != null)
> {
> if (!product.LocalizedProperties.TryGetValue(languageCode, out lp))
> {
> if > (!product.LocalizedProperties.TryGetValue(LanguageSettings.Instance.Default Language, > out lp))
> {
> lp = product.LocalizedProperties.Select(kv => > kv.Value).FirstOrDefault();
> }
> }
> }
> if (lp != null)
> {
> this.Name = lp.Name;
> this.Description = lp.Description;
> }
> }
> }
> There is a problem with searching, though. If there is no translation you > will not find anything. But searching for the default language would > probably return no results either.
> Perhaps you could make sure that every localizable entity have a > translation in every supported language.
> On Tuesday, October 9, 2012 9:03:37 AM UTC+2, Troy wrote:
>> What would happen if you have a product or article or what have you... >> that did not have a translation? How would you be able to at least serve up >> a default language? I may be getting a project where I have to support >> multiple languages, so this is a very interesting conversation to me.
We have entities such as PaymentMethod, ExpenseNoteStatus, ProcessTemplates (we use Workflow Foundation). One expense note needs to have a well defined payment method. I'm not going to put "en/PaymentMethods/1" as the PaymentMethodId in the expense note, I will put "PaymentMethods/1". ExpenseNotes have Expenses, and each Expense is of one ExpenseType. I'm not going to put "en/ExpenseTypes/1" into the ExpenseTypeId property of the expense, I will put "ExpenseTypes/1". The same ExpenseNote is viewed by several people from several countries. One sales person in Spain creates one document and one manager in UK might be required to approve the expense note. The sales person sees expense type name "Habitación de hotel" in spanish, and expense details such as the city "Londres" in spanish. The manager sees the expense type name in english "Hotel room", and the city "London" in english.
I agree the view model is awful, but with a good mapper I hope it become nicer.
Most localizable entities, are small collections, most are reference only collections. So I can ensure all supported languages have a value, may be the default value, but at least one value. That might be a bad idea, I'm experimenting with that. This is only for searching on localizable entities, another option is having one index per language per entity. The index would take the default language if not translated.
Your approach works for you, but I think it doesn't for me.
On Tuesday, October 9, 2012 11:47:06 AM UTC+2, mare wrote:
> "Perhaps you could make sure that every localizable entity have a > translation in every supported language."
> This is probable a wrong assumption, not a very realistic one.
> What you have to think about is how those entities will be used, what use > cases/scenario you want to support? For instance, I agree that the Product > example might be bad. It is unlikely that you would need all the > localizations in one place for a webstore since it is very likely a > webstore for different country will be based on a different domain, it will > follow different business rules etc. so it makes sense to dedicate a > website/web application to one country.
> On the other hand, if building like a company presentation website where > you want to display company information to global visitors and give them > the ability to switch for instance between English, Spanish and Russian > site, it might make sense to say that there will always have to be a > default culture for which every entity has content - that makes sense > otherwise you would be serving up nothing;)
> Then when the default language content is finished you might want to have > the ability to export those entities, hand them over to translators and > import them back in. That's why I said I'd have them as separate entities. > They represent 1:1 the content that's similar to the original language but > it's a copy of it. You want to be able to simply add or remove it. What > happens if you want to remove a supported culture?
> It will be a pain to go through all the entities and remove/empty their > culture strings. It is much easier to have a culture identifier on the > entity and then store it as such
> en/article/1/about-us
> sl/article/2/o-nas
> You end up branching the content. When you only have "en/..." and you want > to localize it, you take everything and translate it. When you want to > remove a localization you just get rid of the branch and remove that > language as supported.
> To sum it up, I like your LanguageSettings file but I don't like the > approach you did in ProductViewModel.
> What are you actually building?
> On Tuesday, October 9, 2012 9:36:42 AM UTC+2, Jesús López wrote:
>> Yes,
>> This is something that we need to deal with.
>> First I would create a well known document with language settings:
>> public class LanguageSettings
>> {
>> public string Id { get { return "WellknownDocuments/LanguageSettings"; >> } }
>> public string DefaultLanguage { get; set; }
>> public List<string> SupportedLanguages { get; set; }
>> public static LanguageSettings Instance { get; set; }
>> }
>> To show products to the user you can use a view model that projects >> localized properties in the current language.
>> It would be great to have a mapper or something that simplifies things >> like this:
>> public class ProductViewModel
>> {
>> public string Id { get; set; }
>> public decimal UnitPrice { get; set; }
>> public string Name { get; set; }
>> public string Description { get; set; }
>> public ProductViewModel(){}
>> public ProductViewModel(Product product, string languageCode)
>> {
>> this.Id = product.Id;
>> this.UnitPrice = product.UnitPrice;
>> Product.Localized lp = null;
>> if (product.LocalizedProperties != null)
>> {
>> if (!product.LocalizedProperties.TryGetValue(languageCode, out lp))
>> {
>> if >> (!product.LocalizedProperties.TryGetValue(LanguageSettings.Instance.Default Language, >> out lp))
>> {
>> lp = product.LocalizedProperties.Select(kv => >> kv.Value).FirstOrDefault();
>> }
>> }
>> }
>> if (lp != null)
>> {
>> this.Name = lp.Name;
>> this.Description = lp.Description;
>> }
>> }
>> }
>> There is a problem with searching, though. If there is no translation you >> will not find anything. But searching for the default language would >> probably return no results either.
>> Perhaps you could make sure that every localizable entity have a >> translation in every supported language.
>> On Tuesday, October 9, 2012 9:03:37 AM UTC+2, Troy wrote:
>>> What would happen if you have a product or article or what have you... >>> that did not have a translation? How would you be able to at least serve up >>> a default language? I may be getting a project where I have to support >>> multiple languages, so this is a very interesting conversation to me.
I recently built an application that needed multi-language support. There
are some tough debates to have. There's a very subtle difference between a
"translation of" and a "localized substitute for". Then you have some real
business decisions of "when there is no match for the requested culture,
show - english? esparanto? nothing?" If "no match" means, "not suitable for
that culture" you get a whole different solution than if the meaning is
"haven't translated it yet, so show them something that they might be able
to use".
Good discussion here. Thanks.
Reminds me that the next time I build such an app I want to use Raven.
Doing this in SQL Server was kind of a PITA.
On Tue, Oct 9, 2012 at 5:57 AM, Jesús López
<jesus.lopez.gurpe...@gmail.com>wrote:
> We have entities such as PaymentMethod, ExpenseNoteStatus,
> ProcessTemplates (we use Workflow Foundation). One expense note needs to
> have a well defined payment method. I'm not going to put
> "en/PaymentMethods/1" as the PaymentMethodId in the expense note, I will
> put "PaymentMethods/1". ExpenseNotes have Expenses, and each Expense is of
> one ExpenseType. I'm not going to put "en/ExpenseTypes/1" into the
> ExpenseTypeId property of the expense, I will put "ExpenseTypes/1". The
> same ExpenseNote is viewed by several people from several countries. One
> sales person in Spain creates one document and one manager in UK might be
> required to approve the expense note. The sales person sees expense type
> name "Habitación de hotel" in spanish, and expense details such as the city
> "Londres" in spanish. The manager sees the expense type name in english
> "Hotel room", and the city "London" in english.
> I agree the view model is awful, but with a good mapper I hope it become
> nicer.
> Most localizable entities, are small collections, most are reference only
> collections. So I can ensure all supported languages have a value, may be
> the default value, but at least one value. That might be a bad idea, I'm
> experimenting with that. This is only for searching on localizable
> entities, another option is having one index per language per entity. The
> index would take the default language if not translated.
> Your approach works for you, but I think it doesn't for me.
> On Tuesday, October 9, 2012 11:47:06 AM UTC+2, mare wrote:
>> "Perhaps you could make sure that every localizable entity have a
>> translation in every supported language."
>> This is probable a wrong assumption, not a very realistic one.
>> What you have to think about is how those entities will be used, what use
>> cases/scenario you want to support? For instance, I agree that the Product
>> example might be bad. It is unlikely that you would need all the
>> localizations in one place for a webstore since it is very likely a
>> webstore for different country will be based on a different domain, it will
>> follow different business rules etc. so it makes sense to dedicate a
>> website/web application to one country.
>> On the other hand, if building like a company presentation website where
>> you want to display company information to global visitors and give them
>> the ability to switch for instance between English, Spanish and Russian
>> site, it might make sense to say that there will always have to be a
>> default culture for which every entity has content - that makes sense
>> otherwise you would be serving up nothing;)
>> Then when the default language content is finished you might want to have
>> the ability to export those entities, hand them over to translators and
>> import them back in. That's why I said I'd have them as separate entities.
>> They represent 1:1 the content that's similar to the original language but
>> it's a copy of it. You want to be able to simply add or remove it. What
>> happens if you want to remove a supported culture?
>> It will be a pain to go through all the entities and remove/empty their
>> culture strings. It is much easier to have a culture identifier on the
>> entity and then store it as such
>> en/article/1/about-us
>> sl/article/2/o-nas
>> You end up branching the content. When you only have "en/..." and you
>> want to localize it, you take everything and translate it. When you want to
>> remove a localization you just get rid of the branch and remove that
>> language as supported.
>> To sum it up, I like your LanguageSettings file but I don't like the
>> approach you did in ProductViewModel.
>> What are you actually building?
>> On Tuesday, October 9, 2012 9:36:42 AM UTC+2, Jesús López wrote:
>>> Yes,
>>> This is something that we need to deal with.
>>> First I would create a well known document with language settings:
>>> public class LanguageSettings
>>> {
>>> public string Id { get { return "WellknownDocuments/**LanguageSettings";
>>> } }
>>> public string DefaultLanguage { get; set; }
>>> public List<string> SupportedLanguages { get; set; }
>>> public static LanguageSettings Instance { get; set; }
>>> }
>>> To show products to the user you can use a view model that projects
>>> localized properties in the current language.
>>> It would be great to have a mapper or something that simplifies things
>>> like this:
>>> public class ProductViewModel
>>> {
>>> public string Id { get; set; }
>>> public decimal UnitPrice { get; set; }
>>> public string Name { get; set; }
>>> public string Description { get; set; }
>>> public ProductViewModel(){}
>>> public ProductViewModel(Product product, string languageCode)
>>> {
>>> this.Id = product.Id;
>>> this.UnitPrice = product.UnitPrice;
>>> Product.Localized lp = null;
>>> if (product.LocalizedProperties != null)
>>> {
>>> if (!product.LocalizedProperties.**TryGetValue(languageCode, out
>>> lp))
>>> {
>>> if (!product.LocalizedProperties.**TryGetValue(LanguageSettings.**Instance.Def aultLanguage,
>>> out lp))
>>> {
>>> lp = product.LocalizedProperties.**Select(kv =>
>>> kv.Value).FirstOrDefault();
>>> }
>>> }
>>> }
>>> if (lp != null)
>>> {
>>> this.Name = lp.Name;
>>> this.Description = lp.Description;
>>> }
>>> }
>>> }
>>> There is a problem with searching, though. If there is no translation
>>> you will not find anything. But searching for the default language would
>>> probably return no results either.
>>> Perhaps you could make sure that every localizable entity have a
>>> translation in every supported language.
>>> On Tuesday, October 9, 2012 9:03:37 AM UTC+2, Troy wrote:
>>>> What would happen if you have a product or article or what have you...
>>>> that did not have a translation? How would you be able to at least serve up
>>>> a default language? I may be getting a project where I have to support
>>>> multiple languages, so this is a very interesting conversation to me.
The approach that I find working fine is "have a default value unless
there's a specific locale for it" for translation scenario.
For example, I have Arabic, English and Indonesian as a target language. I
usually build English content and then progressively translate them to
other languages. When user is looking for Arabic for example (/ar/about-us)
and the translation is not available, I show them by default the English
language.
On Wed, Oct 10, 2012 at 2:18 AM, Kijana Woodard <kijana.wood...@gmail.com>wrote:
> I recently built an application that needed multi-language support. There
> are some tough debates to have. There's a very subtle difference between a
> "translation of" and a "localized substitute for". Then you have some real
> business decisions of "when there is no match for the requested culture,
> show - english? esparanto? nothing?" If "no match" means, "not suitable for
> that culture" you get a whole different solution than if the meaning is
> "haven't translated it yet, so show them something that they might be able
> to use".
> Good discussion here. Thanks.
> Reminds me that the next time I build such an app I want to use Raven.
> Doing this in SQL Server was kind of a PITA.
> On Tue, Oct 9, 2012 at 5:57 AM, Jesús López <
> jesus.lopez.gurpe...@gmail.com> wrote:
>> Mare,
>> We build LOB enterprise applications.
>> We have entities such as PaymentMethod, ExpenseNoteStatus,
>> ProcessTemplates (we use Workflow Foundation). One expense note needs to
>> have a well defined payment method. I'm not going to put
>> "en/PaymentMethods/1" as the PaymentMethodId in the expense note, I will
>> put "PaymentMethods/1". ExpenseNotes have Expenses, and each Expense is of
>> one ExpenseType. I'm not going to put "en/ExpenseTypes/1" into the
>> ExpenseTypeId property of the expense, I will put "ExpenseTypes/1". The
>> same ExpenseNote is viewed by several people from several countries. One
>> sales person in Spain creates one document and one manager in UK might be
>> required to approve the expense note. The sales person sees expense type
>> name "Habitación de hotel" in spanish, and expense details such as the city
>> "Londres" in spanish. The manager sees the expense type name in english
>> "Hotel room", and the city "London" in english.
>> I agree the view model is awful, but with a good mapper I hope it become
>> nicer.
>> Most localizable entities, are small collections, most are reference only
>> collections. So I can ensure all supported languages have a value, may be
>> the default value, but at least one value. That might be a bad idea, I'm
>> experimenting with that. This is only for searching on localizable
>> entities, another option is having one index per language per entity. The
>> index would take the default language if not translated.
>> Your approach works for you, but I think it doesn't for me.
>> On Tuesday, October 9, 2012 11:47:06 AM UTC+2, mare wrote:
>>> "Perhaps you could make sure that every localizable entity have a
>>> translation in every supported language."
>>> This is probable a wrong assumption, not a very realistic one.
>>> What you have to think about is how those entities will be used, what
>>> use cases/scenario you want to support? For instance, I agree that the
>>> Product example might be bad. It is unlikely that you would need all the
>>> localizations in one place for a webstore since it is very likely a
>>> webstore for different country will be based on a different domain, it will
>>> follow different business rules etc. so it makes sense to dedicate a
>>> website/web application to one country.
>>> On the other hand, if building like a company presentation website where
>>> you want to display company information to global visitors and give them
>>> the ability to switch for instance between English, Spanish and Russian
>>> site, it might make sense to say that there will always have to be a
>>> default culture for which every entity has content - that makes sense
>>> otherwise you would be serving up nothing;)
>>> Then when the default language content is finished you might want to
>>> have the ability to export those entities, hand them over to translators
>>> and import them back in. That's why I said I'd have them as separate
>>> entities. They represent 1:1 the content that's similar to the original
>>> language but it's a copy of it. You want to be able to simply add or remove
>>> it. What happens if you want to remove a supported culture?
>>> It will be a pain to go through all the entities and remove/empty their
>>> culture strings. It is much easier to have a culture identifier on the
>>> entity and then store it as such
>>> en/article/1/about-us
>>> sl/article/2/o-nas
>>> You end up branching the content. When you only have "en/..." and you
>>> want to localize it, you take everything and translate it. When you want to
>>> remove a localization you just get rid of the branch and remove that
>>> language as supported.
>>> To sum it up, I like your LanguageSettings file but I don't like the
>>> approach you did in ProductViewModel.
>>> What are you actually building?
>>> On Tuesday, October 9, 2012 9:36:42 AM UTC+2, Jesús López wrote:
>>>> Yes,
>>>> This is something that we need to deal with.
>>>> First I would create a well known document with language settings:
>>>> public class LanguageSettings
>>>> {
>>>> public string Id { get { return "WellknownDocuments/**LanguageSettings";
>>>> } }
>>>> public string DefaultLanguage { get; set; }
>>>> public List<string> SupportedLanguages { get; set; }
>>>> public static LanguageSettings Instance { get; set; }
>>>> }
>>>> To show products to the user you can use a view model that projects
>>>> localized properties in the current language.
>>>> It would be great to have a mapper or something that simplifies things
>>>> like this:
>>>> public class ProductViewModel
>>>> {
>>>> public string Id { get; set; }
>>>> public decimal UnitPrice { get; set; }
>>>> public string Name { get; set; }
>>>> public string Description { get; set; }
>>>> public ProductViewModel(){}
>>>> public ProductViewModel(Product product, string languageCode)
>>>> {
>>>> this.Id = product.Id;
>>>> this.UnitPrice = product.UnitPrice;
>>>> Product.Localized lp = null;
>>>> if (product.LocalizedProperties != null)
>>>> {
>>>> if (!product.LocalizedProperties.**TryGetValue(languageCode, out
>>>> lp))
>>>> {
>>>> if (!product.LocalizedProperties.**TryGetValue(LanguageSettings.**Instance.Def aultLanguage,
>>>> out lp))
>>>> {
>>>> lp = product.LocalizedProperties.**Select(kv =>
>>>> kv.Value).FirstOrDefault();
>>>> }
>>>> }
>>>> }
>>>> if (lp != null)
>>>> {
>>>> this.Name = lp.Name;
>>>> this.Description = lp.Description;
>>>> }
>>>> }
>>>> }
>>>> There is a problem with searching, though. If there is no translation
>>>> you will not find anything. But searching for the default language would
>>>> probably return no results either.
>>>> Perhaps you could make sure that every localizable entity have a
>>>> translation in every supported language.
>>>> On Tuesday, October 9, 2012 9:03:37 AM UTC+2, Troy wrote:
>>>>> What would happen if you have a product or article or what have you...
>>>>> that did not have a translation? How would you be able to at least serve up
>>>>> a default language? I may be getting a project where I have to support
>>>>> multiple languages, so this is a very interesting conversation to me.
Yup. That was the route I went in the previous app as well. It's just not
universally correct.
On Oct 10, 2012 4:53 AM, "Dody Gunawinata" <empirebuil...@gmail.com> wrote:
> The approach that I find working fine is "have a default value unless
> there's a specific locale for it" for translation scenario.
> For example, I have Arabic, English and Indonesian as a target language. I
> usually build English content and then progressively translate them to
> other languages. When user is looking for Arabic for example (/ar/about-us)
> and the translation is not available, I show them by default the English
> language.
> On Wed, Oct 10, 2012 at 2:18 AM, Kijana Woodard <kijana.wood...@gmail.com>wrote:
>> I recently built an application that needed multi-language support. There
>> are some tough debates to have. There's a very subtle difference between a
>> "translation of" and a "localized substitute for". Then you have some real
>> business decisions of "when there is no match for the requested culture,
>> show - english? esparanto? nothing?" If "no match" means, "not suitable for
>> that culture" you get a whole different solution than if the meaning is
>> "haven't translated it yet, so show them something that they might be able
>> to use".
>> Good discussion here. Thanks.
>> Reminds me that the next time I build such an app I want to use Raven.
>> Doing this in SQL Server was kind of a PITA.
>> On Tue, Oct 9, 2012 at 5:57 AM, Jesús López <
>> jesus.lopez.gurpe...@gmail.com> wrote:
>>> Mare,
>>> We build LOB enterprise applications.
>>> We have entities such as PaymentMethod, ExpenseNoteStatus,
>>> ProcessTemplates (we use Workflow Foundation). One expense note needs to
>>> have a well defined payment method. I'm not going to put
>>> "en/PaymentMethods/1" as the PaymentMethodId in the expense note, I will
>>> put "PaymentMethods/1". ExpenseNotes have Expenses, and each Expense is of
>>> one ExpenseType. I'm not going to put "en/ExpenseTypes/1" into the
>>> ExpenseTypeId property of the expense, I will put "ExpenseTypes/1". The
>>> same ExpenseNote is viewed by several people from several countries. One
>>> sales person in Spain creates one document and one manager in UK might be
>>> required to approve the expense note. The sales person sees expense type
>>> name "Habitación de hotel" in spanish, and expense details such as the city
>>> "Londres" in spanish. The manager sees the expense type name in english
>>> "Hotel room", and the city "London" in english.
>>> I agree the view model is awful, but with a good mapper I hope it become
>>> nicer.
>>> Most localizable entities, are small collections, most are reference
>>> only collections. So I can ensure all supported languages have a value, may
>>> be the default value, but at least one value. That might be a bad idea, I'm
>>> experimenting with that. This is only for searching on localizable
>>> entities, another option is having one index per language per entity. The
>>> index would take the default language if not translated.
>>> Your approach works for you, but I think it doesn't for me.
>>> On Tuesday, October 9, 2012 11:47:06 AM UTC+2, mare wrote:
>>>> "Perhaps you could make sure that every localizable entity have a
>>>> translation in every supported language."
>>>> This is probable a wrong assumption, not a very realistic one.
>>>> What you have to think about is how those entities will be used, what
>>>> use cases/scenario you want to support? For instance, I agree that the
>>>> Product example might be bad. It is unlikely that you would need all the
>>>> localizations in one place for a webstore since it is very likely a
>>>> webstore for different country will be based on a different domain, it will
>>>> follow different business rules etc. so it makes sense to dedicate a
>>>> website/web application to one country.
>>>> On the other hand, if building like a company presentation website
>>>> where you want to display company information to global visitors and give
>>>> them the ability to switch for instance between English, Spanish and
>>>> Russian site, it might make sense to say that there will always have to be
>>>> a default culture for which every entity has content - that makes sense
>>>> otherwise you would be serving up nothing;)
>>>> Then when the default language content is finished you might want to
>>>> have the ability to export those entities, hand them over to translators
>>>> and import them back in. That's why I said I'd have them as separate
>>>> entities. They represent 1:1 the content that's similar to the original
>>>> language but it's a copy of it. You want to be able to simply add or remove
>>>> it. What happens if you want to remove a supported culture?
>>>> It will be a pain to go through all the entities and remove/empty their
>>>> culture strings. It is much easier to have a culture identifier on the
>>>> entity and then store it as such
>>>> en/article/1/about-us
>>>> sl/article/2/o-nas
>>>> You end up branching the content. When you only have "en/..." and you
>>>> want to localize it, you take everything and translate it. When you want to
>>>> remove a localization you just get rid of the branch and remove that
>>>> language as supported.
>>>> To sum it up, I like your LanguageSettings file but I don't like the
>>>> approach you did in ProductViewModel.
>>>> What are you actually building?
>>>> On Tuesday, October 9, 2012 9:36:42 AM UTC+2, Jesús López wrote:
>>>>> Yes,
>>>>> This is something that we need to deal with.
>>>>> First I would create a well known document with language settings:
>>>>> public class LanguageSettings
>>>>> {
>>>>> public string Id { get { return "WellknownDocuments/**LanguageSettings";
>>>>> } }
>>>>> public string DefaultLanguage { get; set; }
>>>>> public List<string> SupportedLanguages { get; set; }
>>>>> public static LanguageSettings Instance { get; set; }
>>>>> }
>>>>> To show products to the user you can use a view model that projects
>>>>> localized properties in the current language.
>>>>> It would be great to have a mapper or something that simplifies things
>>>>> like this:
>>>>> public class ProductViewModel
>>>>> {
>>>>> public string Id { get; set; }
>>>>> public decimal UnitPrice { get; set; }
>>>>> public string Name { get; set; }
>>>>> public string Description { get; set; }
>>>>> public ProductViewModel(){}
>>>>> public ProductViewModel(Product product, string languageCode)
>>>>> {
>>>>> this.Id = product.Id;
>>>>> this.UnitPrice = product.UnitPrice;
>>>>> Product.Localized lp = null;
>>>>> if (product.LocalizedProperties != null)
>>>>> {
>>>>> if (!product.LocalizedProperties.**TryGetValue(languageCode, out
>>>>> lp))
>>>>> {
>>>>> if (!product.LocalizedProperties.**TryGetValue(LanguageSettings.*
>>>>> *Instance.DefaultLanguage, out lp))
>>>>> {
>>>>> lp = product.LocalizedProperties.**Select(kv =>
>>>>> kv.Value).FirstOrDefault();
>>>>> }
>>>>> }
>>>>> }
>>>>> if (lp != null)
>>>>> {
>>>>> this.Name = lp.Name;
>>>>> this.Description = lp.Description;
>>>>> }
>>>>> }
>>>>> }
>>>>> There is a problem with searching, though. If there is no translation
>>>>> you will not find anything. But searching for the default language would
>>>>> probably return no results either.
>>>>> Perhaps you could make sure that every localizable entity have a
>>>>> translation in every supported language.
>>>>> On Tuesday, October 9, 2012 9:03:37 AM UTC+2, Troy wrote:
>>>>>> What would happen if you have a product or article or what have
>>>>>> you... that did not have a translation? How would you be able to at least
>>>>>> serve up a default language? I may be getting a project where I have to
>>>>>> support multiple languages, so this is a very interesting conversation to
>>>>>> me.