9 Replies Latest reply on Feb 16, 2012 8:46 AM by Daniel Merchán

    Webcenter portal app globalization - howto

    user279104
      Hi,

      I'm looking for a good guide/tutorial on Custom Webcenter portal app globalization. Webcenter dev guide also doesn't seem to be comprehensive about that.

      I found very straightforward video: http://www.youtube.com/watch?v=ha6FzOkVc24 however it refers to some additional files with code snippets I cannot download anywhere.
        • 1. Re: Webcenter portal app globalization - howto
          Yannick Ongena
          You have some issues with globalization that you need to take into consideration. It is easy to translate the labels and so on but the biggest challenge is translating the content and make sure the portal is behaving correctly when you change language.
          Suppose that English is the default language and you swithc to a different language, you not only want to see the labels change, but also the content and this is very tricky. First of all, you need to configure a workflow or some sort in UCM so when you create a new piece of content, it automaticly creates the translation (empty documents) and send out a notification to the content owners saying they need to translate.

          A second thing you need to do is customize the content presenter so it takes the language as a parameter in a query so you will always show the content in the specific language.

          it is not as straight forward as it looks...
          • 2. Re: Webcenter portal app globalization - howto
            user279104
            Hi Yannick,

            I am aware that to properly implement globalization one has to consider it in multiple areas. However, in my case, I only have to worry about navigation, control labels and so on. Content is not an issue. All content in my portal will be served from the external data sources (webservices, jdbc), so my only consideration is how to pass information about selected language while fetching data.

            Multilingual content in UCM is not an issue, I am even not authorized to use UCM in direct/indirect manner within this application at all.

            Thanks for your contribution, but still - do you know any good guide to start from? Dev guide isn't helpful, and your blog (great by the way) doesn't cover this topic yet ;)
            • 3. Re: Webcenter portal app globalization - howto
              Yannick Ongena
              There is not really a good documentation that explains this however there are a few things you can do:
              1) Use resource bundles for everything
              2) for the navigation model, in the title you can't use expression language BUT you can use expression when creating the template of your site so instead of adding a real title in the nav model, specify a key matching the value in the bundle. This way you can use EL in your template that renders the navigation
              3) When you create custom taskflows, use resource bundles.
              4) when you want to change labels in existing webcenter taskflows, customize the resource bundle.

              I think the most difficult thing it translating the navigation model which is also not that difficult because you can control how it renders.
              • 4. Re: Webcenter portal app globalization - howto
                user279104
                Hi,

                Okay, I know I should use resource bundles for everything. I tried to follow video tutorial mentioned earlier (http://www.youtube.com/watch?v=ha6FzOkVc24):

                - added xlff PortalBundle
                - translated some af:outputText labels on page template

                Now when I try to run my portal in JDeveloper I got following exception:

                <LifecycleImpl> <_handleException> ADF_FACES-60098:Faces - cykl życia otrzymuje nieobsługiwane wyjątki w fazie RENDER_RESPONSE 6
                javax.faces.FacesException: javax.servlet.ServletException: java.util.MissingResourceException: Can't find bundle for base name com.mycompany.myproject.portal.PortalBundle, locale en
                     at com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:415)
                     at org.apache.myfaces.trinidad.context.ExternalContextDecorator.dispatch(ExternalContextDecorator.java:44)
                [----- CUT ---------]
                     at weblogic.servlet.internal.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:253)
                     at com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:410)
                     ... 66 more
                Caused by: java.util.MissingResourceException: Can't find bundle for base name com.mycompany.myproject.portal.PortalBundle, locale en
                     at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1427)
                     at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1250)
                [----- CUT ---------]
                     at oracle.jsp.runtimev2.JspServlet.internalService(JspServlet.java:802)
                     at oracle.jsp.runtimev2.JspServlet.service(JspServlet.java:726)
                     ... 116 more
                <PersonalizationFilter> <doFilter> Caught unexpected client exception.
                javax.servlet.ServletException: java.util.MissingResourceException: Can't find bundle for base name com.mycompany.myproject.portal.PortalBundle, locale en
                     at oracle.jsp.runtimev2.JspReportUtil.reportException(JspReportUtil.java:170)
                     at oracle.jsp.runtimev2.JspServlet.service(JspServlet.java:737)
                [----- CUT ---------]
                     at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)
                     at weblogic.work.ExecuteThread.execute(ExecuteThread.java:207)
                     at weblogic.work.ExecuteThread.run(ExecuteThread.java:176)
                Caused by: java.util.MissingResourceException: Can't find bundle for base name com.mycompany.myproject.portal.PortalBundle, locale en
                     at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1427)
                [----- CUT ---------]
                     at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1250)
                     at oracle.jsp.runtimev2.JspServlet.service(JspServlet.java:726)
                     ... 116 more

                where

                ADF_FACES-60098:Faces - cykl życia otrzymuje nieobsługiwane wyjątki w fazie RENDER_RESPONSE 6

                means

                ADF_FACES-60098:Faces - lifecycle recieves unhandled exceptions in phase RENDER_RESPONSE 6


                I tried to duplicate PortalBundle.xlf as PortalBundle_en.xlf, but it doesn't help. What am I doing wrong? Please note that comparing to mentioned tutorial, I don't have phase listener nor ApplicationBean registered.

                But what next - how can I implement language selection control and pass information about selected language to taskflows defined in my ADF library?

                Concerning 2) - I'm not sure what do you mean - why can't I follow instructions from the video on localizing navigation (starting from 7:04) - seem to be pretty straightforward.
                • 5. Re: Webcenter portal app globalization - howto
                  user279104
                  Hi Yannick,

                  I almost managed to overcome most problems. Globalization works for both labels in portal template and in my custom taskflows. Now the last problem is navigation - in default-navigation-model.xml I use ResourceBundle as ValueType in URLAttribute Title. This however, always displays polish localization instead of choosen one. In video tutorial author mentions CustomPhaseListener, which primary job is to invalidate navigation model. My impression is the same - NavigationModel gets cached somewhere, and this cache should be invalidated each time user changes language.

                  I have registered GlobalizationBean as session managed bean. It also serves as value change listener to selectOneChoice component holding language selection. After changing language it triggers page refresh to update all labels on page. Currently I have such method:

                  public void processValueChange(ValueChangeEvent valueChangeEvent) {
                  System.out.println("language changed from "+ valueChangeEvent.getOldValue() + " to " + valueChangeEvent.getNewValue());
                  refreshPage();
                  }

                  According to my understanding, I should add something like:

                  NavigationContext ctx = [...]
                  ctx.getCurrentNavigationModel().invalidateCache();

                  before refreshPage() to invalidate navigation model cache and apply globalization. But how can I obtain NavigationContext instance from the code?

                  P.S. I understand sollution you previously suggested, but I want to try it out as a last resort, and try to do it in a "proper" way first
                  • 6. Re: Webcenter portal app globalization - howto
                    DMP1970
                    Did you ever figure out where to download the files mentioned in the video? If so, I'd love a link.
                    • 7. Re: Webcenter portal app globalization - howto
                      Daniel Merchán
                      I have the sample based on that video.

                      http://danielmerchanoracle.blogspot.com/2011/09/multi-lenguaje-en-una-aplicacion-de.html

                      You can download it from this post.

                      Kind Regards.
                      • 8. Re: Webcenter portal app globalization - howto
                        DMP1970
                        THANK YOU! How did you end up addressing the individual portlets then? Do they get their own resource bundle or do they somehow inherit the translations from the resource bundles in the portal.
                        • 9. Re: Webcenter portal app globalization - howto
                          Daniel Merchán
                          Hi again.

                          Task Flows and Portlets should be independent. All Task Flows / Portlets have their own ResourceBundle.

                          Mix bundles betweeen TaskFlows/Portlets with Portals is a bad practice and more difficult to maintain.
                          You can pass through URL parameter or another way Portal language to your Portlets / TaskFlows.

                          Regards.

                          Daniel.