Liferay portal provides a lot of cool features, for example, Organization hierarchy, virtual host and SEO (Search engine optimization) friendly URL. Web sites can be built based on organizations and organization hierarchy. Each organization can have public pages and private pages. Each organization can have friendly URL, like /my-org, where only one slash is allowed, while each page can have friendly URL, like /home, /flickr/home, where multiple slashes got supported. In addition, organization public pages can have public virtual host; organization private pages can have private virtual host. (Abstracted from the book: Liferay Portal 6 Enterprise Intranets).
Indeed, these are powerful features to build and manage website. In some use cases, these would not be sufficient. For example, here is a custom model: each brand can have many destinations, while each destination can have many hotels. Each Brand, destination or hotel will have its own public pages and private pages.
As shown in the preceding diagram, each brand will have public virtual host – domain name and SEO friendly URL:
Use case A) http://www.${brand.name}.com[/${locale}]
where ${brand.name} should be brand (presented as a root organization) friendly URL. While destination and hotel do not need virtual host, but they need SEO friendly URL like
Use case B) http://www.${brand.name}.com[/${locale}]/${destination.name} for destination
Use case C) http://www.${brand.name}.com[/${locale}]/${destination.name}/${hotel.name} for hotel
Where ${destination.name} should be destination (presented as a 1st level organization) SEO friendly URL; ${hotel.name} should be hotel (presented as a 2nd level organization) SEO friendly URL.
How to implement these use cases A), B) and C)? This article will show what organization hierarchy, virtual host and SEO friendly URL are and how to extend these features.
Organization hierarchy
Regular organization can be a root, having no parent organization, like Fiesta Americana; or regular organization can have a parent organization, like Cancun, Mexico City, and many child organizations or locations, like Fiesta-Americana Villas Cancun, Fiesta Americana Reforma, and Fiesta Americana Santa Fe. Location must have a regular organization as parent, and have no child organizations. Therefore, organizations and locations form a hierarchical structure: regular organizations form root and trunk; while locations form leaves, as shown in following screenshot.
Virtual host
Suppose that you have virtual domain (or real domain): demo.fiestamericana.com.
You can set public virtual host for the organization Fiesta Americana to demo.fiestamericana.com as follows.
Then you can view any pages of the organization Fiesta Americana.
http://demo.fiestamericana.com/${layout.friendly.url}
You can also view any pages in different languages.
http://demo.fiestamericana.com[/${locale}]/${layout.friendly.url}
As you can see, use case A) can be implemented by group public or private virtual host settings.
Friendly URL
Both Group and Layout can have friend URL.
As Brian Chan mentioned earlier, Group friendly URL should have one and only slash. As shown in the preceding screenshot, the organization Fiesta Americana has friendly URL "/fiesta-ammericana" - there is one and only slash.
Layout can have friendly URL with multiple slashes. As shown in following screenshot, layout "Test" has friendly URL "/home/test".
Customizing virtual host and friendly URL
As you can see, using liferay default features, use cases B) and C) can not be satisfied with.
Thus Here I suggest a new feature: customizing group friendly URL and virtual host.
How?
1) first provide properties - adding following properties in portal-ext.properties.
##
## custom organization friendly URLs
##
## enabling custom organization friendly URLs,
## set custom.organization.friendly.url.enabled to true;
## otherwise set it to false
custom.organization.friendly.url.enabled=true
2) Then customize group friendly URL and virtual host in Virtual Host Filter
3) Definitely keep Liferay portal default features (group friendly URL and virtual host) 100% AS IS; and add customized group friendly URL and virtual host on top of default features.
Results
After applying the new feature, both use case B) and use case C) got supported.
Use case B)
http://demo.fiestamericana.com/cancun for default language, that is, US English;
http://demo.fiestamericana.com/de/cancun for German.
Of course, Liferay default features are working well AS IS. Suppose that layout.friendly.url.public.servlet.mapping is set by default as /web.
http://demo.fiestamericana.com/web/cancun for default language, that is, US English;
http://demo.fiestamericana.com/de/web/cancun for German.
Use case C)
http://demo.fiestamericana.com/es/cancun/fiesta-americana-villas-cancun for Spanish.
http://demo.fiestamericana.com/de/cancun/fiesta-americana-villas-cancun for German.
http://demo.fiestamericana.com/cancun/fiesta-americana-villas-cancun for default locale, that is, US English
Sure, Liferay default features are working well 100% AS IS.
http://demo.fiestamericana.com/es/web/fiesta-americana-villas-cancun for Spanish.
http://demo.fiestamericana.com/de/web/fiesta-americana-villas-cancun for German.
http://demo.fiestamericana.com/web/fiesta-americana-villas-cancun for default locale, that is, US English
By the way, to disable this customized feature, you can simply set the property custom.organization.friendly.url.enabled to false. Then what you have are Liferay default features - 100%, of course.
In addition, you can apply same friendly URLs in Language portlet. Thus when clicking on the icons in Language portlet, you would be able to get same friendly URLs.
Is this feature useful? Your suggestions?
What's next?
As you can see, there are a few limitations:
1) Root Organization has been set up virtual host, either public virtual host or private virtual host, or both. What's happening if virtual host was not set properly?
2) Currently destination and hotel friendly URL have been mapped to 1st level organization and 2nd level organization, respectively.
3) All brands have been managed as root organizations in a portal instance. What's happening if one brand has been managed as root organization in one portal instance while another brand has been managed as root organization in another portal instance?


