Add a conf menu to my portlet - liferay

I'm trying to add a tab in the conf of my custom portlet, beside the natives import/export and permissions.
Like in this image : http://imageshack.us/photo/my-images/716/sampledn.png/
This tab had to allow, to change the value of a parameter in a conf.properties which define some variable.
How can I do that?
Regards.

Yup you can do it by first of all adding this to your portlet.xml as a child of the "portlet" node:
<init-param>
<name>config-jsp</name>
<value>/html/config.jsp</value>
</init-param>
The in your liferay-portlet.xml you need to add this as a child of the "portlet" node:
<configuration-action-class>com.yourportlet.action.ConfigurationActionImpl</configuration-action-class>
Then you need to create this files in the directories you've specified in your XML, and your ConfigurationActionImpl should implement the ConfigurationAction interface so the skeleton would look like this:
public class ConfigurationActionImpl implements ConfigurationAction {
#Override
public String render(PortletConfig config, RenderRequest renderRequest, RenderResponse renderResponse) throws Exception {
return "/html/config.jsp";
}
Let me know if this helps or you have any other questions! :)

Add edit mode to your portlet.xml:
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
<portlet-mode>edit</portlet-mode> <!-- add this line -->
</supports>
Then you will see preferences option in the menu. Override doEdit method in your portlet class to render content of the edit mode.
EDIT:
More advanced solution:
You can add another tab by changing portal jsp via hook. The jsp you need to change is:
/html/portlet/portlet_configuration/tabs1.jsp
Note that this will change configuration window for ALL portlets.

Related

Add a item / page in the portlet admin menu in Liferay

I want to add an other item in the admin menu in a portlet.
For example, add an item "Organization" between Apparence and Configuration.
Is it possible ??
However, i tested a new configuration page in the Configuration menu.
So i add in portlet.xml :
<init-param>
<name>config-jsp</name>
<value>/html/foo/configuration.jsp</value>
</init-param>
in liferay-portlet.xml :
<configuration-action-class>com.projecto.ec.config.ConfigurationActionFooImpl</configuration-action-class>
and my ConfigurationActionPrenalyticImpl looks like this :
public class ConfigurationActionPrenalyticImpl implements ConfigurationAction {
#Override
public void processAction(PortletConfig portletConfig, ActionRequest actionRequest, ActionResponse actionResponse) throws Exception {
// TODO Auto-generated method stub
}
#Override
public String render(PortletConfig portletConfig, RenderRequest renderRequest, RenderResponse renderResponse) throws Exception {
return "/html/preanalytic/configuration.jsp";
}
}
But i don't know how to init correctly this page with some content like in a doView or doEdit.
I'd say it is possible, but is none of the standard extension paths that you typically would go within Liferay. A standard way would be to either implement the JSR-286 "edit" mode or contribute another configuration page to the Liferay-specific configuration.
I've never seen the extension you're intending to do in the wild, and I'm assuming that it would require some poking in the internals. It's most likely not well documented. Given that 6.x is the last release that does not use OSGi (and everything will change with Liferay 7 / DXP), I'm not sure if I should recommend going this way.

Overriding editor template in theme affects admin view

I created a form using the CustomForms module and need to control the markup of the input fields I've included on the form (to add bootstrap specific classes). I added a view to my theme at the location /Views/EditorTemplates/Fields/Input.Edit.cshtml and that allowed me to update the markup for the input fields.
My problem is that the view in my theme is also being picked up in the admin views. I didn't expect this behavior but it's happening. I tried scoping the view override to the url (Input.Edit-url-contact.cshtml) and content type (Input.Edit-ContactRequest.cshtml) using the alternate naming conventions but they do not appear to work in this case.
Is there a way to scope the Input.Edit.cshtml view in my theme so it only applies to the front-end of the site? Or is there a better way to achieve what I'm trying to do?
I ended up working around this issue by implementing a shape table provider (based on Bertrand's suggestion) to specify different template names in my theme so they weren't picked up in the admin. Here's what it looks like:
public class EditorFieldShapeProvider : IShapeTableProvider
{
public void Discover(ShapeTableBuilder builder)
{
builder.Describe("EditorTemplate")
.OnDisplaying(displaying =>
{
var shape = displaying.Shape;
if (shape.ContentField is InputField) {
shape.TemplateName = "CustomInputField";
}
});
}
}
Just drop that class somewhere in your theme and create your view at /ThemeName/Views/EditorTemplates/CustomInputField.cshtml

View.jsp not showing with portlet-class set

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.

What is the difference between super.doView(...) and include(...) on doView override?

I am developing a custom portlet (EDIT:I'm extending MVCPortlet), and looking at several examples and tutorials, I find that when the doView(RenderRequest, RenderResponse) method is overridden, at the end of it there is always at least this line:
super.doView(renderRequest, renderResponse);
or this:
include(viewJSP, renderRequest, renderResponse);
If I don't put either of these my portlet doesn't render anything, but any of them does the trick.
I would like to know which one I should be using, and why do I need to add them to get my portlet to work.
Thanks!
So you must be extending MVCPortlet class. Both the calls are used to include the JSP after the doView processing is completed. If you look at the source code of this class then you would understand what the flow is, below is my explanation:
super.doView(renderRequest, renderResponse);
This includes the default JSP i.e. view.jsp, that you might (or not) have configured in portlet.xml something like this:
<init-param>
<name>view-template</name>
<value>/html/view.jsp</value>
</init-param>
This super class method does nothing but calls the include(viewJSP, renderRequest, renderResponse); method at the end.
include(viewJSP, renderRequest, renderResponse);
This method includes whatever JSP path you have specified for the parameter viewJSP. So with this call you can specify including different JSP for different condition something like the following:
if (isThisTrue) {
include("/html/myCustomPortlet/view.jsp", renderRequest, renderResponse);
} else if (isThisTrueThen) {
include("/html/myCustomPortlet/first/another_view.jsp", renderRequest, renderResponse);
} else {
super.doView(renderRequest, renderResponse);
}
So depending on your requirement you can use any to the two or the mix of the two as shown above. Hope this helps.
The include lets you specify a different JSP to use instead of the default view. So if you are not using a custom view page either will work.

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.

Resources