View.jsp not showing with portlet-class set - liferay

I am able to make a new portlet, but when I change the class view.jsp no longer renders. No errors in my log.
How do I make a custom MVCPortlet display the standard view.jsp in liferay?

Have you modified the portlet-class in portlet.xml appropriately? If so, you need to call super.render(renderRequest, renderResponse); in your class's render method.

Related

how to create dynamic items in liferay theme as per the values in the portlet

I have a theme in liferay where there are some items in the side menu, I want to add some more items to the menu dynamically based on the values i obtained in the portlet's controller.
My theme is like this :
<div id="menu">
<ul class="link" style="height: 609px;">
<li>My Account<i class="pull-right" ></i></li>
<li>Settings<i class="pull-right" ></i></li>
</ul>
</div>
I have a portlet from where I gets some values in a list
List<String> list= new ArrayList<String>();
list.add("test1");
renderRequest.setAttribute("list", list);
The list could have different values.
What I want is if I have a parameter called test1 in the list , I want to add a new parameter in the theme to be available for that particular user.
<li>Bonus<i class="pull-right" ></i></li>
If it was JSP, I would have used the but how can it be done in the liferay theme.(I am using velocity theme).
There's quite some discussion on this already in the comments to your question. Your theme can't access "your portlet's controller", it's the wrong way to think about the problem: If a portlet determines what to show, you should embed the portlet in the theme. After all, you probably want to interact with it, and that's the easiest way to do so.
Even if a portlet is present on a page, a theme can't arbitrarily use any portlet's request attributes - they're well shielded from accessing each other by design: Otherwise you'd have all kinds of conflicts between rogue portlets and themes.
And as long as you can't guarantee that a portlet is on the page, you can't just call arbitrary methods on the portlet anyways. (not that you could otherwise).
If you want to go through with implementing this functionality in a theme, say goodbye to "the portlet controller". You should have your code in an independent utility class, as a portlet in this case is just the wrong place for the implementation.
I'm not fully understanding your complete usecase, so I can't tell you which implementation makes most sense. Only that the combination you outline in your question makes the least sense to me.
As per Olaf's reply,you should probably proceed with a better approach to this design.You can however use attributes from Servlet context in theme.
In your portlet class:
HttpServletRequest request=PortalUtil.getHttpServletRequest(req);
ServletContext servletContext=request.getSession().getServletContext();
servletContext.setAttribute("param", "Product3");
which can then be retrieved in theme via request variable available in theme velocity template:
$request.getSession().getServletContext().getAttribute("param")

How to create a RenderURL during action phase in a portlet?

