2

I'm trying to dynamically render some composition/templates based on the presence of a query string or the absence of a query string. For example:

localhost:9080/myWonderfulApp/test.xhtml?foo=bar

This works, A.xhtml gets pulled in.

localhost:9080/myWonderfulApp/test.xhtml

This doesn't work, B.xhtml does not get pulled in.

I'm having problems with the absence of a query string part. I can render A.xhtml when I pass ?foo=bar, but I can't seem to get B.xhtml rendered when I have no query string. I've tried some variations, I initially figured #{param['foo'] != 'bar' would work, but I think that's not working because I don't have a foo query param at all. I've tried checking if param == null but that didn't work either.

Is it possible to set my rendered attribute based on NO query string?

I can't just set another query string for B.xhtml, either as I'm working on a legacy app that gets 2 different skins, so retrofitting all the old apps that link in isn't an option. New apps will use a query string, old ones need to get an old skin linking in with no query string.

<!--This works-->
<h:panelGrid rendered="#{param['foo'] == 'bar' ? true : false}">
    <ui:composition template="A.xhtml">...</ui:composition>
</h:panelGrid>

<!--This doesn't work-->
<h:panelGrid rendered="#{param == null ? true : false}">
    <ui:composition template="B.xhtml">...</ui:composition>
</h:panelGrid>

This doesn't seem to work, either:

<h:panelGrid rendered="#{empty facesContext.externalContext.requestParameterMap.foo ? true : false}">
magenta placenta
  • 1,461
  • 7
  • 22
  • 34

1 Answers1

1

You just need the inverse condition: #{param.foo != 'bar'}. Those conditional operators returning booleans are unnecessary, the equation itself returns a boolean already. The #{param} is never null. It returns a Map<String, String> which is just empty (not null!) when it doesn't contain any parameters. The brace notation is only useful when the parameter name contains periods which would otherwise be interpreted as nested properties, but request parameter names shouldn't contain periods anyway.

So, this should do:

<h:panelGrid rendered="#{param.foo == 'bar'}">
    <ui:composition template="A.xhtml">...</ui:composition>
</h:panelGrid>

<h:panelGrid rendered="#{param.foo != 'bar'}">
    <ui:composition template="B.xhtml">...</ui:composition>
</h:panelGrid>

As a different alternative, if you want to use the conditional operators the right way, you can also do

<ui:composition template="#{param.foo == 'bar' ? 'A' : 'B'}.xhtml">...</ui:composition>
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Neither seem to work. In your version, B.xhtml doesn't get loaded when the page is accessed without a query string, A.xhtml is loaded. I can't seem to use EL in my template, either, it causes a stack overflow, crashes my editor (RAD) and it won't relaunch. I have to edit the file in another editor (remove the EL in my template), then RAD will launch. This is in JSF 1.2 as well. – magenta placenta Mar 23 '12 at 16:27
  • I must admit that this is a quite strange way of using ``, but as I don't know your functional requirement and other details and I have myself never used this construct, I just ignored the strange usage. But after all, don't you rather mean to use `` or at least `` which in turn uncludes another composition? – BalusC Mar 23 '12 at 16:30
  • BTW, it does work without rendering a composition - as well as what I was trying yesterday.
    These output true and false and work correctly, but when I try to render the templates, they just don't work. I did try ui:decorate as well, but it gave me duplicate ID errors - it seemed to be pulling in both templates.
    – magenta placenta Mar 23 '12 at 16:32