Latest version liferay support better way to configure friendly URL mapping. In this article, I’ll show you how to add friendly URL into your existing portlet.
First, create a xml file and give a meaningful name. Such as “product-friendly-url-routes.xml”. Place this file under your src/main/resources folder.
[googlefont font=”Oswald” fontsize=”20″]Sample unfriendly URL [/googlefont]
This is a sample URL that you have to deal with.
http://localhost:8080/en_GB/product?p_p_id=product_WAR_portlet_INSTANCE_7Huk&p_p_lifecycle=0&p_p_state=normal&p_p_mode=view&p_p_col_id=column-1&p_p_col_count=1&_product_WAR_portlet_INSTANCE_7Huk_action=expiringProduct&_product_WAR_portlet_INSTANCE_7Huk_type=all
[googlefont font=”Oswald” fontsize=”20″]Step 1: Configure friendly URL routes [/googlefont]
The sample code below show when you have an unfriendly URL that meet the condition with parameter action=expiringProduct. The liferay friendly URL mapping will change it to /expiring/view
<route> <pattern>/expiring</pattern> <implicit-parameter name="action">expiringProduct</implicit-parameter> </route>
[googlefont font=”Oswald” fontsize=”20″] More than one parameter[/googlefont]
- In this example I create few routes. When one of the criteria that match and it will apply the pattern display as part of the friendly URL.
- Example when action=expiringProduct and type=all are match, it will return a friendly url with /expiring/view-all.
- If the URL only consists of action=expiringProduct and it will return /expiring.
- The last pattern /query will generally map in most cases. (This is not required in most case, liferay provided a default mapping)
<?xml version="1.0"?> <!DOCTYPE routes PUBLIC "-//Liferay//DTD Friendly URL Routes 6.1.0//EN" "http://www.liferay.com/dtd/liferay-friendly-url-routes_6_1_0.dtd"> <routes> <route> <pattern>/expiring/view-all</pattern> <implicit-parameter name="action">expiringProduct</implicit-parameter> <implicit-parameter name="type">all</implicit-parameter> </route> <route> <pattern>/expiring</pattern> <implicit-parameter name="action">expiringProduct</implicit-parameter> </route> <route> <pattern>/expired/view-all</pattern> <implicit-parameter name="action">expiredProduct</implicit-parameter> <implicit-parameter name="type">all</implicit-parameter> </route> <route> <pattern>/expired</pattern> <implicit-parameter name="action">expiredProduct</implicit-parameter> </route> <route> <pattern>/query</pattern> <implicit-parameter name="p_p_id">product_WAR_portlet</implicit-parameter> <implicit-parameter name="p_p_lifecycle">1</implicit-parameter> <implicit-parameter name="p_p_mode">view</implicit-parameter> </route> </routes>
[googlefont font=”Oswald” fontsize=”20″]Step 2: Configure liferay-portlet.xml [/googlefont]
Open your liferay-portlet.xml and add the highlighted element.
<portlet> <portlet-name>product</portlet-name> [highlight type="yellow"]<struts-path>product</struts-path>[/highlight] [highlight type="yellow"]<friendly-url-mapper-class>[/highlight] [highlight type="yellow"]com.liferay.portal.kernel.portlet.DefaultFriendlyURLMapper[/highlight] [highlight type="yellow"]</friendly-url-mapper-class>[/highlight] [highlight type="yellow"]<friendly-url-mapping>myproduct</friendly-url-mapping>[/highlight] [highlight type="yellow"]<friendly-url-routes>[/highlight] [highlight type="yellow"]product-friendly-url-routes.xml[/highlight] [highlight type="yellow"]</friendly-url-routes>[/highlight] <layout-cacheable>false</layout-cacheable> <instanceable>false</instanceable> <private-request-attributes>false</private-request-attributes> <private-session-attributes>false</private-session-attributes> <header-portlet-javascript>/js/jquery1.8.2.js</header-portlet-javascript> <header-portlet-javascript>/js/jquery.portlet.js</header-portlet-javascript> <add-default-resource>true</add-default-resource> </portlet>
[googlefont font=”Oswald” fontsize=”20″]structs-path[/googlefont]
You can find your structs-path from your original URL. Copy and paste it.
[googlefont font=”Oswald” fontsize=”20″]friendly-url-mapping[/googlefont]
You can configure the fragment as you like in friendly-url-mapping setting. It will display as part of the friendly URL.
[googlefont font=”Oswald” fontsize=”20″]friendly-url-routes [/googlefont]
A place to register your friendly url routes xml file
[googlefont font=”Oswald” fontsize=”20″]JSP[/googlefont]
In you JSP you can hardcoded the path where it link to your portlet or generate friendly URL dynamically.
<a href="./product/-/myproduct/expiring">Show expiring product</a> <a href="./product/-/myproduct/expired">Show expired product</a> --- OR --- <portlet:renderURL var="expiringProductURL"> <portlet:param name="type" value="all"/> </portlet:renderURL> <a href="${expiringProductURL}">All Expiring Product</a>
[googlefont font=”Oswald” fontsize=”20″]Reference[/googlefont]
- https://www.liferay.com/community/wiki/-/wiki/Main/FriendlyURLMapper#section-FriendlyURLMapper-Instanceable+Portlets
- https://www.liferay.com/documentation/liferay-portal/6.1/development/-/ai/adding-friendly-url-mapping-to-the-portlet
[googlefont font=”Oswald” fontsize=”20″]Download example[/googlefont]
You can download the sample example from here
Hi,
I tried to implement friendly url for my portlet “product” but unfortunatly it didn’t work. Please can you help me, I’m reaaly new to liferay development.
Thanks alot.
Nabil
1- Below the route
/{instanceId}
0
view
normal
/product/view_product
/{instanceId}/maximized
0
view
maximized
/product/view_product
2 – Below the origine url I want to transform as friendly URL
http://localhost:8080/web/guest/product?
p_p_id=225_INSTANCE_08MX&
p_p_lifecycle=0
&p_p_state=normal&
p_p_mode=view&
p_p_col_id=column-1&
p_p_col_count=1
&_225_INSTANCE_08MX_struts_action=%2Fproduct%2Fview_product
&_225_INSTANCE_08MX_redirect=http%3A%2F%2Flocalhost%3A8080%2Fweb%2Fguest%2Fproduct%3Fp_p_id%3D25_INSTANCE_08MX%26p_p_lifecycle%3D0%26p_p_state%3Dnormal%26p_p_mode%3Dview%26p_p_col_id%3Dcolumn-1%26p_p_col_count%3D1%26_225_INSTANCE_08MX_%252F%3D
&_225_INSTANCE_08MX_productId=25414