Chapter 11. CMS Portlet
Prev |  | Next

## Chapter 11. CMS Portlet

### Roy Russo

`<roy @ jboss dot org>`

### Thomas Heute

`<theute@jboss.org>`

JBoss Portal packages a Web Content Management System capable of serving and allowing administration of web content. This chapter describes the CMS Portlet which is responsible for serving resources requested, the following chapter describes the CMSAdmin Portlet and all administration functionality.

## 11.1. Introduction

The CMS Portlet displays content from the file store inside a portlet window, or, in the case of binary content, outside of the portlet window altogether.

## 11.2. Features

The CMSPortlet handles all requests for all content types.

The methodology of serving content within the CMSPortlet, allows for some beneficial features, like:

1. Search-engine friendly URLs: http://domain/[portal]/content/company.html
2. Serve binaries with simple urls independant of the portal: http://domain/content/products.pdf
3. Deploy several instances of the CMSPortlet on any page and configure them to display different start pages.
4. Localization support: CMSPortlet will display content based on the user request locale, or display content using the default locale setting.

## 11.3. CMS Configuration

### 11.3.1. Welcome page

The CMS portlet default page is defined as a preference and can be overriden like any other preference up to the user's preference level. The default CMS portlet displayed when you install JBoss Portal for the first time is describe in the following file: jboss-portal.sar/portal-core.war/WEB-INF/portlet.xml .

             <portlet-preferences>
                <preference>
                   <name>indexpage</name>
                   <value>/default/index.html</value>
                </preference>
             </portlet-preferences>

The preference key is "indexpage". To change the default page, just make sure to create an html document using the CMS Admin portlet then change the value of "indexpage" to the corresponding path.

### 11.3.2. Service Configuration

#### 11.3.2.1. Tuning Jackrabbit

JBoss Portal uses Apache Jackrabbit as its Java Content Repository implementation. Configuration of the service descriptor, allows for changing many of the variables associated with the service.

Here is the default configuration for the CMS repository found under `portal-cms.sar/META-INF-INF/jboss-service.xml`

             ...
             <attribute name="DoChecking">true</attribute>
             <attribute name="DefaultContentLocation">portal/cms/conf/default-content/default/</attribute>
             <attribute name="DefaultLocale">en</attribute>
             <attribute name="RepositoryName">PortalRepository</attribute>
             <attribute name="HomeDir">${jboss.server.data.dir}${/}portal${/}cms${/}conf</attribute>

Below is a list of items found in the service descriptor and their definitions. Only items commonly changed are covered here and it is recommended you do not change any others unless you are very brave.

- DoChecking: Should the portal attempt to check for the existence of the repository configuration files and default content on startup?
- DefaultContentLocation: Location of the default content used to pre-populate the repository.
- DefaultLocale: Two-letter abbreviation of the default locale the portal should use when fetching content for users. A complete ISO-639 list can be found here .
- HomeDir: Location of configuration information for the repository when in 100% FileSystem store mode. Otherwise, its in the database.

#### 11.3.2.2. Changing the url under which the content should be accessible

By default, the content will be accessible to a url like this: http://www.example.com/content/[...], if you need or prefer to change "content" to something else you will need to edit the following file: `portal-cms.sar/META-INF-INF/jboss-service.xml` and change the value of Prefix to something else. Please note that you cannot change it to "nothing", you need to provide a value.

             ...
       <mbean
          code="org.jboss.portal.core.cms.CMSObjectCommandFactory"
          name="portal:commandFactory=CMSObject"
          xmbean-dd=""
          xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
          <xmbean/>
          <attribute name="Prefix">content</attribute>
          <attribute name="TargetWindowRef">default.default.CMSPortletWindow</attribute>
          <depends optional-attribute-name="Factory" proxy-type="attribute">portal:commandFactory=Delegating</depends>
          <depends optional-attribute-name="CMSService" proxy-type="attribute">portal:service=CMS</depends>
       </mbean>
             ...

- Prefix: This is the context path prefix that will trigger the portal to render content. By default, navigating to a URL such as http://localhost:8080/[portal_context]/content/Test.PDF will trigger the portal to display the PDF isolated from the portal pages. The path following the Prefix has to be absolute when fetching content.

