title: JSF <ui:include /> where src is dynamic and primefaces
body: <p>I am struggling with an issue where I am attempting to dynamically generate pages using JSF 2.1 and Primefaces for a kind of CMS project.  My issue is that I am attempting to dynamically include a page that lives in a database using a custom ResourceResolver (that part works great).  The problem is that I am using a request parameter to determine which page to serve (ie: <a href="http://xxx.xxx.com/context/public/?p=2" rel="nofollow">http://xxx.xxx.com/context/public/?p=2</a>).  This works fine until I want to use any Ajax or more specifically Primefaces (in my case the schedule component where I need to use actionListeners).  I have found that my view is not resolved when the ajax request is made, probably due to the fact that it is request scoped.  Below is a bit of code:</p>
  
  <pre><code>&lt;?xml version='1.0' encoding='UTF-8' ?&gt;
  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui" 
    xmlns:ui="http://java.sun.com/jsf/facelets"&gt;
  &lt;ui:composition template="/WEB-INF/view/public/templates/public-template.xhtml"&gt;
      &lt;ui:define name="body"&gt; 
          &lt;p:outputPanel autoUpdate="false" rendered="#{empty publicBean.site}"&gt;
              &lt;div&gt;No site found!&lt;/div&gt;
          &lt;/p:outputPanel&gt;
  
          &lt;p:outputPanel autoUpdate="false" rendered="#{! empty publicBean.page and empty publicBean.page.pageTemplate}"&gt;
              &lt;div&gt;No valid page template found!&lt;/div&gt;
          &lt;/p:outputPanel&gt;
  
          &lt;ui:include src="#{publicBean.view}" /&gt;
      &lt;/ui:define&gt;
  &lt;/ui:composition&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>The number of views is unknown and are dynamically created so, I can't just do an ugly block of ui:includes and conditionally render then.  </p>
  
  <p>So what I am seeing is that my ajax based forms (using p:commandButton for example) are not working when I am doing this.  I never see the action executed on my beans.  But if I hard code the view that is returned from "#{publicBean.view}" so it always returns the same view, everything works.  So I am assuming during the ajax call publicBean.view is probably returning null or in my case AgoraConstants.CUSTOM_VIEW_NOT_FOUND.  Here is the code in my backing bean:</p>
  
  <pre><code>public String getView()
  {
       // If this below is uncommented, the form with ajax/primefaces works
      //if ( 1 == 1 )
      //{
      //    return "/X-AGORA-VIEW/districtOfficeCalendarTemplate.xhtml";
      //}
      if ( page != null &amp;&amp; page.getPageTemplate() != null )
      {
          return AgoraConstants.CUSTOM_VIEW_PREFIX + page.getPageTemplate().getName() + ".xhtml";
      }
      else if ( site != null &amp;&amp; site.getLandingPage() != null &amp;&amp; site.getLandingPage().getPageTemplate() != null )
      {
          return AgoraConstants.CUSTOM_VIEW_PREFIX + site.getLandingPage().getPageTemplate().getName()+".xhtml";
      }
      return AgoraConstants.CUSTOM_VIEW_NOT_FOUND;
  }
  </code></pre>
  
  <p>So here is my question, how can I keep around the request parameter so that I can get this to work the way I want with ajax and primefaces?  I could throw it in the session, but then if the user opens the site in two tabs with different views, things could get confused and not function correctly.  Basically, how should I keep the request vars around so that I can make sure that getView() returns that same view for ajax requests?  It seems like there should be an easy solution to this problem, but I am not seeing any help would be greatly appreciated.  </p>
  
  <p>** Edit ** </p>
  
  <p>I also tried changing my backing bean to view scoped (from request), but that didn't seem to help (but I don't know why). Below is more of the backing bean code.  I added the init method, which is called when the bean is created with @PostConstruct.</p>
  
  <pre><code>public void init()
  {       
      site = null;
      page = null;
  
      logger.info("Loading public view...");
  
      if (  getFacesContext().getExternalContext().getRequestParameterMap().containsKey(AgoraConstants.PUBLIC_PAGE_REQUEST_VAR) )
      {
          logger.info("Restoring Page...");
          long value = parseLong((String)getFacesContext().getExternalContext().getRequestParameterMap().get(AgoraConstants.PUBLIC_PAGE_REQUEST_VAR));
          if ( value &gt;= 0 )
          {
              logger.info("Attempting to restore: {}", value);    
              try
              {
                  page = pageService.getItem(value);
                  if ( page != null )
                  {
                      if ( ! page.isEnabled() )
                      {
                          page = null;
                      }
                  }
              }
              catch(Exception e)
              {
                  logger.warn("Failed to load site: {}", e.getLocalizedMessage());
              }
          }
      }
  
      if (  page == null &amp;&amp; getFacesContext().getExternalContext().getRequestParameterMap().containsKey(AgoraConstants.PUBLIC_SITE_REQUEST_VAR) )
      {
          logger.info("Restoring Site...");
          long value = parseLong((String)getFacesContext().getExternalContext().getRequestParameterMap().get(AgoraConstants.PUBLIC_SITE_REQUEST_VAR));
          if ( value &gt;= 0 )
          {
              logger.info("Attempting to restore: {}", value);    
              try
              {
                  site = siteService.getItem(value);
              }
              catch(Exception e)
              {
                  logger.warn("Failed to load site: {}", e.getLocalizedMessage());
              }
          }
      }
  
      if ( page != null &amp;&amp; page.getSite() != null)
      {
          site = page.getSite();
      }
  
      if ( site == null )
      {
          site = siteService.getDefaultSite();
      }
  }
  
  public String getView()
  {
  //        if ( 1 == 1 )
  //        {
  //            return "/X-AGORA-VIEW/districtOfficeCalendarTemplate.xhtml";
  //        }
      if ( page != null &amp;&amp; page.getPageTemplate() != null )
      {
          logger.info("a" + AgoraConstants.CUSTOM_VIEW_PREFIX + page.getPageTemplate().getName() + ".xhtml");
          return AgoraConstants.CUSTOM_VIEW_PREFIX + page.getPageTemplate().getName() + ".xhtml";
      }
      else if ( site != null &amp;&amp; site.getLandingPage() != null &amp;&amp; site.getLandingPage().getPageTemplate() != null )
      {
          logger.info("b" + AgoraConstants.CUSTOM_VIEW_PREFIX + site.getLandingPage().getPageTemplate().getName()+".xhtml");
          return AgoraConstants.CUSTOM_VIEW_PREFIX + site.getLandingPage().getPageTemplate().getName()+".xhtml";
      }
      logger.info("c");
      return AgoraConstants.CUSTOM_VIEW_NOT_FOUND;
  } 
  </code></pre>