Posts

Showing posts from November, 2019

Custom OSGi settings in Liferay 7.2

Image
Custom OSGi settings implementation Overview This tutorial show how to implement configurable OSGi settings for your project. OSGi module implementation Problem formulation Let's say, you need an account configuration for external system access with values: "LifeDev User" - user name; "LifeDev Password" - password. And you need it to be displayed under custom category in System Settings. Module Creation Create module with the following structure: LifeDevConfigurationCategory  - settings category; LifeDevAccountConfiguration  - OSGi settings; LifeDevConfigurationKeys  - constants; Language.properties  - resource bundle. Dependencies The list of dependencies in  build.gradle : dependencies { compileOnly group: "biz.aQute.bnd", name: "biz.aQute.bndlib", version: "3.1.0" compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel", version: "4.0.0"

Resolving "internal" dependencies

Image
Resolving "internal" dependencies in your OSGi modules Overview Sometimes you may need to reference some class from "internal" package of Liferay's OSGi bundle. But classes under "internal" package are not exposed by Liferay bundles, and thus, can't be used by default. You can include dependency on that module, for example: compileOnly group: "com.liferay", name: "com.liferay.asset.publisher.web", version: "3.0.43" and you'll be able to compile/assemble/deploy your OSGi JAR, but you'll get a runtime error during deployment, like: org.osgi.framework.BundleException: Could not resolve module: com.lifedev.asset.publisher.portlet.filter [1105]_ Unresolved requirement: Import-Package: com.liferay.asset.publisher.web.internal.util _ [Sanitized] at org.eclipse.osgi.container.Module.start(Module.java:444) at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:428) saying that pa

JSP Override with OSGi Fragments

JSP Override with OSGi Fragments Note : article is obsolete, check new version here . Overview This article describes how to create custom JSP Override module (AKA JSP Hook in previous Liferay versions). Note: Although this way is not recommended way by Liferay (see:  https://portal.liferay.dev/docs/7-2/customization/-/knowledge_base/c/jsp-overrides-using-osgi-fragments ), it seems to be the most straightforward and powerfult approach. JSP-Override module creation 1 - Finding the required JSP in Liferay sources. Let's say, for example, you need to customize Asset Publisher configuration and add additional option for Content Set Provider configuration: max items count to display. Find the appropriate JSP file in Liferay sources: for Liferay 7.2 CE GA 1 this is: liferay-ce-portal-src-7.2.0-ga1-20190531153709761.zip!/liferay-ce-portal-src-7.2.0-ga1/modules/apps/asset/asset-publisher-web/src/main/resources/META-INF/resources/configuration/asset_list_provider.jsp 2

Portlet Filter in Liferay 7.2

Liferay 7.2 - Portlet Filter Sample Overview This article describes how to create custom portlet filter in Liferay 7.2. Note: Portet Filters are similar to  Servlet Filters , but they are invoked in scope of portlet and, thus, use  javax.portlet.PortletRequest  /  javax.portlet.PortletResponse  (instead of  javax.servlet.ServletRequest  /  javax.servlet.ServletResponse ). Why do you need it? Portlet filter may be used in the following scenarios: for custom portlet: to simplify portet's and MVCCommand's code; for customization Liferay's OOTB portlets: customization portlets code may be tricky, and you may use portlet filters to inject custom functionality. Portlet Filter creation Create  service  Liferay module for the filter class. Define dependencies in  build.gradle  file: dependencies { compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel", version: "4.0.0" compileOnly group: "com.li

Servlet Filter in Liferay 7.2

Liferay 7.2 - Servlet Filter Sample Overview This article describes how to create a servlet filter in Liferay 7.2.  In this sample we'll create a filter for documents, which allows only admins to access the PDF files. Filter creation Create  service  Liferay module for the filter class. Define dependencies in  build.gradle  file: dependencies { compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel" compileOnly group: "com.liferay.portal", name: "com.liferay.util.taglib" compileOnly group: "javax.portlet", name: "portlet-api" compileOnly group: "javax.servlet", name: "javax.servlet-api" compileOnly group: "jstl", name: "jstl" compileOnly group: "org.osgi", name: "osgi.cmpn" } Define OSGi metadata in  bnd.bnd , sample: Bundle-Name: LifeDev Document Servlet Filter Bundle-SymbolicName: com.lifedev.docu

Friendly URLs for Custom Portlets

Friendly URLs for Custom Portlets Default Liferay's URLs are too long and do not look nice. You may want to make them better. And  FriendlyURLs  mechanism may help here. Let's say, you have a custom portlet displaying a single entity (called 'app'), using the ID to fetch it ('appId'). So, we would like to have an URL like: http://localhost:8080/web/guest/app-page/-/app/1234 , where  1234  is the appId. Such URL is shorter and cleaner than the full URL with long namespaced parameters. Below are the steps to register a simple friendly URL for custom portlet: Create file  src/main/resources/META-INF/friendly-url-routes/routes.xml  in your portlet module: <?xml version="1.0"?> <!DOCTYPE routes PUBLIC "-//Liferay//DTD Friendly URL Routes 7.1.0//EN" "http://www.liferay.com/dtd/liferay-friendly-url-routes_7_1_0.dtd"> <routes> <route> <pattern> /{appId:\d+} </pattern>