In the method processAction(ActionRequest request, ActionResponse response), I insert a record into database and get the ID and then
I want to redirect to the view page of this record. So I need to create a RenderURL with a parameter value for that ID.
ActionResponse doesn't provide method to create a renderURL. Some codes in Liferay do similar things like:
create renderURL before accessing the actionURL
pass the renderURL as a parameter in the actionURL
However, at that time, I don't know the value of ID.
Other codes also use new PortletURLImpl() directly. My portlet cannot see that class.
Other codes also use new PortletURLImpl() directly. My portlet cannot see that class.
Because this class is in portal-impl.jar and also it is not recommended to use classes from this jar. Starting from Liferay 6.1, you won't be able to build your portlet from plugins-sdk if you classes point to portal-impl.jar.
Now to answer your question:
Any jsp is rendered by the render method or doView method (if using liferay's MVCPortlet) and this method would be called as part of the normal life-cycle of portlets.
Here are the steps you would need to take:
set a render parameter (using response.setRenderParameter() method) in your `processAction' method at the last which would be available in your render method, as follows:
actionResponse.setRenderParameter("myID", 1201);
Just for info: After using setRenderParameter you cannot use sendRedirect method
fetch this "myID" in your render method as you fetch any other request parameter:
//assuming your ID is a long
long myUserName = ParamUtil.getLong(renderRequest, "myID");
or
String strMyID = renderRequest.getParameter("myID");
long myID = Long.parseLong(strMyID);
After this, just use
include(renderPage, renderRequest, renderResponse);
were renderPage is nothing but a string containing the path to your jsp within docroot like /html/yourportlet/view.jsp
Just as an afterthought:
If you are using a Liferay IDE, then you can try creating a simple portlet project with MVCPortlet and then look at the generated portlet.xml's <init-param>
So basically you need to pass information from action-phase to render-phase, the development guide is a good place for explaining this in detail.
That's it.
Hope this helps.
Let me know if you have any confusion regarding this.
In action phase do the following:
ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute (WebKeys.THEME_DISPLAY);
PortletURL url = PortletURLFactoryUtil.create(request, this.getPortletName(), themeDisplay.getPlid(), PortletRequest.RENDER_PHASE);
For example, if you want to redirect to the login page and back, you can do the following:
response.sendRedirect("/c/portal/login?redirect=" + HttpUtil.encodeURL(url.toString()));
Definitely you can add or copy the parameters as required.
Instead of creating the renderURL you can include the view page include(viewTemplate,actionRequest,actionResponse). Or if you want to sent any parameter any want's to get it in doView then use actionResponse.setParameter(name,value) method
I create a RenderURL with a place holder as parameter value, like this:
<portlet:renderURL var="redirect">
<portlet:param name="ID" value="__ID__" />
</portlet:renderURL>`
In processAction:
String redirect = redirectParam.replace("__ID__", "123213");
actionResponse.sendRedirect(redirect) ;

What is the difference between doView() and render() functions in Liferay?

What is the actual difference between doView() and render() functions in Liferay? and also what is the difference between renderRequest and resourceRequest?
doView() = to handle render requests when in VIEW mode.
render() = This method invokes the doDispath() method and sets the title of the portlet by using getTitle() method. Then it invokes one of doView(), doEdit(), doHelp(), etc. depending of the portlet mode specified in the RenderRequest.
Again, RenderRequest is when you want to handle requests in the VIEW mode of the portlet. If your portlet uses additional resources to render the view (i.e. images, JavaScript files, etc.) then the JSP that renders the view will use <portlet:resourceURL /> tags to generate valid URLs to those resources. Those URLs will be processed with a pair of ResourceRequest and ResourceResponse objects.
You can override the resource phase though but bear in mind that when you use ResourceRequest/ResourceResponse to serve, the portlet can't change the current portlet mode, window state or render parameters. And also the parameters set on the resource urls are not the render parameters and they are valid to serve only that current resource request.

Want to create a custom component that mirror existing component functionalities, but using different renderer

The JSF component SelectOneRadio layout is very limited so I wrote a custom Renderer for it, and it works great. However, there are times when I want to use the standard SelectOneRadio layout as well. So I decide to make my new component that utilize the custom Renderer I create, but I want this new component to mirror the functionality of SelectOneRadio, and the only different is that it will use my Renderer. Do I need to create both custom tag and custom component to go with my custom renderer in this case? What class should I extends to obtain all functionalities from SelectOneRadio? I would greatly appreciated if you can provided some codes.
EDIT
#BalusC: I like your idea about detecting the value of layout to delegate the correct renderer. So if I have layout="div_layout", then it works great, but if it is pageDirection or lineDirection and nothing show up. What I did is: I create a class that extends MenuRenderer and I override encodeEnd method, so in there I did this
String layout = (String) component.getAttributes().get("layout");
if(layout != null){
if(layout.equals(PAGE_DIRECTION) || layout.equals(LINE_DIRECTION)){
super.encodeEnd(context, component);
return;
} else if (!layout.equals(DIV_LAYOUT)){
//Throw error message
}
}
//Continue with my own renderer code
EDIT2
Above when I said nothing show up, I was wrong. super.encodeEnd(context, component); did render, but instead of render the radio, it render select option tag. So it seems that I delegate to the wrong renderer. I need to use RadioRenderer instead of MenuRenderer.
If it's specific to your own web application, then you could replace just alone the renderer. Easiest is to extend the implementation specific renderer and then depending on the value of one of the standard attributes (layout is the best choice) either delegate to the implementation specific renderer, or do your own custom rendering job.
I case of Mojarra, you'd like to extend com.sun.faces.renderkit.html_basic.RadioRenderer and then register it as follows
<renderkit>
<renderer>
<component-family>javax.faces.SelectOne</component-family>
<renderer-type>javax.faces.Radio</renderer-type>
<renderer-class>com.example.ExtendedRadioRenderer</renderer-class>
</renderer>
</renderkit>
If you wish to be implementation independent, then you'd need to write the entire renderer implementation yourself.
If you wish to have a custom component for it, then you'd need to write it yourself as well.

Wicket : Can a Panel or Component react on a form submit without any boilerplate code?

I am currently evaluating Wicket and I am trying to figure out how things work.
I have a question regarding form submit and panels (or other components).
Imagine a custom wicket panel which contains a text field, doing as-you-type validation using ajax. This panel is added to a form.
How can the Panel react a form submit (let's say because javascript/ajax is unavailable)?
I am currently only aware of one solution: calling a panel's method inside the Form onSubmit() method. But this seems not like a "reusable" approach here, because I have to add boilerplate code to every form's onSubmit() which contains the panel (and every developer which use the panel must know this).
So here comes my question: Is there any way that a Panel/Component can "detect" a form submit in some way? Or is there any other solution beside this?
Thank you.
Make your panels implement org.apache.wicket.markup.html.form.IFormModelUpdateListener, and the updateModel() method should be called when the containing form is submitted and passes validation.
There's a good example of code using this by one of the wicket authors at the Wicket In Action blog.
Well, you could simply do the following:
Panel{
Form{
onSubmit(){
Panel.this.onSubmit();
}
}
protected void onSubmit(){}
}
...
This means that any panel that extends your panel need only override the onSubmit and the form no matter what it is in html will call that method. That way you can extend the panel and only override one method for each form.
With regard to form components, the framework handles it for you transparently. Forms are aware of any child form components, even if they haven't been added directly to the parent form.
I would have a Form inside that Panel. This way, you can reuse that Panel without requiring an external Form. As Forms can not be nested inside each other in HTML, Wicket will swap the inner Form(s) into 's transparently, but will make sure that each of the inner Forms takes part of the form processing (validation,..).
You can override the OnSubmit() function of the Form in your Panel. Wicket will call it for you.
what do you mean by "react"? I have only started recently with Wicket, but FWIK, form submit updates the model of a component, and then it calls onSubmit(), which you can override to take special actions beyond that. See Wicket in Action, chapter 6.
After that, the page (and it's components) get re-rendered, using the updated model, so basically, they really "react" on a submit, with quite few lines of code.
For your mentioned case with Component in a Form, have a look at the CompoundPropertyModel.
Implementing IFormSubmitListner and IFormModelUpdateListener shall call the respective methods during a form submit.
However, if you want to do some processing after form submit, I'm afraid you have no choice but to write some boilerplate code yourself.

Resources