Hybris: How to pass class as a parameter to cms:component? - java

I've started to learn Hybris and I want to find out how to pass the class as a parameter to a custom CMS Component (for the component's root element).
Let's suppose that in a jsp file named customNavigationComponent.jsp I have this piece of code:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%# taglib prefix="cms" uri="http://hybris.com/tld/cmstags"%>
<c:forEach items="${navigation.entries}" var="navigationLink">
<div class="custom-component-wrapper">
<cms:component component="${navigationLink.item}"/>
</div>
</c:forEach>
And the custom component looks like this:
<a href="${component.url}">
<div>${component.linkText}</div>
</a>
I would like to understand what I need to do to pass the class navigation-link as a parameter, like this:
<cms:component component="${navigationLink.item}" class="navigation-link"/>
so that the rendered result will be similar to:
<a href="stackoverflow.com" class="navigation-link">
<div>Lorem Ipsum</div>
</a>

There is no attribute called, class in cms:component and therefore the following statement will not work:
<cms:component component="${navigationLink.item}" class="navigation-link"/>
Please check https://help.sap.com/doc/a4265d5ea8314eb2929e6cf6fb8e35a5/1811/en-US/de/hybris/platform/cms2lib/cmstags/CMSComponentTag.html
In order to understand it better, you can compare it with c:forEach. At https://docs.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/c/forEach.html, you will find a list of attributes available with c:forEach and if you want to dig deeper, you can further check https://tomcat.apache.org/taglibs/standard/apidocs/javax/servlet/jsp/jstl/core/LoopTagSupport.html
If you want to use your statement, you will need to create a custom tag.

Related

Custom tag that evaluates its body based on the variables of the tag

Ok, now this is something for the hard core JSTL wizards I guess ;-)
I would like to have a tag whose body does not substitute the variables of the surrounding page. It should only take the variables into account that have been specified in the body of the tag or in the tag itself like this:
<c:set var="outsideVar" value="outside value"/>
<a:component>
<%# taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<div data-component-id="9">
<c:set var="componentId" value="9"/>
<c:set var="path" value='${abc:getCurrentPath()}_${componentId}'/>
<c:set var="resource" value='${abc:getResourceFromPath(path)}'/>
<c:set var="val" value="${resource.getValue('paragraphValue')"/>
<p>${fn:escapeXml(val)}</p>
${outsideVar}
</div>
</a:component>
The outsideVar variable should not be set and the body of the tag should behave like the content of a <jsp:include/>
This is a more specific question of this one:
Is it possible to create a local page scope in a JSP?
The link also explains the background of this question.
Your custom tag can grab and remove all page attributes before evaluating the body, and then clear and restore afterwards.

set Attribute via href

I am trying to set a variable (named as "o") in jsp in the body of tag - how could I do it without scriplets?
I have wrote this piece of code but it is not working:
<a class="overfl" href="myServlet?action=request.setAttribute('o',i)"> ${values[i]} </a>
Try with JSTL Core c:set Tag to set the attribute in any scope.
Sample code:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:set var="salary" scope="request" value="${2000*2}"/>
ServletRequest#setAttribute() method doesn't return any value.
Get the value back in the same way as you are doing here ${values[i]}
or try with JSTL Core c:out Tag to get the value back.
In your case simply pass the action values as query parameter as shown below:
<a class="overfl" href="myServlet?action=${i}"> ${values[i]} </a>
And get the value back at server side using
String action = servletRequest.getParameter("action");
If the varaible is not already defined in your request's attribute so call <%request.setAttribute('o',i); %> then if you want to write it to the jsp output you have to to write <%request.getAttribute('o') %> in the place where you want to add it's value like this :
<%request.setAttribute('o',i); %>
<a class="overfl" href="myServlet?action=<%=request.getAttribute('o') %>"> ${values[i]} </a>

Setting parent jsp variables in child jsp

