dev@jsftemplating.java.net

Re: JSFTemplating: Working w/ ResourceBundles

From: Ken Paulsen <Ken.Paulsen_at_Sun.COM>
Date: Tue, 18 Jul 2006 23:57:52 -0700

Yes... I forgot to mention that. JSF does provide an alternate syntax
for this:

    #{resource["jvm.GeneralTitle"]}

I think that's the right syntax. I talked to Anissa earlier about this
same issue... she decided that she'd use the $resource{} syntax instead
which does work correctly for names w/ dots:

    $resource{bundle.jvm.GeneralTitle}

This requires that you init it in the beforeCreate instead of
beforeEncode however (for now).

Ken

Ana Caballero wrote:
> Hi Ken,
>
> This works fine as long as I don't use "." in the key name. For
> example the following will not work" #{resource.jvm.GeneralTitle}" for
> key name "jvm.GeneralTitle" and bundle name "resource".
>
> If I change the key name to "JVMGeneralTitle" and use the following
> #{resource.JVMGeneralTitle} it will work.
>
> If I use the following syntax #{resourceBundleName, resourceKey} I get
> the exception below:
>
> javax.servlet.ServletException: Encountered "," at line 1, column 7.
> Was expecting one of:
> "}" ...
> "." ...
> "[" ...
> ">" ...
> "gt" ...
> "<" ...
> "lt" ...
> ">=" ...
> "ge" ...
> "<=" ...
> "le" ...
> "==" ...
> "eq" ...
> "!=" ...
> "ne" ...
> "&&" ...
> "and" ...
> "||" ...
> "or" ...
> "*" ...
> "+" ...
> "-" ...
> "?" ...
> "/" ...
> "div" ...
> "%" ...
> "mod" ...
> <FUNCTIONSUFFIX> ...
> "(" ...
> javax.faces.webapp.FacesServlet.service(FacesServlet.java:256)
> com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:73)
> com.sun.enterprise.web.VirtualServerPipeline.invoke(VirtualServerPipeline.java:120)
>
> org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:231)
>
> com.sun.enterprise.web.connector.grizzly.ProcessorTask.invokeAdapter(ProcessorTask.java:602)
>
> com.sun.enterprise.web.connector.grizzly.ProcessorTask.processNonBlocked(ProcessorTask.java:542)
>
> com.sun.enterprise.web.connector.grizzly.ProcessorTask.process(ProcessorTask.java:762)
>
> com.sun.enterprise.web.connector.grizzly.ReadTask.executeProcessorTask(ReadTask.java:322)
>
> com.sun.enterprise.web.connector.grizzly.ReadTask.doTask(ReadTask.java:247)
>
> com.sun.enterprise.web.connector.grizzly.ReadTask.doTask(ReadTask.java:201)
>
> com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:252)
>
> com.sun.enterprise.web.connector.grizzly.WorkerThreadImpl.run(WorkerThreadImpl.java:103)
>
>
>
> Ken Paulsen wrote:
>
>>
>> Hi...
>>
>> To reference a ResourceBundle key, this can be done using JSF EL
>> (i.e. #{resourceBundleName, resourceKey}). I also provide a
>> $resouce{resouceBundleName.resourceBundleKey} syntax which does the
>> same thing (actually it provides better error messages, is more
>> explicit, and works more easily w/ key's containing '.' characters --
>> but for now I'll focus on the #{} syntax). The problem is that while
>> you can refer to keys in a RB that already exists, you need to ensure
>> that bundle exists... which until now I didn't provide a way to load
>> the bundle into the request scope.
>>
>> Here's how to load the bundle into the request scope:
>>
>> <!beforeEncode
>> setResourceBundle(key="resource" bundle="full.path.to.Bundle");
>> />
>> ...
>> "Some string which refers to: #{resource.key}
>>
>> You should do this in a beforeEncode as it must happen each request
>> (beforeCreate will only happen on the first request). This event
>> should happen under the 1st element in the page (for now). This is
>> because this type of event doesn't get fired if it is nested deep in
>> the UIComponent tree. If you don't want to do it there, you can wrap
>> it in an "event" component and put it anywhere before you use it:
>>
>> <event>
>> <!beforeEncode
>> setResourceBundle(key="foo" bundle="a.b.c.Resouces")
>> />
>> </event>
>>
>> That's it...
>>
>> If you want to know the alternate syntax, read on.... The
>> $resource{bundle.key} syntax is faster, provides better error
>> detection, better error messages, etc. The down side is that it does
>> not perform "deferred" evaluation. This means that it only gets
>> evaluated 1 time if you set it on a UIComponent property. It also
>> means that you will likely need to use a "beforeCreate" instead of
>> "beforeEncode" (depending on where you're using the expression). The
>> setResourceBundle{} command is the same.
>>
>> I'll be looking at ways to improve this area, I may provide a new
>> event type which executes in the "beforeCreate" time-frame but
>> executes every request... this would be more appropriate for this
>> initialization-type code and would make the 2 syntaxes more
>> interchangeable.
>>
>> Let me know if you have problems...
>>
>> Ken
>