CMS Perspectives
Perspectives in Hippo CMS are the different screens provided by the UI to a user. Examples are the Content perspective in which documents, images and assets can be edited, the Admin perspective with management of users, groups, roles, etc. These are all different areas the user can navigate to and carry out different types of operations. The end user manual describes which perspectives are bundled with the default installation of Hippo CMS.
Creating a custom perspective
A custom perspective can show any type of information, interact with the content, load an external iframe, etc. Creating one requires at least the XML definition/configuration of the perspective and a Wicket plugin together with its HTML file, its resource bundle. Optionally, the perspective can include a CSS file for styling and an icon that will show up in the main menu on the left side of the CMS.
Example
Our example perspective will show an empty screen that shows the text "Hello world!". The example will use package 'com.example'.
First add the file cms/src/main/java/com/example/MyCustomPerspective.java:
package com.example; import javax.jcr.Session; import org.apache.wicket.markup.head.CssHeaderItem; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.request.resource.CssResourceReference; import org.apache.wicket.request.resource.ResourceReference; import org.hippoecm.frontend.plugin.IPluginContext; import org.hippoecm.frontend.plugin.config.IPluginConfig; import org.hippoecm.frontend.plugins.standards.perspective.Perspective; import org.hippoecm.frontend.session.UserSession; public class MyCustomPerspective extends Perspective { private static final ResourceReference PERSPECTIVE_CSS = new CssResourceReference(MyCustomPerspective.class, "MyCustomPerspective.css"); public MyCustomPerspective(IPluginContext context, IPluginConfig config) { super(context, config); setOutputMarkupId(true); Session session = UserSession.get().getJcrSession(); } @Override public void renderHead(final IHeaderResponse response) { response.render(CssHeaderItem.forReference(PERSPECTIVE_CSS)); } }
Next, add the Wicket markup file cms/src/main/resources/com/example/MyCustomPerspective.html:
<html xmlns:wicket="http://wicket.apache.org/"> <wicket:panel> <div id="my-custom-perspective"> Hello world! </div> </wicket:panel> </html>
The perspective's configurations need to be added to the repository. This can be done with an initialize item.
First, add the perspective's configuration in the file cms/src/main/resources/my-custom-perspective.xml:
<?xml version="1.0" encoding="UTF-8"?> <sv:node sv:name="myCustomPerspective" xmlns:sv="http://www.jcp.org/jcr/sv/1.0"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>frontend:plugin</sv:value> </sv:property> <sv:property sv:name="plugin.class" sv:type="String"> <sv:value>com.example.MyCustomPerspective</sv:value> </sv:property> <sv:property sv:name="wicket.id" sv:type="String"> <sv:value>service.tab</sv:value> </sv:property> </sv:node>
Next, add the bootstrap index file cms/src/main/resources/hippoecm-extension.xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <sv:node xmlns:sv="http://www.jcp.org/jcr/sv/1.0" sv:name="hippo:initialize"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>hippo:initializefolder</sv:value> </sv:property> <sv:node sv:name="myhippoproject-my-custom-perspective"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>hippo:initializeitem</sv:value> </sv:property> <sv:property sv:name="hippo:contentresource" sv:type="String"> <sv:value>my-custom-perspective.xml</sv:value> </sv:property> <sv:property sv:name="hippo:contentroot" sv:type="String"> <sv:value>/hippo:configuration/hippo:frontend/cms/cms-static</sv:value> </sv:property> <sv:property sv:name="hippo:sequence" sv:type="Double"> <sv:value>30000</sv:value> </sv:property> </sv:node> </sv:node>
The order of the perspectives in the CMS is determined by the order of their configuration nodes under /hippo:configuration/hippo:frontend/cms/cms-static. Change the order by adjusting the hippo:sequence number of the initialize item, or use the 'insert' and 'location' options of enhanced XML import to insert the node at the specific location relative to another node.
The title of the perspective will be loaded from a compile-time Java resource bundle. For now, we only add the key of the English title ('perspective-title') in the file cms/src/main/resources/com/example/MyCustomPerspective.properties:
perspective-title=My Custom Perspective
The perspective also needs an icon that will be displayed in the left side of the CMS. The icon should be an SVG that's rendered at 48x48 pixels. The icon should be placed in the same Java package as the perspective, and have the same name but in spinal-case instead of CamelCase. For the example, download this Hippo icon and save it as cms/src/main/resources/com/example/my-custom-perspective.svg.
Last, include the CSS file that is referenced in the Java class: cms/src/main/resources/com/example/MyCustomPerspective.css
#my-custom-perspective { font-size: 16px; font-weight: bold; }
Rebuild and start your project. The CMS should now contain a custom perspective that displays "Hello World!".
Lazy loaded perspective
Perspectives can use the CMS plugin framework to register plugins and use other plugins. The example perspective above does not register or use any plugins yet. But if it would, all its plugins would be instantiated directly when someone logs in to the CMS. That may slow down the initial page load of the CMS considerably.
Perspectives can also be loaded lazily. A lazy loaded perspective defers the instantiation of its plugins until it is activated for the first time (i.e. select in the UI). This strategy decreases the amount of time to instantiate the CMS UI after logging in. When your perspective performs expensive operations it may be worthwhile to make it lazy-loaded.
A perspective be made lazy loaded by including a string property cluster.name in its configuration node. That property contains the name of the a plugin cluster node below /hippo:configuration/hippo:frontend/cms. Only when the perspective is activated for the first time, the plugin cluster will be loaded.
Example
For example, the configuration of the lazy loading Reports perspective looks like this:
/hippo:configuration/hippo:frontend/cms/cms-static/reportsPerspective - cluster.name = hippo-reports - plugins.class = org.onehippo.cms7.reports.ReportsPerspective - wicket.id = service.tab
The cluster.name property refers to the plugin cluster node
/hippo:configuration/hippo:frontend/cms/hippo-reports
That plugin cluster will only be loaded when the Reports perspective is activated for the first time.