Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Best Practice: localization internationalization i18n of server-returned strings

    Hi Isomorphic,

    how is server side string i18n best done (e.g. builtin .ds.xml-validator error message)? I could think of two ways:
    • Transfer technical string/stringID from server to client, have lookup to translated string on the clientside
    • Transfer current language with each RPCRequest, return already localized string from the server
    If the way you use is the latter, do you have stub that shows the mechanism (get language, then get translation)?

    Thank you & Best regards
    Blama

    #2
    Hi Blama,
    Did you see the docs here?

    Regards
    Isomorphic Software

    Comment


      #3
      Hi Isomorphic,

      I saw that. Sorry for not being more clear.
      I meant DMI Validation or DSResponse-Errormessages like return new DSResponse().setFailure(myLocalizedMessage);

      So where I return from Java code, but have the incoming DSRequest and HttpServletRequest available.

      Best regards
      Blama

      Comment


        #4
        Use standard Java techniques - the current Locale is accessible from the ServletRequest.

        Comment


          #5
          Hi Isomorphic,

          how can I do the same thing for serverside DMI validation?

          The signature of my DMI validator is:
          Code:
          public boolean condition(Object value, Validator validator, String fieldName, Map<Object, Object> record, DataSource ds)
          I can't get the request's locale here, can I? validator.getLanguage() is completely unrelated.

          I want to to this:
          Code:
          validator.addErrorMessageVariable("errorMessage", myLocalizedErrorMessage);
          Best regards
          Blama

          Comment


            #6
            Hi Isomorphic,

            the last post is just about validator.addErrorMessageVariable("errorMessage", myLocalizedErrorMessage). I found a related thread, which unfortunately does not help.


            The return new DSResponse().setFailure(myLocalizedMessage) is working as expected, thank you.
            For anyone interested:
            Code:
            public class I18n {
                public static String getString(String key, HttpServletRequest httpServletRequest) {
                    /* Use the following line in development, when you want to add strings in a running Tomcat instance without restarting Tomcat */
                    // ResourceBundle.clearCache();
                    ResourceBundle labels = null;
                    // Find the first matching language from the request
                    for (Enumeration<Locale> e = httpServletRequest.getLocales(); e.hasMoreElements();) {
                        Locale currentLocale = e.nextElement();
                        labels = ResourceBundle.getBundle("com.mypackage.server.i18n.I18n", currentLocale);
                        if (labels.getLocale().getLanguage().equals(currentLocale.getLanguage()))
                            break;
                    }
                    return labels.getString(key);
                }
            }
            Plus files I18n_??-utf8.properties and following ant-target:
            Code:
                    <echo>Converting server i18n files (UTF-8 to ASCII)</echo>
                    <exec executable="${java.sdk}/bin/native2ascii.exe">
                        <arg value="-encoding" />
                        <arg value="UTF-8" />
                        <arg value="${basedir}/src/com/mypackage/server/i18n/I18n_de-utf8.properties" />
                        <arg value="${basedir}/src/com/mypackage/server/i18n/I18n_de.properties" />
                    </exec>
                    <exec executable="${java.sdk}/bin/native2ascii.exe">
                        <arg value="-encoding" />
                        <arg value="UTF-8" />
                        <arg value="${basedir}/src/com/mypackage/server/i18n/I18n_en-utf8.properties" />
                        <arg value="${basedir}/src/com/mypackage/server/i18n/I18n_en.properties" />
                    </exec>
            Thank you & Best regards
            Blama
            Last edited by Blama; 10 Dec 2015, 07:17.

            Comment


              #7
              condition() is invoked via DMI. After the first 5 required parameters, any of the optional parameters can be declared, including HttpServletRequest.

              Comment


                #8
                Hi Isomorphic,

                thanks, just the information I needed!

                Best regards
                Blama

                Comment


                  #9
                  Hi Isomorphic,

                  I saw this thread and your link to the docs there:
                  It obtains the user's Locale from the servlet request, but you can override this if you want to force an application-specific locale, regardless of the user's operating system settings. To do this, specify a "locale" parameter on HTTP requests to the DataSourceLoader and IDACall servlets.
                  While I now have a fully browsersetting-localizable application, a requested feature in the future will be to change the locale in the application. I'll then do that with DB-persisting per user and a cookie for the login screen.
                  As I imagine it, this will work for Login, the GWT application and DataSourceLoader-calls. But how do I permanently add a locale-parameter to the clientside RPCManager-requests?
                  This is needed for validator and DSResponse-failure l10n. I had a look at the methods there, but did not find something that looked like the solution.

                  Best regards
                  Blama

                  PS: I think all the information in this thread would be a good addition to the docs: HttpServletRequest for DSResponse-failure messages and the additional HttpServletRequest parameter for DMI validation messages. While this is part of the Quick Start Guide and one could know it, it is not part (and does not need to) of the DMI Validation sample. Same is true for the annoying no-spaces requirement in title-tags.
                  All these would be really valuable in the i18n-docs where everyone will search for it.

                  Comment


                    #10
                    Use RPCManager.setActionURL().

                    It's not clear what you're suggesting should be added to the docs. The docs already suggest adding the locale parameter to force locale. We don't want to recapitulate Java basics like how servletRequest.getLocale() works.

                    Comment


                      #11
                      Hi Isomorphic,

                      thanks for the hint on RPCManager.setActionURL().

                      I meant the following additions to the docs:
                      • An additional HttpServletRequest parameter can be added to the condition() method for DMI-Validation message localization. Perhaps with link to validator.serverObject.
                      • An information on the RPCManager.setActionURL() you just mentioned. For DataSourceLoader it is clear that the parameter goes into the bootstrap-html file. For IDACall it is not immediately clear where to put the parameter.
                      • An information on the no-whitespace requirement for <title><fmt:message...-tags.
                      Best regards
                      Blama

                      Comment


                        #12
                        Ah, so these are requests to interlink the information to make it easier to find, not new sections. We've gone ahead and done this.

                        On the last point, it's not that whitespace is disallowed, it's that it's significant. It can be used to, for example, embed HTML in properties that allow it. We've noted this in the docs.

                        Comment


                          #13
                          Hi Isomorphic,

                          sorry to bother here again. I read your last post and the changed docs, which now include:
                          Code:
                          Note that all whitespace is significant. A declaration like this one:
                              <DataSource  xmlns:fmt="WEB-INF/" ID="i18nTest">
                          ​      <title>
                                    <fmt:message key="dsTitle" />
                                </title>
                                 ...
                            </DataSource>
                          .. will cause linefeed / carriage return characters to be embedded in your title. This can be useful in situations where you want to embed small amounts of HTML in a localized attribute, but most of the time, you will want the <fmt> tag on one line with the surrounding tag (eg "title").
                          It seems we did not understand each other.
                          My problem is not with potential "\r\n"s or spaces in the resulting titles. The problem is that the title-placeholders do not get replaced.
                          My .ds.xml excerpt (note one space after opening title-tag):
                          Code:
                          <field name="MISSINGINFORMATION" length="35" type="text" escapeHTML="true" canSave="false">
                              <title> <fmt:message key="missingData" /></title>
                          </field>
                          DataSourceLoader result:
                          Code:
                          {escapeHTML:true,validators:[],length:35,name:"MISSINGINFORMATION",canSave:false,type:"text",title:" [B]<fmt:message key=\"missingData\" xmlns:fmt=\"lmscompany/fmt\"/>[/B]"}
                          This ultimately results in an empty title, as the browsers interprets the fmt as an unknown (and also empty) html tag.

                          Best regards
                          Blama
                          Last edited by Blama; 26 Feb 2016, 02:02. Reason: Typo

                          Comment


                            #14
                            Dear isomorphic,

                            The technique i18n for translating application tag and datasource name field is clear, but how would you recommend to implement database data translation inside the asynchronous ds call. Let say the datasource maps the following field with specific translation of a tag defined in the database name_en, name_de, name_fr. How could we switch to the right language in the datasource description.
                            I have experimented that the column name definition inside a datasource cannot be defined dynamically neither via a session variable or via a language tag <fmt> or <JSTL Core> in contrast to the column title that works,

                            Have you any thought how to achieve the data translation from database inside a datasource call.
                            Thanks,
                            Itaca

                            Comment


                              #15
                              Hi Itaca,

                              that's a problem I'd like to tackle as well soon, but perhaps something for a new thread (@Isomorphic: Perhaps move #14/#15 to a new thread?)

                              For example:
                              • Temperatures: (id=1, shortName=hot), (2, mid), (3, cld), DataSource T_Temperature
                              • English: Hot, Medium, Cold
                              • German: Heiß, Mittel, Kalt


                              One solution I could think of is using PL/SQL (I'm using oracle) with nativeName="translate('T_Temperature', id, 'de')"

                              Problems here:
                              • How do I get the 'de' (=browser language) there? DynamicDSGenerator?
                              • Even if I cache the translations in a package on the DB, will the SQL / PLSQL context switches kill my performance?


                              Another solution: Use includeFrom="T_TemperatureTranslation.name_de"

                              Problems here:
                              • How do I get the 'de' (=browser language) there? DynamicDSGenerator?
                              • How do I actually translate? View? How do I define the view-columns? Oracle-PIVOT?
                              • Will the joining / pivoting kill my performance?
                              • Will having "TemperatureTranslation" for all my localizable DS be a heck of a maintainance-task?

                              Could you suggest a best practice?

                              Thank you & Best regards
                              Blama

                              Comment

                              Working...