Jetspeed version 2.2.1 introduces JetUI rendering engine. JetUI is a replacement for the now deprecated and removed Jetspeed Desktop pipeline. JetUI is primary concerned with advanced portal customization and rendering features. With JetUI, we have not abandoned pure server-side rendering. Jetspeed will still fully support classic server side rendering of portal pages. With version 2.2.1, two rendering engines are made available to you directly from the installer:
There are a few options for turning on the JetUI rendering and customization engine. The first option is to install Jetspeed using our packaged installer The installer will ask you if you would like to install the JetUI or Classic portal pipeline. You cannot run both at once. The default is JetUI.
The second option is to build Jetspeed using the Custom Builder. The Build Guide is a bit long winded and has a lot of information about Maven internals. Here are a few commands distilled to help you get past all that...
List all build commands available to from the custom builder:
mvn jetspeed:mvn -Dlist
Build and deploy the entire JetUI-enabled portal demo with several portlet apps and deploy it to Tomcat
mvn jetspeed:mvn -Dtarget=ui
Build and deploy the JetUI-enabled minimal with only j2-admin portlet app and deploy it to Tomcat
mvn jetspeed:mvn -Dtarget=min-ui
Variants of the two options above, with DBPSMLL-enabled
mvn jetspeed:mvn -Dtarget=ui-dbpsml mvn jetspeed:mvn -Dtarget=min-ui-dbpsml
The third option is to manually switch to using the JetUI portal on a deployed installation of Jetspeed. Editing the WEB-INF/conf/jetspeed.properties (or WEB-INF/conf/override.properties), you can manually switch from Classic mode to JetUI mode and back by setting the jetui.customization.method to Classic: server; or JetUI: ajax.
jetui.customization.method=ajax
Additionally, you can set the default pipeline, although it is not necessary if you directly hit the JetUI pipeline by addressing all URLs with /jetspeed/ui instead of /jetspeed/portal
pipeline.default = jetui-pipeline
Finally, if you would like for /jetspeed/portal to go to the JetUI pipeline, change the pipelines.xml pipeline-map bean to:
<entry key='/portal'> <value>jetui-pipeline</value> </entry>
If you will be deploying a JetUI site, it is important to understand how spaces are configured. A space is a top level organization of the Jetspeed site. You can use spaces to organize or group projects or teams into a common area. Spaces have a lot in common with folders, and they support all folder functionality and metadata. Just like folders, Spaces can have specific security constraints on them. There are two administrative tools available for managing Spaces: the Space Manager and the Space Navigator. The Space Manager allows you to maintain spaces, for example if you want to add or modify a space, use the Space Manager.
Configuring a Space With a two exceptions, Spaces can only be top level folders. You can configure your spaces by editing the folder.metadata file of any space. In a folder.metadata file of any top level directory, you can make that folder a space by adding the space-owner metadata property:<metadata name='space-owner' xml:lang='en'>admin</metadata>
Once you have added this single property, the folder will be promoted from a normal folder to a space. You can also use the Space Manager to create spaces. There are two other kinds of Spaces:
The Public Space is really the root directory of the Jetspeed site. It has a security constraint of public-view, meaning that only the administrator can edit it, and that all other users can view the public space. The Public Space is important in that you can set metadata here that is inherited by all other spaces and folders in the system. For example, you can set the theme or default security policy for the entire site in the folder.metadata file in the root Public Space. Of course Spaces can override these settings.
Every user gets their own space. User spaces are located in the /_user/{username} folders. The username is usually set as the space-owner in the space-owner metadata tag.
When a new user is added to the system, Jetspeed will create a Home space for that user, and copy in the contents of a template folder as the default home space for that user. You can configure the new user template in the /_template/new-user folder. Here you will find a folder.metadata file, along with several other page files which are all copied into a new user home space when that user is created. The space-owner metadata tag is added automatically to the folder-metadata by Jetspeed. Additionally, certain regular expression rules are used to build the menus fro the Jetspeed Page Navigator. The regex below is the default, and it tells the Page Navigator to show menus for pages and folders in the current directory, as well as all links in the home space of the user.
<menu name="space-navigations" regexp="true" options="+/*/,+/*.psml" depth="-1"/> <menu name="space-links" regexp="true" options="+/*.link"/>
There is also a template that is used for when new spaces are created. This template is found under /_template/space. Here you can configure which default pages, links and security constraints are applied when creating a new space. Feel free to modify the files, or add more pages in the user and space templates found in /_template for your systems.
Future Directions - SpacesSpaces also support an additional organization of content called Environments. Environments are a collection of spaces. JetUI does not currently support environment administration. Spaces were introduced to Jetspeed with version 2.2.1, along with JetUI. Future versions of Jetspeed will support full domain mappings to spaces. Domain mapping will enable use cases like white label portals, where different URLs map to different Spaces or Environments. In an upcoming release, Jetspeed will support multi-domain security. This means you can setup a domain of users, and associate those users with a domain and set of Spaces.
The Space Navigator is a special navigational portlet giving users quick access to spaces. From the Space Navigator, you can navigate to any space in the system where you have secure access to view that space. Additionally, from the Space Navigator, the Admin can Edit the current space, as well as create a new space. The Space Navigator is implemented using two new features introduced with JetUI: page templates and detached portlets. In order for the Space Navigator to appear on every page in the system, we have configured the Space Navigator in the root folder in the page template named template.tpsml. Since this portlet definition is in the system wide page template, it will automatically appear on every page in the system, allowing your users to always have access to space navigation.
<fragment id="jsSpaceNavigator" type="portlet" name="j2-admin::SpaceNavigator" decorator='clear'> <property name="y" value="300"></property> <property name="x" value="20"></property> <property name="state" value="detach"></property> </fragment>
Additionally, the Space Navigator is a detached portlet. JetUI introduced a new special property to fragments named state. We set this property to the value detach. If a portlet is detached, it is not limited to the flow layout control of most portal pages. Instead it can be placed at a specific area on the page. See the x and y properties, which are used to locate the portlet at a specific location in the page header area. Detached portlets can also be dragged and moved around. However, we do not want the portlet to be moved, so we use a clear decorator, meaning the portlet has no title bar. Since JetUI drags and drops portlets by the title bar, if we use a clear decorator, the portlet cannot be moved.
In Classic Jetspeed, URLs are mapped using the Jetspeed Profiler. The Profiler uses a powerful set of rules to locate a page, based on runtime parameters such as language, country code or media type. While the profiler is powerful, it is also complicated to configure. JetUI simplifies URL mapping by having not using the profiler. This means that a URLs map directly to the logical folder or page in the Jetspeed site. JetUI does not support subsites, since subsites are driven by profile rules.
Portlets can be moved around the page by clicking on their title bar, holding the mouse down, and dragging the portlet to another location on the page. By default, you can only drag portlets by their title bar. There are two modes of drag and drop:
There is a CSS style configured in jetspeed.properties to indicate which div of a portal is the draggable part. This property is jetui.style.drag.handle which defaults to the decorator style named .PTitle
JetUI supports two toolbars, one docked on the left-side, and one docked on the right-side of the page. These toolbars are optional, but out of the box they are configured to be enabled. In the demo distribution of JetUI, we have placed the toolbars in the system wide page template, template.tpsml, meaning that all pages will by default display the toolbars. You can easily configure the page template to not have toolbars, or only have one toolbar, by editing the template.tpsml file and removing the two fragment definitions. The fragment definitions must use a special fragment id by convention. For the left toolbar, the fragment id must be jstbLeft. For the right toolbar, the fragment id must be jstbRight. If these fragments are not found on a page, the toolbar will not be displayed.
<fragment id="jstbLeft" type="layout" name="jetspeed-layouts::VelocityOneColumn"> <property name="row" value="0"></property> <property name="column" value="0"></property> <property name="state" value="normal"></property> <property name='toolbar' value='true'></property> <property name='class' value='jsLeftToolbar'></property> <fragment id="jsPageNavigator" type="portlet" name="j2-admin::PageNavigator"> <property name="row" value="0"></property> <property name="column" value="0"></property> <property name="state" value="normal"></property> <property name="tool" value="true"></property> </fragment> </fragment>
Notice that there are special properties for a toolbar. A toolbar is a layout. It requires a special property to denote that it is a toolbar. This property is aptly named toolbar and is set to true. A toolbar fragment has a location on the page specified by row and column properties. It also has a state property, which can be either normal or closed. There are arrow buttons at the top of the toolbar, which allows you to hide or open the toolbar. This state is persisted per user in the state property of the fragment. When the toolbar is open, the state is normal, when closed, the state is closed. Finally, a toolbar has a CSS class which is used to format the layout. The layout is a single column containing one portlet, the Page Navigator, which is flagged as a tool. Tools can not be drop targets when using flow control drag and drop. In this case there is only one portlet in the toolbar. Of course more than one portlet could be placed in the toolbar.
Here is the definition for the right toolbar, which holds the Jetspeed Toolbox
<fragment id="jstbRight" type="layout" name="jetspeed-layouts::VelocityOneColumn"> <property name="row" value="0"></property> <property name="column" value="2"></property> <property name="state" value="normal"></property> <property name='toolbar' value='true'></property> <property name="state" scope="user" scopeValue="guest" value="closed"></property> <property name='class' value='jsRightToolbar'></property> <fragment id="jsToolbox" type="portlet" name="j2-admin::JetspeedToolbox"> <property name="row" value="0"></property> <property name="column" value="0"></property> <property name="state" value="normal"></property> <property name="tool" value="true"></property> </fragment> </fragment>
JetUI introduces a three new portlet window actions: detach, attach and close. Actually detach and attach are toggles, a portlet is either detached or attached, it can never be both. A close up look at the portlet title bar shows the two new action icons, the X is the close button, which will remove the portlet from the page. The button to its right, with the arrow hooking to the left, is the detach button. Once a portlet is detached, the detach button becomes an re-attach button, the one with the arrow hooking to the right Detaching a portlet puts the portlet in Z-Order drag and drop mode, meaning it always tries to stay on top of all other portlets. By pressing the attach button, the portlet is put back into the nearest slot in a column, going back to flow control drag and drop and rendering. The detached state is stored on the fragment, and the state can be on a per user basis. Here we see both the row, column and x,y properties set on this fragment. The row and column or only relevant for an attached portlet being rendering in flow control mode. The x,y properties are only relevant when the portlet is detached. Also notice the state of this fragment is detach. Additionally, there is a new attribute on properties named scope. Below you can see the x,y values are scoped for a user, with the scopeValue set to the username admin. Each user can have their portlet positioning customized to their settings. As you can see, the XML can get quite large with many users. It is therefore recommended to always store PSML in the database with JetUI.
<fragment id="dp-22" type="portlet" name="j2-admin::ForgottenPasswordPortlet"> <property name="row" value="1"></property> <property name="column" value="0"></property> <property name="x" scope="user" scopeValue="admin" value="536.0"></property> <property name="y" scope="user" scopeValue="admin" value="88.0"></property> <property name="width" scope="user" scopeValue="admin" value="1121.0"></property> <property name="height" scope="user" scopeValue="admin" value="120.0"></property> <property name="state" scope="user" scopeValue="admin" value="detach"></property> <property name="row" scope="user" scopeValue="admin" value="4"></property> </fragment>
Here is a screen shot of a bunch of portlets all detached. As you can see, it is like a desktop. All portlets get can get focus when clicked on, going to the top of the rendering order for the page.
Only detached portlets can be resized. Resizing is rather easy to do. Simply grab the portlet by the bottom right hand corner, where you will see a gradient icon, and drag it away to make it bigger, or in towards itself to make the portlet window smaller. If a portlet is attached, the gradient will not be visible. When a portlet is resized, two new attributes are stored with the fragment, height and width. This is how Jetspeed stores the width and height of a resized portlet. Notice how the height and witdth properties are store with a user scope, and for the scopeValue the name of the user is stored as dave. Each user can have their portlet window sizes customized to their settings. As you can see, the XML can get quite large with many users. It is therefore recommended to always store PSML in the database with JetUI.
<fragment id="dp-22" type="portlet" name="j2-admin::ForgottenPasswordPortlet"> ... <property name="width" scope="user" scopeValue="dave" value="1121.0"></property> <property name="height" scope="user" scopeValue="dave" value="120.0"></property> <property name="state" scope="user" scopeValue="dave" value="detach"></property> </fragment>
The Jetspeed Toolbox is a dockable portlet, designed to make user customizations very easy in just one click. The toolbox can be docked to the left or right side of the page, or it can float freely on top of the page. The toolbox contains three panels giving you quick access to adding portlets, changing layouts, or changing themes:
The Portlet Selector is the first tab. This new feature gives you fast access to page customization by allowing you to search for portlets by keyword or category, and then add the portlets to your page with one click. The first feature you will see is the search capability of the toolbox. You can type in a search string, and the portlet selector will return a list of portlets matching your search criteria. The search is on fully-indexed portlet metadata, like keywords and titles, over all automatically indexed content in the portlet registry. The search index is Lucene, and the Solr enterprise search engine is also supported.
Additionally, portlets can be categorized and filtered based on categories (see the drop down list). One click addition of portlets is now possible without ever leaving the page being customized. Portlets are also filtered by secure access. Only portlets that are configured to be viewable to the current user are displayed in the Jetspeed Toolbox.
Categories are configured in either the j2-admin portlet.xml deployment descriptor, or with the Portlet Application Manager as shown below. Remember when adding a new category, to give it a new category name prefixed by Keywords:, and then add all the keywords relevant to the category in a comma separated list in the corresponding Value field. When the search engine searches over portlet content, it will match the keywords to the search results. The preference named Categories is also important, dont forget to add your category name to this comma-separated list or your Category will not show up. Finally, the number of rows of portlets displayed in the portlet selector is controlled by the Rows preference. Ignore the Columns preference. There is also a DefaultCategory preference, which is the initial category displayed in the portlet selector.
Selecting the theme for the current page is as easy as selecting the theme tab and then clicking on the theme. Jetspeed introduces several new themes in 2.2.1. Themes are still implemented as page decorators, with a few extensions made in the page decorator decorator.properties. You can find the page decorators in the Jetspeed webapp, under decorations/layout directory. There are currently for layouts supporting JetUI: Green Earth, Jetspeed, Purple Planet, and Turbo. In order for a decorator to appear in the theme selector, you will need to add two properties to the decorator.properties file.
icon = images/greenearth.png compatibility=2.2.1
The compatibility setting tells JetUI which version this decorator is compatible. In order to be used with JetUI, the value of the compatibility property must be 2.2.1 or higher. The icon property is used in the Toolbox to provide a visual of the colors that will be used in the theme. The file should be placed in the decorations/layout/{decoratorName}/images directory.
Page layouts, selected from the Layout tab, allow the end user the ability to customize the layout of a page with one click. There are four supporte layouts: OneColumn, TwoColumn, ThreeColumn, and FourColumn. The layouts in JetUI are currently limited to these four choices. We hope to improve on that in the new future. The images you see are stored under the Jetspeed webapp in the layouts directory.
The Portlet Selector supports previewing portlets, in case you don't want to place the portlet on the page before first having a look at it. There are two ways for a portlet to support previewing. First, the portlet can provide an image of the portlet, and tell Jetspeed about it in the jetspeed-portlet.xml deployment descriptor of the portlet app Enter a js:metadata for the given portlet, with the name attribute set to portlet.preview.image where the image path is a portlet application relative path to a preview image.
<portlet id="WeatherPortlet"> <portlet-name>WeatherPortlet</portlet-name> <js:metadata name="portlet.preview.image">/images/preview/weatherportlet.png</js:metadata> </portlet> <portlet id="GoogleMapsPortlet"> <portlet-name>GoogleMapsPortlet</portlet-name> <js:metadata name="portlet.preview.image">/images/preview/googlemapsportlet.png</js:metadata> </portlet>
Portlets can also implement an extended Custom Preview Mode. This requires actually coding in the portlet, as well as the following deployment elements in the portlet.xml on a portlet definition:
<supports> <mime-type>text/html</mime-type> ... <portlet-mode>preview</portlet-mode>
Additionally the custom portlet mode must be declared for the portlet applications
. .. <custom-portlet-mode> <description>Custom Preview Mode</description> <portlet-mode>preview</portlet-mode> </custom-portlet-mode>
Portlets can be cloned from the Jetspeed Toolbox. Cloning a portlet creates an actual copy (clone) of the portlet in the portlet registry. When cloning a portlet, the end user is presented with a dialog for entering different preference values for the cloned portlet. This new feature is meant to facilitate the creation of variations of portlets, without the need to cut and paste the definitions in the portlet.xml. A typical use case could be a Weather portlet as shown below. For each city, the end user could create cloned variations of the base Weather portlet using the Clone dialog. The variation is based on the preferences, for example changing the title and city. Note that you must always change the name of the portlet, or you will not be allowed to create a new portlet. Portlet names must be unique in a portlet application. Note that when redeploying a portlet application, portlet clones will not be deleted. Clones can also be created and deleted from the Portlet Application Manager
The Jetspeed Page Navigator enables end users to navigate over and manage their own spaces, pages and folders. Additionally, in the hands of an administrator, the entire site can be easily managed using the Jetspeed Navigation. The view of the navigator is separated into three sections:
The top two sections are really just menus, which can be customized. The menus are looked for in the current folder or spaces folder.metadata. If there isn't a menu definition, then the menu navigator will search up the folder tree to find a higher definition of a menu. For spaces, the default menus are defined with regular expressions:
<menu name="space-navigations" regexp="true" options="+/*/,+/*.psml" depth="-1"/> <menu name="space-links" regexp="true" options="+/*.link"/>
All menu options have a context menu. The context menus only appear when you hover near the menu option name, appearing as a down arrow. Folders only have one context menu: Document Ordering.
Document ordering allows you to change the order of menu options (pages) in the navigators menu. Pages items have four context menu options for managing pages:
Pages, Folders and Links can be Added to the current folder or space with the Add button at the bottom of the navigator. To add a page, give it a name, select a template, and press add.
Adding Folders and Links works the same as adding pages. The templates made available in the template option are configured in the portlet.xml of the j2-admin app
<portlet-preferences> <preference> <name>defaultTemplatePage</name> <value> /_template/new-user/min.psml </value> </preference> <preference> <name>templatePages</name> <value> /_template/new-user/min.psml /_template/new-user/default-page.psml </value> </preference> <!-- If the following pref is blank, then the default admin role and admin user is used. --> <preference> <name>spaceAdminRoles</name> <value></value> </preference> </portlet-preferences>
The templates can also be configured in the Portlet Application Manager
PSML was extended in version 2.2.1 to support many of the JetUI features. PSML Templates are a new feature allowing for toolbars and space navigators to appear across all pages without needing to declare the portlets and layouts for each and every page. Instead, fragments can be automatically merged with any page using page templates or fragment references.
Fragments had two new attributes added to support multi-user customizations of fragment properties. These two attributes are scope and scopeValue. The one scope supported is user, where the scopeValue is set to the name of the user. This allows for per user fragment customizations. Beware that if lots of users start customizing fragments, you might want to store your pages in the database and not the file system. Scope and scopeValue can be combined with any fragment property, including the new set of properties described below.
<fragment id="dp-22" type="portlet" name="j2-admin::ForgottenPasswordPortlet"> ... <property name="width" scope="user" scopeValue="dave" value="1121.0"></property> <property name="height" scope="user" scopeValue="dave" value="120.0"></property> <property name="state" scope="user" scopeValue="admin" value="detach"></property> </fragment>
New properties were added to support drag and drop, resizing, detaching, and docking. Here are some examples:
... <property name="y" value="300"></property> <property name="x" value="20"></property> <property name="state" value="detach"></property> ... <property name='toolbar' value='true'></property> <property name="state" scope="user" scopeValue="guest" value="closed"></property> <property name='class' value='jsRightToolbar'></property> <fragment id="jsToolbox" type="portlet" name="j2-admin::JetspeedToolbox"> <property name="row" value="0"></property> <property name="column" value="0"></property> <property name="state" value="normal"></property> <property name="tool" value="true"></property> </fragment> ...
property | values | description |
---|---|---|
state | normal,detach,closed | the window state of a fragment, either detached or attached (normal) or closed (for a user or set of users) |
toolbar | true,false | Is this fragment a toolbar |
toolbar | true,false | Is this fragment a tool in a toolbar? |
x | numeric screen value | The x position of a detached portlet |
y | numeric screen value | The y position of a detached portlet |
width | numeric screen value | The width of a resized, detached portlet |
height | numeric screen values | The height of a resized, detached portlet |
class | a CSS class name | The CSS style to apply to a given fragment |
To manually configure JetUI properties, edit the WEB-INF/conf/jetspeed.properties (or WEB-INF/conf/override.properties)
property | values | description |
---|---|---|
jetui.customization.method | ajax,server | To use JetUI customization engine, set to ajax. To turn on Jetspeed Classic rendering engine, set to server |
jetui.render.engine | CSRE,SSRE | Set the JetUI rendering engine to Client Side Rendering Engine or Server Side Rendering Engine. |
jetui.ajax.transport | json | Transport for all REST API calls made by the JetUI customization engine. Currently only JSON supported. |
jetui.render.template | /WEB-INF/jetui/yui/jetui.jsp | The out of the box JetUI rendering JSP template for rendering merged pages |
jetui.drag.mode | full | Only supports full, which drag entire window full size, drop on other portlets targets. Future support would drag a small icon. |
jetui.style.portlet | .portal-layout-cell | CSS style for JetUI portlet windows, also used to identify and find all portlets |
jetui.style.layout | .portal-layout-column | CSS style for JetUI layout windows, also used to identify and find all layout containers |
jetui.style.drag.handle | .PTitle | CSS style for JetUI title bars, also used as a handle of portlet windows to drag from |
pipeline.default | jetspeed-pipeline | set the default pipeline, although it is not necessary if you directly hit the JetUI pipeline by addressing all URLs with /jetspeed/ui instead of /jetspeed/portal |
A key component of the Jetspeed-2 portal engine is its request pipeline. All requests to the portal are ran through a set of Spring configurable pipelines, where each node in the pipeline flow is called a Valve. Pipelines are configured in the WEB-INF/assembly/pipelines.xml file. See the Pipelines Guide for more information. The JetUI rendering engine is configured through its own pipeline in pipelines.xml. Look for the configuration bean named jetui-pipeline.
<bean id="jetui-pipeline" class="org.apache.jetspeed.pipeline.JetspeedPipeline" init-method="initialize"> <meta key="j2:cat" value="default" /> <constructor-arg> <value>JetuiPipeline</value> </constructor-arg> <constructor-arg> <list> <ref bean="capabilityValve" /> <ref bean="portalURLValve" /> <ref bean="securityValve" /> ... <ref bean="jetuiValve" /> <ref bean="cleanUpValve" /> </list> </constructor-arg> </bean>
You may want the classic pipeline to be completely turned off. Out of the box, it is not. To get /jetspeed/portal to go to the JetUI pipeline, change the pipelines.xml pipeline-map bean to:
<bean id='pipeline-map' class='java.util.LinkedHashMap'> <meta key="j2:cat" value="default" /> <constructor-arg> <map> ... <entry key='/portal'> <value>jetui-pipeline</value> </entry>