
The other day I was speaking with a woman on the train. She was
telling me about her daughters. I wanted to ask her how old they are,
but I got the pluralization wrong and instead of saying "bnot kama"
(plural) I said "bat kama," (singular) to which she responded 36.
tl;dr: You can offend people just was well with pluralization issues
as with gender issues.
Michael
On Mon, Feb 21, 2011 at 8:40 AM, Max Cantor
Of course, you just pointed out one of the big difficulties with i18n. I dont think you're wife would take kindly to you referring to her in the male gender. so now, you need the person's gender too. i18n is hard :( the whole would should switch to esperanto.
max
On Feb 21, 2011, at 2:25 PM, Michael Snoyman wrote:
A proper i18n solution is high on my wish list right now, but I've purposely avoided implementing one so far since I'd rather wait until I think we have a good solution as opposed to implementing an acceptable solution now. But let me share my ideas, it might help you out here.
In general, it's very uncommon that you need a completely separate set of templates for each language. Your markup, classes, styles, and logic will likely be identical for each language, and creating a separate template for each will just result in a lot of pain in the long run. Instead, you're likely better off having a single template and just translating strings.
I've blogged about this before[1]. My idea is to use a datatype for your translatable strings, and then have a function that takes a language and a value and returns the translated string. A simple example:
data Strings = Hello | Person String Int toEnglish Hello = "Hello" toEnglish (Person name age) = name ++ " is " ++ show age ++ " years old" -- obviously need to check if person is 1 year old and correct
toHebrew Hello = "שלום" toHebrew (Person name age) = name ++ " הוא בן " ++ show age ++ " שנים"
The nice thing about this approach is you have the full power of Haskell to address typical translation issues, such as pluralization, word order and gender matching. (As a counter example, at work, we use XSLT for this, and then you get the full power of XSLT for solving the problem ::cringe::.)
You can then use the languages[2] function from Yesod to help you out:
getRenderString = chooseFunc `fmap` languages where chooseFunc [] = toEnglish -- default language chooseFunc ("en":_) = toEnglish chooseFunc ("he":_) = toHebrew chooseFunc (_:x) = chooseFunc x
Then you can write a handler function like:
getPersonR name age = do render <- getRenderString defaultLayout [$hamlet| <h1>#{render Hello} <p>#{render $ Person name age} |]
Which will work for English and Hebrew just fine. Ideally, I would like to add support to Hamlet for this directly, involving a String rendering function similar to the URL rendering function already in place. But for the moment, this should work.
I'd love to hear peoples opinions about this.
Michael
[1] http://docs.yesodweb.com/blog/i18n-in-haskell [2] http://hackage.haskell.org/packages/archive/yesod-core/0.7.0.1/doc/html/Yeso...
On Sun, Feb 20, 2011 at 11:19 PM, Dmitry Kurochkin
wrote: Hi all.
I want a handler to render different templates for different languages. I have getCurrentLanguage function and now I try to do something like:
getRootR = do currentLanguage <- getCurrentLanguage defaultLayout $ do addWidget $(widgetFile $ currentLanguage ++ "/homepage")
This results in:
GHC stage restriction: `currentLanguage' is used in a top-level splice or annotation, and must be imported, not defined locally
This makes sense to me, because TH is calculated at compile time. I would like to hear ideas how to work around this restriction. Perhaps there is an existing solution in Yesod?
At the moment, the best I could think of is smth like this:
getRootR = do currentLanguage <- getCurrentLanguage defaultLayout $ do case currentLanguage of "en" -> addWidget $(widgetFile "en/homepage") ... and so on for each language ...
Obviously, this is not a solution taking in account that there are many languages and many handlers.
I was considering creating a global (template file name -> rendered template) map. But I am not sure this is really feasible.
Regards, Dmitry
_______________________________________________ web-devel mailing list web-devel@haskell.org http://www.haskell.org/mailman/listinfo/web-devel
_______________________________________________ web-devel mailing list web-devel@haskell.org http://www.haskell.org/mailman/listinfo/web-devel