### 11.3.3. Configuring the Content Store Location

By default, the JBoss Portal CMS stores all node properties, references, and binary content in the database, using the portal datasource. The location of some of these items is configurable, and there are 3 options:

- Section 11.3.3.1, “100% Filesystem Storage”

- Section 11.3.3.2, “100% Database Storage”

- Section 11.3.3.3, “Mixed Storage”

#### 11.3.3.1. 100% Filesystem Storage

To enable 100% Filesystem storage, you must edit the file: jboss-portal.sar/portal-cms.sar/META-INF/jboss-service.xml . You will note that the file is set to use the HibernateStore and HibernatePersistenceManager classes, by default. To have the CMS use 100% file system storage, simply comment these blocks. Then, you should uncomment to use the LocalFileSystem and XMLPersistenceManager classes. Follow these steps to activate 100% FS storage:

1. Comment out the following blocks (there are 3 in total):

       <!-- HibernateStore: uses RDBMS + Hibernate for storage -->
       <FileSystem class="org.jboss.portal.cms.hibernate.HibernateStore">
       ...
       </FileSystem>

   And uncomment the blocks under them (there are 3 in total):

       <!-- LocalFileSystem: uses FileSystem for storage. -->
       <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
       ...
       </FileSystem>

2. Now comment out the following blocks (there are 2 in total):

       <!-- HibernatePersistentManager: uses RDBMS + Hibernate for storage -->
       <PersistenceManager class="org.jboss.portal.cms.hibernate.state.HibernatePersistenceManager">
       ...
       </PersistenceManager>

   And uncomment the blocks under them (there are 2 in total):

       <!-- XMLPersistenceManager: uses FileSystem for storage -->
       <PersistenceManager class="org.apache.jackrabbit.core.state.xml.XMLPersistenceManager"/>

### Warning

If you do any change at the workspaces configuration you will need to delete the file $JBOSS_HOME/server/xxx/data/portal/cms/conf/workspaces/default/workspace.xml before restarting JBoss or redeploying JBoss Portal. If you forget to do that, the changes won't affect the CMS. For the same reason, you also need to delete that file if you recompile JBoss Portal after changing the name of the datasource. Note that on a cluster environment, you need to remove that file (if it exists) on all the nodes.

#### 11.3.3.2. 100% Database Storage

This is the default configuration for the CMS store. Please view the original jboss-portal.sar/portal-cms.sar/META-INF/jboss-service.xml , for guidance on how to reset it.

#### 11.3.3.3. Mixed Storage

Mixed storage consists of meta-data being stored in the DB and blobs being stored on the Filesystem. This is the recommended setting for those of you that serve large files or stream media content.

Setting the repository this way is simple. Change every instance in the file jboss-portal.sar/portal-cms.sar/META-INF/jboss-service.xml , from:

    <param name="externalBLOBs" value="false"/>

to:

    <param name="externalBLOBs" value="true"/>

### Warning

If you do any change at the workspaces configuration you will need to delete the file $JBOSS_HOME/server/xxx/data/portal/cms/conf/workspaces/default/workspace.xml before restarting JBoss or redeploying JBoss Portal. If you forget to do that, the changes won't affect the CMS. For the same reason, you also need to delete that file if you recompile JBoss Portal after changing the name of the datasource. Note that on a cluster environment, you need to remove that file (if it exists) on all the nodes.

## 11.4. Localization Support

The CMS Portlet now serves content based on the user's locale setting. For example: if a user's locale is set to Spanish in his browser, and he requests URL: default/index.html , the CMSPortlet will first try and retrieve the Spanish version of that file. If a Spanish version is not found, it will then try and retrieve the default language version set for the CMSPortlet.

## 11.5. CMS Service

The CMS portlet calls a CMS service that can be reused in your own portlets.

### 11.5.1. CMS Interceptors

Since JBoss Portal 2.4 you can add your own interceptor stack to the CMS service. The interceptors are called around each command (Get a file, write a file, create a folder...), this is a very easy way to customize some actions based on your needs.

To create your own interceptor you just need to extend the `org.jboss.portal.cms.CMSInterceptor` class and provide the content of the `invoke(JCRCommand)` method. Do not forget to make a call to `JCRCommand.invokeNext()` or the command will never be executed.

