Organization hierarchy, virtual host and friendly URL

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?

Blogs
Very good article exactly what i was needing to look at. Thanks
nice blog, Jonas.
I came across the exact same situation in a project.
Is that something you already implemented? I would be interested in some insights of your changes to the VirtualHostFiler class.

When will this be available in Liferay? :-)

Thanks
Thanks, @William and @st,

This new feature is not available in Liferay 6.1 yet. At present, the patch is available for 6.0 EE. Please let me know if you want to use this new feature in 6.0 EE.

By the way, a patch for 6.0.5 GA 3 could be easily provided when requested.
Hi Jonas,
thanks for your quick reply. I will discuss with the project manager and get back to you.
happy friday
s t
Hi Jonas,
we'd like to test the patch and play with it a little. Is it available in the download section for EE Customers? How can we get it?

Thanks
s t
Hi ST, please drop email to jonasliferay@gmail.com. I will send the patch 6.0 EE by email.

Thanks

Jonas
Hi Jonas,I want it try it too,
Can you send the patch 6.0 EE to me!
k0521klb@163.com
@lb, thanks. The fix patch was sent by email. Please check. It would be nice that you could share your test results here.
Configuring the virtual host perhaps you could have lower Google Page Rank:

"If you set up virtual host in configuration of your community there are two ways to access every page. There is normal domain.com/web/guest/my-page-title and domain.com/my-page-title . Problem is those are two different URL and google can treat them as duplicate content (http://www.google.com/support/webmasters/bin/answer.py?answer=66359) and lower Page Rank."

Is there a solution for this?

http://issues.liferay.com/browse/LPS-20389
Thank you so much Jonas. Your usage and explanation of Liferay is excellent.
[...] Consegui usando virtual hosts, como explicaram no wiki do Liferay, aqui e um pouco nesse blog. Não fiz exatamente como explicaram lá: [...] Read More