I am passing a variable logo which contains the file name of an image file from my controller to the GSP and then I try to display the image like this:
<img src="${resource(dir:'images',file:"${logo}")}" alt="Logo" border="0" />
Even though the variable logo contains the correct value I get an Unclosed GSP expression error:
java.lang.RuntimeException: Error initializing GroovyPageView
at org.grails.plugin.resource.DevModeSanityFilter.doFilter(DevModeSanityFilter.groovy:26) ~[plugin-classes/:na]
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [na:1.6.0_26]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [na:1.6.0_26]
at java.lang.Thread.run(Thread.java:662) [na:1.6.0_26]
Caused by: org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException: Unclosed GSP expression
... 4 common frames omitted
Replacing ${logo} with the file name works.
What am I doing wrong?
Thanks a lot
Jonas
You are trying to embeed Expresion Language inside Expresion Language.
Replace:
<img src="${resource(dir:'images',file:"${logo}")}" alt="Logo" border="0" />
By
<img src="${resource(dir:'images',file:logo)}" alt="Logo" border="0" />
Inside EL you can refer to variables directly
Ernest is right that you shouldn't use a GString in this case. The actual error is that values aren't correctly quoted.
You could also do
<img src='${resource(dir:"images",file:"${logo}")}' alt="Logo" border="0" />
(notice the single-quotes and double-quotes, they are properly closed)
Related
I work use asp.net mvc5 in my project.
I try to display Image stored in my Shared folder in the project:
<img src="#Url.Content(~/Views/Shared/logo.png)" alt="" />
But I get this error on the fly:
Compiler Error Message: CS1525: Invalid expression term '/'
Any idea why I get the error above?
#Url.Content helper needs string as a parameter so you should write like this:
<img src="#Url.Content("~/Views/Shared/logo.png")" alt="" />
or you can use single brackets
<img src='#Url.Content("~/Views/Shared/logo.png")' alt='' />
I've the following code snippet in my Facelet:
<h:commandLink id="cmdbtn">
<f:ajax event="click" execute="#form"
listener="#{screenShotBean.takeScreenshot}" />
</h:commandLink>
It works fine, but when I outcomment it like this,
<!-- <h:commandLink id="cmdbtn"> -->
<!-- <f:ajax event="click" execute="#form" -->
<!-- listener="#{screenShotBean.takeScreenshot}" /> -->
<!-- </h:commandLink> -->
then it throws the following exception:
javax.el.PropertyNotFoundException: Property 'takeScreenshot' not found on type monstage.test.com.ScreenShotBean
at javax.el.BeanELResolver$BeanProperties.get(BeanELResolver.java:237)
at javax.el.BeanELResolver$BeanProperties.access$400(BeanELResolver.java:214)
at javax.el.BeanELResolver.property(BeanELResolver.java:325)
at javax.el.BeanELResolver.getValue(BeanELResolver.java:85)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at org.apache.el.parser.AstValue.getValue(AstValue.java:169)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189)
at com.sun.faces.facelets.el.ELText$ELTextVariable.toString(ELText.java:217)
at com.sun.faces.facelets.el.ELText$ELTextComposite.toString(ELText.java:157)
at com.sun.faces.facelets.compiler.CommentInstruction.write(CommentInstruction.java:77)
at com.sun.faces.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:82)
at com.sun.faces.facelets.compiler.UILeaf.encodeAll(UILeaf.java:183)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1779)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:424)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
When I change the method expression with parentheses as below,
<!-- <h:commandLink id="cmdbtn"> -->
<!-- <f:ajax event="click" execute="#form" -->
<!-- listener="#{screenShotBean.takeScreenshot()}" /> -->
<!-- </h:commandLink> -->
Then doesn't throw the exception, but it's still invoked.
How is this caused and how can I solve it?
Look closer at the stack trace. Here's the relevant part:
...
org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189)
com.sun.faces.facelets.el.ELText$ELTextVariable.toString(ELText.java:217)
com.sun.faces.facelets.el.ELText$ELTextComposite.toString(ELText.java:157)
com.sun.faces.facelets.compiler.CommentInstruction.write(CommentInstruction.java:77)
...
It's thus evaluating EL in a comment block (recognizable by CommentInstruction). A comment block is considered as template text. Facelets evaluates by default also EL #{} in template text. It's like as if you're writing <p>#{screenShotBean.takeScreenshot}</p> without any JSF tag.
You've several options:
Remove the comment block altogether.
Escape EL expressions in the comment by prefixing it with \ as in
\#{screenShotBean.takeScreenshot}
so that they won't be evaluated.
Wrap the entire comment block in <ui:remove> so that it doesn't appear in the component tree (nor in the generated HTML output).
Disable parsing of all comments by Facelets by adding the following context parameter to web.xml:
<context-param>
<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
Note that no one comment will end up in generated HTML output this way.
In addition to the options BalusC already provided you could also add the attribute rendered="false" to your commandLink.
If you have several components you want to be able to toggle quickly, you might want to consider creating a debug property in a bean or use the project stage:
rendered="#{facesContext.application.projectStage == 'Development'}"
You could also use the context parameter that skips comments in your web.xml.
This is the parĂ¢meter:
javax.faces.FACELETS_SKIP_COMMENTS
I am trying to set the text in a button to either 'Enable' or 'Submit' depending on the value of a action class member(mode). But it is reporting an error which is saying 'equal symbol expected' on the first line. I searched and found that there are questions regarding 'equal symbol expected' error but nothing specific to Struts 2 tags. Neither I could spot any obvious error as missing closing quotes.
It would be nice if anyone can help.
<s:set name="submitButtonLabel" value="<s:if test="mode.equals('enable')">Enable</s:if> <s:else>Submit</s:else>" />
<s:submit value = "%{#submitButtonLabel}" cssClass="btn btn-gray" />
Try this:
<s:submit value="%{mode.equals('enable') ? 'Enable' : 'Submit'}" />
You cannot nest tags like that. Write your <s:if> inside <s:set> tag instead.
<s:set name="submitButtonLabel">
<s:if test="mode.equals('enable')">Enable</s:if>
<s:else>Submit</s:else>
</s:set>
i have a file name that contains spaces: bw3 - Copy_1340627264571.jpg
and i use this name to load the image as follows:
<h:graphicImage value="/#{myBean.imageFolder}/#{image.name}" width="30" height="30" style="border:0;"/>
this is translated to:
<img width="30" height="30" style="border:0;" src="/MyAPP/image/bw3+-+Copy_1340627264571.jpg">
while if i tried to print the name in outputText, it's printed correctly:
<h:outputText value="#{image.name}"/>
this is translated to:
<span id="myForm:viewImagesTable:0:_t68">bw3 - Copy_1340627264571.jpg</span>
any ideas how to fix that ?
This seems to be a bug in <h:graphicImage>. Spaces in request URI should be URL-encoded as %20 using java.net.URI and spaces in request query string should be URL-encoded as + using java.net.URLEncoder. It seems that <h:graphicImage> encodes the entire URI using java.net.URLEncoder.
Better replace them yourself beforehand:
<h:graphicImage value="/#{myBean.imageFolder}/#{image.name.replace(' ', '%20')}" />
Or, much better, don't allow spaces in filenames at all. When it concerns uploaded files, replace them by _ or something before saving.
Note that this has nothing to do with EL as your question tagging suggest.
I'm porting the servlet/jsp Netbeans' Affableben tutorial to JSF Framework, and want to use Facelets for the view.
I already have the JPA entities, the session beans and the managed beans. I'm starting with the View. However, I have not found the equivalent in Facelets to work around this line:
<a href="<c:url value='category?${category.id}'/>">
This is the full loop, both in jsp and facelets:
JSP code:
<c:forEach var="category" items="${categories}">
<div class="categoryBox">
<a href="<c:url value='category?${category.id}'/>">
<span class="categoryLabel"></span>
<span class="categoryLabelText"><fmt:message key='${category.name}'/></span>
<img src="${initParam.categoryImagePath}${category.name}.jpg"
alt="<fmt:message key='${category.name}'/>" class="categoryImage">
</a>
</div>
</c:forEach>
Equivalent Facelets code:
<ui:repeat var="category" value="${categoryController.items}">
<div class="categoryBox">
<h:link outcome="${category.id}"/>
<span class="categoryLabel"></span>
<span class="categoryLabelText">${category.name}</span>
<img src="./resources/img/categories/${category.name}.jpg"
alt="${category.name}" class="categoryImage"/>
</div>
</ui:repeat>
This line is not working in Facelets as expected:
<h:link outcome="${category.id}"/>
What would be a working equivalent in Facelets?
EDIT 1
public String getName() throws UnsupportedEncodingException {
return URLEncoder.encode(name, "UTF-8");
}
Warning message: Unable to find resource img/categories/fruit+%26+veg.jpg
The <h:link> utilizes JSF implicit navigation and requires a real (implicit) navigation outcome value. You need to specify the view ID in the outcome. You need to specify request parameters by <f:param>. You also need to nest the spans and the image in the link as you did in your initial example. Assuming that you have a category.xhtml file in the root, this should do:
<h:link outcome="category">
<f:param name="id" value="#{category.id}" />
<span class="categoryLabel"></span>
<span class="categoryLabelText">#{category.name}</span>
<img src="./resources/img/categories/#{category.name}.jpg"
alt="#{category.name}" class="categoryImage"/>
</h:link>
Unrelated to the concrete question, you should be using <h:graphicImage> instead of <img> as well. This way JSF will ensure that the src is properly set. In your particular case that would be
<h:graphicImage name="img/categories/#{category.name}.jpg"
alt="#{category.name}" class="categoryImage"/>
(note that I replaced ${} by #{}, just to adhere the standard and for the consistency)
You can change from this line:
<a href="<c:url value='category?${category.id}'/>">
to this:
<h:link outcome="category.xhtml?id=#{category.id}" />
<h:link outcome="category">
<f:param name="id" value="#{category.id}" />
</h:link>
<h:outputLink value="category.xhtml?id=#{category.id}" ></h:outputLink>