Panu, maybe you may want to cc seaside mailing list too ;)
On Fri, Sep 10, 2010 at 2:41 PM, Panu Suominen <[hidden email]> wrote: 2010/9/10 Stanislav Paskalev <[hidden email]>: _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
To keep the story short. I did not find any tools to use translations in seaside and magritte so I had to made something up on my own. I am skeptic wether it will have any value beyond myself but comments are very welcome.
There is more explanation in the following conversation: (pharo-project subscribers, sorry for double post). Forwarded conversation Subject: i18n tools ------------------------ From: Panu Suominen <[hidden email]> Date: 2010/9/9 To: [hidden email] I am researching wether out team could start using Pharo. I have tried to locate some tools to do user interface translations but I did not find anything in time so I had to develop some rudimentary key-based translation tools my self. I would like to know is this lack of translation tools reality and if others are having same kind of problems? -- Panu ---------- From: Stéphane Ducasse <[hidden email]> Date: 2010/9/9 To: [hidden email], A friendly place where any question about pharo is welcome <[hidden email]> Cc: Hilaire Fernandes <[hidden email]> hilaire can you provide some pointers because you did a lot of translations. Stef > _______________________________________________ > Pharo-users mailing list > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-users ---------- From: Panu Suominen <[hidden email]> Date: 2010/9/10 To: Stéphane Ducasse <[hidden email]> Cc: A friendly place where any question about pharo is welcome <[hidden email]>, Hilaire Fernandes <[hidden email]> To stimulate little more.. I have done rudimentary translation support for magritte and seaside. Should I publish them or are there already working options? -- Panu ---------- From: Stanislav Paskalev <[hidden email]> Date: 2010/9/10 To: [hidden email], A friendly place where any question about pharo is welcome <[hidden email]> Seaside had none the last time I asked. Please do so. Stanislav Paskalev ---------- From: Panu Suominen <[hidden email]> Date: 2010/9/10 To: Stanislav Paskalev <[hidden email]> Cc: A friendly place where any question about pharo is welcome <[hidden email]> 2010/9/10 Stanislav Paskalev <[hidden email]>: I am in a bit hurry, but I hope you can still make sense out of this. The whole seaside and translation thing is based on the fact that Seaside render: method is dispatched to objects renderOn: method where we can access session. On the other hand we can store language to session. If we implement object that is able to answer correctly to translate: -message with language as a parameter we have a simple translation framework. I created a simple translation framework which is able to return translation for certain key. Keys are looked from properly named subclass. Names are form of LanguagePackOfProgramX_fi, LanguagePackOfProgramX_en. Each containing translations for the given language. K3LanguagePack and tests should give better idea. Notice that examples below need language -method in session.... Example to use with seaside: renderContentOn: html html render: (LanguegPackOfMyProgram translationFor: #greetingMessge) Example with magritte: descriptionEmail ^MAStringDescription new accessor: #email; label: (K3CoreLanguagePack translationFor: #email); addCondition: [:value | value includes: $@] labelled: (LanguegPackOfMyProgram translationFor: #emailNotValid); beRequired; requiredErrorMessage: (LanguegPackOfMyProgram translationFor: #emailIsRequired); priority: 10; yourself. The magritte part was builded on top of 2.0.5 magritte-seaside. This code enabled me to build seaside application demo that could change its user interface on the fly. Meaning that anything else stays as it is, only the language changes. But I don't know how useful this is for other people. Currently the major flaw is that there is no way to set the arguments for the translation ('Hello user, your name is {1}'). It is not a big addition but haven't needed it in this proof of concept. However it should not be very hard to implement. Other thing that should be discussed is the way translations are stored. I chose to use symbols that points to methods and thus translations can be encapsulated in classes. However there seems to be NaturalLanguageTranslator and string translate already in existence and I am wondering should I change the implementation to use them instead. I am very open to suggestions. -- Panu ---------- From: Mariano Martinez Peck <[hidden email]> Date: 2010/9/10 To: [hidden email], A friendly place where any question about pharo is welcome <[hidden email]> Cc: Seaside - general discussion <[hidden email]> Panu, maybe you may want to cc seaside mailing list too ;) -- Panu _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside Korppi-Translation-PanuSuominen.4.1.cs (12K) Download Attachment |
In reply to this post by Mariano Martinez Peck
2010/9/10 Hilaire Fernandes <[hidden email]>:
> Check with Philip Marchall, he did modification to use gettext code with > Seaside. Ok. Thanks to all for the help. Seaside and gettext are apparently the magic words that solves this problem. :) http://forum.world.st/Seaside-Gettext-sneak-peak-td2164600.html -- Panu _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
2010/9/10 Panu Suominen <[hidden email]>:
> 2010/9/10 Hilaire Fernandes <[hidden email]>: >> Check with Philip Marchall, he did modification to use gettext code with >> Seaside. > > Ok. Thanks to all for the help. Seaside and gettext are apparently the magic > words that solves this problem. :) > > http://forum.world.st/Seaside-Gettext-sneak-peak-td2164600.html I believe you can not get gettext from here [1]. The repo for Seaside-Gettext is still the same. [1] http://www.squeaksource.com/PharoNonCorePackages Cheers Philippe _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
2010/9/11 Philippe Marschall <[hidden email]>:
> I believe you can not get gettext from here [1]. Why is that? Following code seemed to do the loading fine. Gofer new squeaksource: 'PharoNonCorePackages'; package: 'ConfigurationOfGettext'; load. ((Smalltalk at: #ConfigurationOfGettext) project version:'1.0') load. Couple of questions: 1) What is the preferred method to use variable content in strings? Is it: 'The time now is {1}' translated format: {Time now} 2) Is there already a plan to support above kind of parametrisation in Seaside? 3) Is there a way to translate magrittes validation errors? Does it seem good idea to create class that is going to be translated (but not yet is) and the translation is resolved later. For example when seaside's render: method is called. This way magritte errors could be transalted when they get rendered. Actually translated method could return this kind of objects and the resulting object's asString (printOn:) and renderOn: could do the actual translation With same kind of idea one could also pass the arguments to the actual translation. For example t := 'The time is now {1}' translatedWith:{[Time now]} "in seaside:" html render: t Does this make any sense? Or is there already a better solution/plan? -- Panu _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
2010/9/11 Panu Suominen <[hidden email]>:
> 2010/9/11 Philippe Marschall <[hidden email]>: >> I believe you can not get gettext from here [1]. > Why is that? Dunno, ask Hilaire. > Following code seemed to do the loading fine. > Gofer new squeaksource: 'PharoNonCorePackages'; package: > 'ConfigurationOfGettext'; load. > ((Smalltalk at: #ConfigurationOfGettext) project version:'1.0') load. > > Couple of questions: > 1) What is the preferred method to use variable content in strings? Is it: > 'The time now is {1}' translated format: {Time now} Variable content is not supported, that's mainly a Gettext issue. You can use the above code but ignores the locale of the session, the result will probably be a bit underwhelming > 2) Is there already a plan to support above kind of parametrisation in Seaside? Once Gettext supports it, yes. > 3) Is there a way to translate magrittes validation errors? Not out of the box. You'd probably have to customize Magritte error rendering. > Does it seem good idea to create class that is going to be translated > (but not yet is) and the translation > is resolved later. For example when seaside's render: method is > called. This way magritte errors > could be transalted when they get rendered. Actually translated method > could return this > kind of objects and the resulting object's asString (printOn:) and > renderOn: could do the actual > translation I don't quite follow. > With same kind of idea one could also pass the arguments to the actual > translation. For example > t := 'The time is now {1}' translatedWith:{[Time now]} > "in seaside:" > html render: t > > Does this make any sense? Or is there already a better solution/plan? Again, once Gettext supports it, I'd be happy to add support for it in Seaside-Gettext. Cheers Philippe _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
2010/9/11 Philippe Marschall <[hidden email]>:
>> Does it seem good idea to create class that is going to be translated >> (but not yet is) and the translation >> is resolved later. > I don't quite follow. Ok. I try to explain my idea better. With magritte you have to spell out the error messages before you know anything about the locale of the user who is going to see the messages. One can of course write those error messages as plain strings and then write alternative seaside component to translate the string later. However with this kind of aproach there is no way to extract the translations for .pot file. This problem (and the need for special translate: -seside method) would go away if the String translate method would return object that translates itself when the actual translated version is needed (basically printOn: and renderOn: methods). The main parts of the effective code would be something like this: String>>translated "answer the receiver translated to the default language" ^LazyTranslation fromString: self. LazyTranslation>>renderOn: html html text: (self translate: WACurrentLocalizationContext value localeID). LazyTranslation>>printOn: aStream ^self translate. LazyTranslation>>translate ^(NaturalLanguageTranslator translate: msgid). LazyTranslation>>translate: localeID ^(NaturalLanguageTranslator translate: msgid to: localeID). Of course LazyTranslation should have to fake it string nature with additional methods. The goal of this approach is simply decouple the creation of translation and printing it using some locale. I hope this made more sense. -- Panu _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
In reply to this post by Mariano Martinez Peck
VisualWorks has UserMessage that renders actual translated string based on the current process' locale (provided a matching catalog in that locale is available, of course) which is set by the session (technically a filter on the session). It also has an optional default string to support lazy catalog implementation. UserMessage instance can be created in code via, _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
In reply to this post by Panu Suominen-3
2010/9/12 Panu Suominen <[hidden email]>:
> 2010/9/11 Philippe Marschall <[hidden email]>: >>> Does it seem good idea to create class that is going to be translated >>> (but not yet is) and the translation >>> is resolved later. >> I don't quite follow. > > Ok. I try to explain my idea better. With magritte you have to spell > out the error messages before you know anything about the locale of > the user who is going to see the messages. Nope. The locale is set before the Magritte code even kicks in. > One can of course write > those error messages as plain strings and then write alternative > seaside component to translate the string later. However with this > kind of aproach there is no way to extract the translations for .pot > file. > > This problem (and the need for special translate: -seside method) > would go away if the String translate method would return object that > translates itself when the actual translated version is needed > (basically printOn: and renderOn: methods). > > The main parts of the effective code would be something like this: > > String>>translated > "answer the receiver translated to the default language" > ^LazyTranslation fromString: self. Override in String, not gonna happen. > LazyTranslation>>renderOn: html > html text: (self translate: WACurrentLocalizationContext value localeID). > > LazyTranslation>>printOn: aStream > ^self translate. > > LazyTranslation>>translate > ^(NaturalLanguageTranslator translate: msgid). > > LazyTranslation>>translate: localeID > ^(NaturalLanguageTranslator translate: msgid to: localeID). > > > Of course LazyTranslation should have to fake it string nature with > additional methods. The goal of this approach is simply decouple the > creation of translation and printing it using some locale. I hope this > made more sense. Cheers Philippe _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
>> Ok. I try to explain my idea better. With magritte you have to spell
>> out the error messages before you know anything about the locale of >> the user who is going to see the messages. > > Nope. The locale is set before the Magritte code even kicks in. Yes, there is some locale at the time magritte reads the meta-data and creates the component, but this locale might not be the locale user wants to use in user interface. User might change the locale/language for the session but this does not affect the magritte code because the error messages are created with different locale. And I think that is a problem. Or is there something I don't understand? -- Panu _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
In reply to this post by Philippe Marschall
Translation is not limited to seaside?
> >>> I believe you can not get gettext from here [1]. >> Why is that? > > Dunno, ask Hilaire. > >> Following code seemed to do the loading fine. >> Gofer new squeaksource: 'PharoNonCorePackages'; package: >> 'ConfigurationOfGettext'; load. >> ((Smalltalk at: #ConfigurationOfGettext) project version:'1.0') load. _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
Because of the responses I have received here, I am pretty sure the
code I attached has no use for others, but I decided to send it here anyways. I have had such hard time to find any resources about translating text in seaside that this can not make the situation much worse. :) Attached change set will add asTranslation method to String class. This method will create LazyTranslation which does the actual translation "on the fly" when needed. This approach enables seaside to translate text without using translate: -method, but remember to use the WALocalizationContextFilter with the application. Using render: -will render the text with the locale used by the session and text: will use the local of the image. Also magritte forms get translated correctly without any modifications to the magritte code. To use it write descriptions following way: descriptionEmail ^MAStringDescription new accessor: #email; label: 'Email' asTranslation; addCondition: [:value | value includes: $@] labelled: 'Email is not valid.' asTranslation; beRequired; priority: 10; yourself. I know that the code is bad, but I really needed the feature. At least I hope that I get a lots of reasons why the approach I have taken is really a wrong way to go. Sorry to bother you with this so much. -- Panu _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside gettext-translation.1.cs (3K) Download Attachment |
In reply to this post by Panu Suominen-3
2010/9/12 Panu Suominen <[hidden email]>:
>>> Ok. I try to explain my idea better. With magritte you have to spell >>> out the error messages before you know anything about the locale of >>> the user who is going to see the messages. >> >> Nope. The locale is set before the Magritte code even kicks in. > > Yes, there is some locale at the time magritte reads the meta-data and > creates the component, but this locale might not be the locale user wants > to use in user interface. User might change the locale/language for > the session but this does not affect the magritte > code because the error messages are created with different locale. > And I think that is a problem. > > Or is there something I don't understand? I see what you mean. The other question is of course whether Magritte would work with a LazyTranslation where a String is expected. Sure you can try to be clever and subclass String or ProtoObject but that will probably break at some point. Maybe a better way would be a method like #markForLaterTranslation that would answer the receiver but also export it into the .po file? Cheers Philippe _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
2010/9/12 Philippe Marschall <[hidden email]>:
> I see what you mean. The other question is of course whether Magritte > would work with a LazyTranslation where a String is expected. It only passes the strings along. It does not do any operations to them. At least I haven't bumbed in to a case where it would alter the string. But of course this behaviour might change but then translating the text would also be a problem. Could you think something that might get broken in the future? I think the approach is vulnerable to calls that alter and copy the string, but in many cases it would brake the current translation system also. > Maybe a better way would be a method > like #markForLaterTranslation that would answer the receiver but also > export it into the .po file? It is other possibility and I thought it also. I see couple of problems. If markForLaterTranslation does not mark the object in any way it would be hard to determine in which cases text should be translated. This can create situation where text gets no translation or gets translated twice or more. It requires quite many changes to code. User interface code has to be changed to take care translations. And when translation logic is changed the user interface code has to be changed too. For example when arguments are added to translations #translate: -method of seaside has to be changed too. I think this will divide the logic to several places. -- Panu _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
Free forum by Nabble | Edit this page |