I have a parent jsp a.jsp which includes another jsp b.jsp. I am calculating some values in b.jsp which needs to be used in parent jsp a.jsp , which will pass this calculated value to another jsp say c.jsp. How can I evaluate value in child jsp and pass it to parent jsp before that page completely loads?
How are you including the "child" jar inside the parent? static or dynamic import?
if you have
<%# include file="myFile.jsp" %>
change it by
<jsp:include file="myFile.jsp" />
then in the parent set a property in the request (not in the session, that would be "dirtier"):
<% request.setAttribute("attrName", myValue) %>
finally, in the "child" jsp:
<% myValue = (MyValueType)request.getAttribute("attrName") %>
If you need to pass an attribute between including and included jsp (and viceversa)you should use the page context, which is the more short context (from lifecycle perspective)
You can set variables in the request in b.jsp, and use them in parent.jsp. But you can only use them in the parent jsp after the <jsp:include> tag. Remember that this is all evaluated on the server side, so when you say "before that page completely loads," you can be guaranteed that the server has evaluated it before the browser has loaded it. If you mean that you want to delay evaluation on the server until some code below it is evaluated, that's not going to be possible. At least not like this.
b.jsp
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:set var="myVar" scope="request" value="Hello"/>
parent.jsp
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<jsp:include page="b.jsp"></jsp:include>
<span>
The value is ${requestScope.myVar}.
</span>
You could you session scope to accomplish this.
(b.jsp)
session.setAttribute("value",value);
(c.jsp)
session.getAttribute("value");
However, I would recommend doing some major restructuring instead. In your example, the value of your data depends on the order of the elements on the page. If you ever need to re-arrange things (for instance, moving the b.jsp include after the c.jsp include), you risk breaking the business logic.
A good pattern for web development is a model-view-controller pattern. The "controller" determines what page should be displayed, the "model" calculates all the data and makes it available, and the "view" does the display and formatting.
I would recommend reviewing this article, which is helpful for understanding why MVC is a valuable approach:
http://www.javaranch.com/journal/200603/Journal200603.jsp#a5
Edit: As other users have mentioned, request scope would be cleaner than session scope. However, I still recommend determining the value first before writing any display content.

Printing an array/collection of javabeans in JSP

Is there a standard way of printing an array/collection elements of javabeans in JSP? All I know is the <jsp:getProperty> tag which can't do this. I know it can be done using custom tags, but it being such an essential requirement should be provided by JSP.
Also, I have read that using setAttribute() method of PageContext, ServletContext etc we can in a Servlet get the bean and work on it, but it's giving me null value.
pageContext.getAttribute("beanPropertyVariable") //set in page scope
application.getAttribute("beanPropertyVariable") //set in application scope
How can I achieve this?
The standard way is using JSTL <c:forEach>.
Assuming that ${beans} represents the collection of javabeans, here's an example:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
...
<c:forEach items="${beans}" var="bean">
${bean.property1}<br/>
${bean.property2}<br/>
${bean.property3}<br/>
</c:forEach>
That's also the simplest way you can get.
See also:
Our JSTL wiki page
Our Javabeans wiki page
you can use JSTL c:foreach tag like below
<c:forEach items="${list}" var="var">
${var}<br/>
</c:forEach>

how to pass parameter to a javascript function using struts taglib?

I have a javascript function updateHiddenField(value) that gets a value as parameter and then sets this value as the value of a hidden field.
I have a JavaBean flight with parameters id and flightNo.
Problem: How can I pass the parameter id of JavaBean flight to the js function updateHiddenField(value) when using <html:link> tag(struts)?
<html:link href="javascript:updateHiddenField(idToPassHere)"><bean:write name="flight" property="flightNo"/></html:link>
Thanks
Umar
You don't seem to be gaining anything by using <html:link> over <a> - so that would be the easiest change:
<a href="javascript:updateHiddenField(<bean:write name="flight" property="id"/>)">
<bean:write name="flight" property="flightNo"/>
</a>
More generally I would suggest you add event listeners to your DOM objects, rather than mixing markup & functionality.
<html:link href="javascript:updateHiddenField(<s:property value="id"/>)"><bean:write name="flight" property="flightNo"/></html:link>
Assuming your taglib import is <% #taglib prefix="s" uri="/struts-tags" %>

Categories