Create a Custom Perspective

Overview

This page describes how to create a custom application—referred to as a "perspective"—in Bloomreach Content and add it to the navigation UI.

About Perspectives

A perspective is a distinct application within Bloomreach Content, accessible through the navigation UI. Examples include the Content perspective for editing documents and assets, and the Setup > System perspective for managing users, groups, and roles. Each perspective provides access to a specific area of functionality. For a list of default perspectives, see the end user manual.

Info:
If your custom perspective loads an external application via URL, you must add the application's domain to the Content Security Policy.

Create a Custom Perspective

A custom perspective can display any content, interact with the repository, or load external resources such as iframes. At minimum, you must provide repository configuration and a Wicket plugin class with its corresponding HTML file. Optionally, you can add a CSS file for custom styling. Custom perspectives appear in the navigation's Extensions menu.

Extensions menu showing My Custom Perspective navigation item

Example: Hello World Perspective

This example creates a perspective that displays "Hello world!" on an empty screen, using the package com.example.

1. Create the Java Class

Add the following file at 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)); } }

2. Create the Wicket Markup File

Add the following file at 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>

3. Add the CSS File

Add the CSS file referenced in the Java class at cms/src/main/resources/com/example/MyCustomPerspective.css:

#my-custom-perspective {
  font-size: 16px;
  font-weight: bold;
}

4. Build and Restart

Rebuild your project and restart the application.

5. Configure the Perspective in the Repository

Use the Console to add a new frontend:plugin node under /hippo:configuration/hippo:frontend/cms/cms-static. Configure the following properties:

  • Add the frontend:navigationitem mixin.

  • Set the required property frontend:appPath. This value appears as the last segment in the URL when the perspective is active. For example, if frontend:appPath is myapp and the CMS is deployed at https://cms.example.com, the perspective URL is https://cms.example.com/myapp.

  • Set the hipposys:userrole property. Assign a product-provided role (such as xm.cms.user) or a custom role from your project.

Example configuration:

/hippo:configuration/hippo:frontend/cms/cms-static/myCustomPerspective: jcr:primaryType: frontend:plugin jcr:mixinTypes: ['frontend:navigationitem'] frontend:appPath: my-custom-perspective hipposys:userrole: xm.cms.user plugin.class: com.example.MyCustomPerspective wicket.id: service.tab

Info:
Perspective Order
The order of perspectives in the Extensions menu matches the order of their configuration nodes under /hippo:configuration/hippo:frontend/cms/cms-static.

6. Add Translations

Add translation key-value pairs under /hippo:configuration/hippo:translations/hippo:navigation/navigationitem for each required language. The displayName key is mandatory. If it is missing, the navigation UI will not display the custom perspective.

Example translation configuration:

/hippo:configuration/hippo:translations/hippo:navigation/navigationitem: jcr:primaryType: hipposys:resourcebundles /displayName: jcr:primaryType: hipposys:resourcebundles /en: jcr:primaryType: hipposys:resourcebundle my-custom-perspective: My Custom Perspective

7. Verify

Log in to Bloomreach Content. The custom perspective should appear in the Extensions menu.

Lazy-Loaded Perspective

By default, all plugins for a perspective are instantiated when a user logs in to the CMS. This can slow down the initial page load, especially if the perspective registers or uses multiple plugins.

To improve performance, you can configure a perspective to load lazily. A lazy-loaded perspective defers plugin instantiation until the user selects the perspective in the UI for the first time. This approach is recommended if your perspective performs resource-intensive operations.

To enable lazy loading, add a cluster.name property to the perspective's configuration node. This property specifies the name of a plugin cluster node under /hippo:configuration/hippo:frontend/cms. The cluster is loaded only when the perspective is first activated.

Scope of lazy loading
The cluster.name property only defers instantiation of the plugins inside the referenced plugin cluster. It does not defer:

  • The perspective's own tab/shell. Every perspective node configured under cms-static is instantiated as soon as a user logs in, regardless of whether cluster.name is set.

  • Iframe loading, for iframe-based custom perspectives. If your perspective embeds an external application via an iframe, that iframe is created and its URL is requested at CMS login — independent of cluster.name. Expect the iframe URL to be requested immediately after login, even before an editor selects the perspective for the first time.

Example: Lazy-Loaded Reports Perspective

Configuration for a lazy-loaded perspective:

/hippo:configuration/hippo:frontend/cms/cms-static/reportsPerspective: jcr:primaryType: frontend:plugin jcr:mixinTypes: ['frontend:navigationitem'] cluster.name: hippo-reports frontend:appPath: content-reports hipposys:userrole: xm.report.user plugin.class: org.onehippo.cms7.reports.ReportsPerspective wicket.extension: [] wicket.id: service.tab

The cluster.name property points to the plugin cluster node:

/hippo:configuration/hippo:frontend/cms/hippo-reports

This cluster is loaded only when the Reports perspective is activated for the first time.

Note:
If plugins in your perspective's cluster expose services required by other parts of the CMS, those services will not be available until the perspective is loaded. To make such services available by default, move them to /hippo:configuration/hippo:frontend/cms/cms-services.

Share Feedback
Page: /build/editor-interface/cms-perspectives
Section: Build
Category *