liferayliferay-7

Is it possible to load a Liferay portlet dynamically on a page from a .jsp file?


I have a portlet that is deployed on a page and I need to produce a link that will load a different portlet (which is in a different module) in full-screen mode. I can load the built in Login portlet this way without a problem, but when I try to load any of my custom portlets I get two red error boxes with the message "You do not have the roles required to access this portlet." And I have the permissions - I can access the portlet fine when added to a page - and I'm even testing with an omni-admin account.

The portlet ID that has the .jsp file is 'subscriptionmanagement_WAR_subscriptionmanagementportlet' and the portlet ID I'm trying to load is 'GRPSignupForm_WAR_NY511RMportlet'. The tag is:

<liferay-portlet:renderURL portletName="GRPSignupForm_WAR_NY511RMportlet" var="grpPortlet" windowState="<%= WindowState.MAXIMIZED.toString() %>">
</liferay-portlet:renderURL>

Which produces the URL: http://localhost:8080/group/test/unsubscribe?p_p_id=tripitinerary_WAR_NY511RMportlet&p_p_lifecycle=0&p_p_state=maximized&p_p_mode=view

However, as I've mentioned, I have been able to load other portlets in this way. The login portlet for example using the same tag works fine:

<liferay-portlet:renderURL portletName="<%= PortletKeys.LOGIN %>" var="loginURL" windowState="<%= WindowState.MAXIMIZED.toString() %>">
    <portlet:param name="mvcRenderCommandName" value="/login/login" />
</liferay-portlet:renderURL>

The obvious difference is that it is passing a specific render command parameter, but otherwise it is the same. It produces the URL: http://localhost:8080/group/test-1/unsubscribe?p_p_id=com_liferay_login_web_portlet_LoginPortlet&p_p_lifecycle=0&p_p_state=maximized&p_p_mode=view&_com_liferay_login_web_portlet_LoginPortlet_mvcRenderCommandName=%2Flogin%2Flogin

For completeness, here is the code for the portlet I'm trying to load. But as I mentioned above, I have tried to load various portlets in this project and all of them produce the permissions error.

@Component(
        immediate = true,
        property = {
            "com.liferay.portlet.display-category=root//NYSDOT//GRP",
            "com.liferay.portlet.instanceable=false",
            "com.liferay.portlet.header-portlet-css=/css/main.css",
            "com.liferay.portlet.footer-portlet-javascript=/js/main.js",
            "com.liferay.portlet.css-class-wrapper=grh-signup-form-portlet",
            "javax.portlet.display-name=GRP Signup Form",
            "javax.portlet.init-param.template-path=/html/",            
            "javax.portlet.init-param.add-process-action-success-action=false",
            "javax.portlet.init-param.config-template=/html/configuration.jsp",
            "javax.portlet.init-param.view-template=/html/view.jsp",
            "javax.portlet.init-param.edit-template=/html/edit.jsp",
            "javax.portlet.name=" + GRPSignupPortletKeys.GRPSIGNUP,
            "javax.portlet.resource-bundle=content.Language",
            "javax.portlet.security-role-ref=administrator,guest,power-user,user"
        },
        service = Portlet.class
    )
public class GRPSignupPortlet extends GenericPortlet {
    ...
    ...
}

So it's obviously possible, as the Login portlet works. I'm sure there is just some small bit of config I'm missing. I've tried to see what is different in the Liferay Login portlet that allows it to work, but haven't found the secret.

Liferay CE 7.3


Solution

  • You need to add the property 'add-default-resource'. In the component add:

    "com.liferay.portlet.add-default-resource=true"
    

    From portal.properties: "add-default-resource" set to true will allow those portlets to be dynamically added to any page by any user. This is useful (and necessary) for some portlets that need to be dynamically added to a page, but it can also pose a security risk because it also allows any user to do it.

    It's prudent to also add

    "com.liferay.portlet.add-default-resource-check-enabled=true",
    

    From portal.properties: Set this property to true to add a security check around this behavior. If set to true, then portlets can only be dynamically added to a page if it contains a proper security token. This security token is automatically passed when using a portlet URL from one portlet to another portlet.