Handling Multilanguage JSF Application with Rewrite

Splash Forums Rewrite Users Handling Multilanguage JSF Application with Rewrite

This topic contains 28 replies, has 3 voices, and was last updated by  Christian Kaltepoth 3 years, 2 months ago.

Viewing 15 posts - 1 through 15 (of 29 total)
  • Author
    Posts
  • #23906

    naska.om
    Participant

    How can I achieve something like this post in rewrite?

    #23912

    The best approach I’ve seen regarding this is described in this post here:

    http://ocpsoft.org/support/topic/yet-another-i18n-approach/

    I hope this help.

    Christian

    #23929

    I think we should probably spend some time to write up this solution in our docs module. I’ll try to get some time to do this, in the mean time, I’ll create an issue so we don’t forget:

    https://github.com/ocpsoft/rewrite/issues/97

    #23979

    naska.om
    Participant

    Thanks @lincoln and @Christian I used the approach you provided. Now I want to redirect to myDefaultLang/home when end user enters my domain. I use the following rule for it:`
    .addRule()
    .when(Path.matches(“/”))
    .perform(Redirect.temporary(context.getContextPath() + “/{lang}/Home”))
    .where(“lang”).bindsTo(…)
    `
    How do I bind lang parameter to my localeBean.getLang() in rewrite to avoid recieving a null parameter for lang?

    • This reply was modified 3 years, 2 months ago by  naska.om.
    • This reply was modified 3 years, 2 months ago by  naska.om.
    #23982

    Simply bind the parameter to your backing bean like this:

    .where(“lang”).bindsTo(El.property("localeBean.lang"))

    #23983

    naska.om
    Participant

    Second, I use

    
    <h:form>
        <h:selectOneMenu value="#{localeBean.lang}" onchange="submit()">
            <f:selectItem itemValue="en" itemLabel="English" />                                                                                
            <f:selectItem itemValue="ar" itemLabel="العربیە" />
        </h:selectOneMenu>
    </h:form>   
    

    With this code, when I change Language, the language of page changes but lang in the address bar stays the same. For example when I am at myContextPath/en/Home and I change select ar in the selectOneMenu the language of the page changes to arabic but in the address bar I still have myContextPath/en/Home. Why is this so?

    #23985

    naska.om
    Participant

    Thanks @Christian and third issue is thatmy primefaces components don’t work after this rewrite change. Do you have any idea?

    #23991

    naska.om
    Participant

    And I don’t know why langis always null.

    #23995

    Could you post your complete Rewrite configuration and the code of your LocaleBean?

    #24012

    naska.om
    Participant

    Sure:
    My LocaleBean.java:

    @ManagedBean
    @RequestScoped
    public class LocaleBean{          
        private String lang;
        
        public Locale getLocale(){
            Locale locale;
            FacesContext context = FacesContext.getCurrentInstance();
            if (lang != null){
                locale = new Locale(lang);
                context.getViewRoot().setLocale(locale);            
            }else{
                if(context == null){
                    locale = context.getApplication().getDefaultLocale();
                }else{
                    locale = context.getViewRoot().getLocale();
                    if(locale == null){
                        locale = context.getApplication().getDefaultLocale();
                    }
                }
            }    
            return locale;
        }
    
        public String getLang() {
            return lang;
        }
    
        public void setLang(String lang) {
            this.lang = lang;
        }            
    }

    My Rewrite Configuration Class:

    @Inject
        private LocaleBean localeBean;
        
        private static Map<String, Properties> langToViews = new HashMap<String, Properties>();
        private static Map<String, Properties> langToPaths = new HashMap<String, Properties>();
        
        private String getView(String lang, String path){
            Properties viewMap = getViewMap(lang);
            String view = viewMap.getProperty(path);
            return String.format("/%s.xhtml", view);
        }
        private Properties getViewMap(String lang){
            Properties props = langToViews.get(lang);
            if(props == null){
                props = new Properties();
                try{
                    props.load(getClass().getResourceAsStream(String.format("text_%s.properties",lang)));
                    langToViews.put(lang, props);
                } catch(IOException e){
                    throw new RuntimeException(e);
                }
            }
            return props;
        }
        private String getPath(String lang, String view){
            Properties pathMap = getPathMap(lang);
            String path = pathMap.getProperty(view);
            return String.format("/%s/%s",lang, path);
        }
        private Properties getPathMap(String lang){
            Properties props = langToPaths.get(lang);
            if(props == null){
                props = new Properties();
                try{
                    props.load(getClass().getResourceAsStream(String.format("text_%s.properties",lang)));
                    langToPaths.put(lang, props);
                }catch (IOException e){
                    throw new RuntimeException(e);
                }
            }
            return props;
        }
    
       @Override
       public Configuration getConfiguration(final ServletContext context)
       {
           
         return ConfigurationBuilder.begin()
                 
                 .addRule()
                 .when(Direction.isInbound().and(Path.matches("/{lang}/{path}")))
                 .perform(new HttpOperation(){
                     @Override
                     public void performHttp(HttpServletRewrite event, EvaluationContext context){                     
                         String lang = (String) Evaluation.property("lang").retrieve(event, context);
                         String path = (String) Evaluation.property("path").retrieve(event, context);
                         String view = getView(lang, path);
                         localeBean.setLang(lang);
                         Forward.to(view).perform(event, context);                
                     }
                 })
                 .addRule()
                 .when(Direction.isOutbound().and(Path.matches("/{view}.xhtml")))
                 .perform(new HttpOperation(){
                     @Override
                     public void performHttp(HttpServletRewrite event, EvaluationContext context){
                         String lang = localeBean.getLocale().getLanguage();
                         String view = (String) Evaluation.property("view").retrieve(event, context);
                         String path = getPath(lang, view);
                         Substitute.with(path).perform(event, context);
                     }
                 })
                 //Redirect to Home
                .addRule()             
                .when(Path.matches("/"))
                .perform(Redirect.temporary(context.getContextPath() + "/{lang}/Home"))
                 .where("lang").bindsTo(El.property(localeBean.getLang()));                                         
       }    
       @Override
       public int priority()
       {
         return 10;
       }

    Lnaguage Selection Part of My Home.xhtml:

    <h:form>
             <h:selectOneMenu value="#{localeBean.lang}" onchange="submit()">
                 <f:selectItem itemValue="en" itemLabel="English" />                                                                                                            
                 <f:selectItem itemValue="ar" itemLabel="العربیە" />
             </h:selectOneMenu>
         </h:form> 

    text.properties:

    Home=Home
        Forum=Forum
        About=About
        Contact=Contact
        Login=Login

    text_en.properties:

    Home=Home
        Forum=Forum
        About=About
        Contact=Contact
        Login=Login

    text_ar.properties:

    Home=البیت
        Forum=منتدی
        About=معلومات عنا
        Contact=اتصل بنا
        Login=تسجیل الدخول
    • This reply was modified 3 years, 2 months ago by  naska.om.
    • This reply was modified 3 years, 2 months ago by  naska.om.
    • This reply was modified 3 years, 2 months ago by  naska.om.
    • This reply was modified 3 years, 2 months ago by  naska.om.
    #24017

    My guess is that your PrimeFaces components don’t work any more because some of the PrimeFaces resources match your inbound pattern and are therefore rewritten by your rule. A resource like /javax.faces.resources/jquery.js would for example match /{lang}/{path}. So you should restrict the lang parameter somehow. Something like:

    
    .addRule()
    .when(Direction.isInbound().and(Path.matches("/{lang}/{path}")))
    .perform(....)
    .where("lang").matches("[a-z]{2}")
    

    Or:

    
    .where("lang").matches("en|ar")
    
    #24018

    And BTW: Your initial redirect from / to /.../Home won’t work, because the lang property will be null, as it is never initialized anywhere in your code.

    #24019

    naska.om
    Participant

    You’re right @Christian, I have experienced the problem of prime faces another time when I imported a jQery library which was the same version of primefaces jQuery library.

    Where can I initialize my lang property? And Why doesn’t the url change as I change the selected language?

    #24020

    You could initialize the property directly:

    
    @ManagedBean
    @RequestScoped
    public class LocaleBean{          
    
        private String lang = "en";
    
        // getters / setters
    
    }
    

    This way the property will have a default value which will change if Rewrite or any other component calls the setter.

    To change the URL in the address bar, you will have to redirect the user to a new URL. So you should execute an JSF action method and perform a redirect there.

    #24021

    naska.om
    Participant

    After initializing lang, now I get another error:

    org.ocpsoft.rewrite.exception.RewriteException: El provider [org.ocpsoft.rewrite.cdi.CdiExpressionLanguageProvider] could not extract value from property [en]
    javax.el.PropertyNotFoundException: ELResolver cannot handle a null base Object with identifier 'en'
Viewing 15 posts - 1 through 15 (of 29 total)

You must be logged in to reply to this topic.

Comments are closed.