JBoss Portal provides two CMS interceptors out of the box, a very basic Log interceptor ( `org.jboss.portal.cms.impl.interceptors.LogInterceptor` ) that prints all the commands called. And a cache interceptor to enable distributed caching or content ( `org.jboss.portal.cms.impl.interceptors.CacheInterceptor` ). For more information about the cache interceptor, see below.

To add or remove an interceptor, you just need to edit the following file: `portal-cms-sar/META-INF/jboss-service.xml`. It works the same way as the server interceptor, for each interceptor you need to define an mbean then add it to the cms interceptor stack. For example, if you have the 2 default interceptors, you should have the following lines in the jboss-service.xml file:

       <mbean
          code="org.jboss.portal.cms.impl.interceptors.LogInterceptor"
          name="portal:service=Interceptor,type=Cms,name=Log"
          xmbean-dd=""
          xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
          <xmbean/>
       </mbean>
       <mbean
          code="org.jboss.portal.cms.impl.interceptors.CacheInterceptor"
          name="portal:service=Interceptor,type=Cms,name=Cache"
          xmbean-dd=""
          xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
          <xmbean/>
          <depends>portal:service=CMSTreeCache</depends>
       </mbean>
       <mbean
          code="org.jboss.portal.server.impl.invocation.JBossInterceptorStack"
          name="portal:service=InterceptorStack,type=Cms"
          xmbean-dd=""
          xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
          <xmbean/>
          <depends-list optional-attribute-name="InterceptorNames">
             <depends-list-element>portal:service=Interceptor,type=Cms,name=Log</depends-list-element>
             <depends-list-element>portal:service=Interceptor,type=Cms,name=Cache</depends-list-element>
          </depends-list>
       </mbean>

The first two mbeans define the interceptors and the third mbean, define which interceptors to add to the CMS service.

If you create your own interceptor `org.example.myCMSInterceptor`, the service descriptor file will look like:

       <mbean
          code="org.example.myCMSInterceptor"
          name="portal:service=Interceptor,type=Cms,name=MyName"
          xmbean-dd=""
          xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
          <xmbean/>
       </mbean>
       <mbean
          code="org.jboss.portal.cms.impl.interceptors.LogInterceptor"
          name="portal:service=Interceptor,type=Cms,name=Log"
          xmbean-dd=""
          xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
          <xmbean/>
       </mbean>
       <mbean
          code="org.jboss.portal.cms.impl.interceptors.CacheInterceptor"
          name="portal:service=Interceptor,type=Cms,name=Cache"
          xmbean-dd=""
          xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
          <xmbean/>
          <depends>portal:service=CMSTreeCache</depends>
       </mbean>
       <mbean
          code="org.jboss.portal.server.impl.invocation.JBossInterceptorStack"
          name="portal:service=InterceptorStack,type=Cms"
          xmbean-dd=""
          xmbean-code="org.jboss.portal.common.system.JBossServiceModelMBean">
          <xmbean/>
          <depends-list optional-attribute-name="InterceptorNames">
             <depends-list-element>portal:service=Interceptor,type=Cms,name=Log</depends-list-element>
             <depends-list-element>portal:service=Interceptor,type=Cms,name=Cache</depends-list-element>
             <depends-list-element>portal:service=Interceptor,type=Cms,name=MyName</depends-list-element>
          </depends-list>
       </mbean>

### Note

The interceptor order is important ! For example the cache interceptor may stop the call, so if you place the log interceptor after the call you wouldn't see all the commands that have been executed by the portlets.

To check that the interceptors have been correctly added, you can check the JMX console, by going to: `http://localhost.localdomain:8080/jmx-console/HtmlAdaptor?action=inspectMBean&name=portal%3Aservice%3DInterceptorStack%2Ctype%3DCms` You should notice all the interceptors in the attribute "interceptors".

### 11.5.2. CMS Cache

The CMS cache is implemented as an interceptor, it makes it easy to be added or removed as you saw above. The CMS cache is available by default only if you precised `portal.clustered = true` in local.properties then cleaned, built and deployed the corresponding portal.

Prev | Up | Next
Chapter 10. Security | Home | Chapter 12. Layouts and Themes