Add a Custom Report to the Content Reports Application

This Bloomreach Experience Manager feature requires a standard or premium license. Please contact Bloomreach for more information.

Introduction

Goal

Add a custom reporting plugin to the CMS.

Background

Insights > Content reports is a separate application in the CMS. It is similar to the Setup > System application and provides an overview of icons / portals with a breadcrumb behaviour. Each icon represents a configurable group of plugins which gets shown if an icon is clicked. The following example will describe a basic setup to add a custom portal group with one panel.

The Content reports application is based on Ext JS and Wicket, for further information have a look at the wicket-extjs project source code.

Create a PortalPanelPlugin

To create a Portal Panel which represents a group of plugins with an icon, title and description create the following class in the cms module of your project:

HelloWorldPortalPanel.java:

package com.onehippo.cms7.reports.plugins;

import org.apache.wicket.request.resource.ResourceReference;
import org.apache.wicket.request.resource.PackageResourceReference;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.hippoecm.frontend.plugin.IPluginContext;
import org.hippoecm.frontend.plugin.config.IPluginConfig;
import org.onehippo.cms7.reports.ReportsPerspective;
import org.onehippo.cms7.reports.plugins.PortalPanelPlugin;

public class HelloWorldPortalPanel extends PortalPanelPlugin {

    public static final String HELLO_WORLD_PANEL_SERVICE =
                                         "service.reports.helloworld";

    public HelloWorldPortalPanel(final IPluginContext context,
                                 final IPluginConfig config) {
        super(context, config);
    }

    @Override
    public ResourceReference getImage() {
        return new PackageResourceReference(HelloWorldPortalPanel.class,
                                     "hello-world-48.png");
    }

    @Override
    public IModel<String> getTitle() {
        return new Model<String>("Hello World");
    }

    @Override
    public IModel<String> getHelp() {
        return new Model<String>("Hello World Help");
    }

    @Override
    public String getPanelServiceId() {
        // the service id of the perspective this plugin should be rendered
        // in, here the reports perspective
        return ReportsPerspective.REPORTING_SERVICE;
    }

    @Override
    public String getPortalPanelServiceId() {
        // the service id of the portal panel, to associate plugins to
        // the panel
        return HELLO_WORLD_PANEL_SERVICE;
    }

}

The important functions which register and connect everything are getPanelServiceId() and getPortalPanelServiceId().

Note the reference to the image hello-world-48.png. Add a 48x48 icon (e.g. this copy of the 'buzz' icon) with that name to the cms module, under src/main/resources, in the package com.onehippo.cms7.reports.plugins.

Create an ExtPlugin

To render a plugin within the portal you must create another class (also in the cms module) which adds a Javascript resources header contribution and generates the Ext JS Javascript code to instantiate the class. It is a bridge between Wicket and Ext JS which initialises the config object passed to the constructor of the Ext JS javascript class. The annotation @ExtClass maps the java class to the custom javascript Ext JS class Hippo.Reports.HelloWorldPluginPanel which is defined in the file referenced by the head contribution Hippo.Reports.HelloWorldPluginPanel.js. @ExtProperty passes / converts class member variables to the javascript config object ( Hippo.Reports.HelloWorldPluginPanel.js).

HelloWorldPlugin.java:

package com.onehippo.cms7.reports.plugins;

import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
import org.apache.wicket.request.resource.JavaScriptResourceReference;
import org.hippoecm.frontend.plugin.IPluginContext;
import org.hippoecm.frontend.plugin.config.IPluginConfig;
import org.onehippo.cms7.reports.AbstractExtRenderPlugin;
import org.onehippo.cms7.reports.plugins.ReportPanel;
import org.wicketstuff.js.ext.ExtComponent;
import org.wicketstuff.js.ext.util.ExtClass;
import org.wicketstuff.js.ext.util.ExtProperty;

public class HelloWorldPlugin extends AbstractExtRenderPlugin {

    private static final JavaScriptResourceReference PANEL_JS =
        new JavaScriptResourceReference(HelloWorldPlugin.class, "Hippo.Reports.HelloWorldPluginPanel.js");

    private ExtComponent helloWorldPluginPanel;

    @ExtClass("Hippo.Reports.HelloWorldPluginPanel")
    public class HelloWorldPluginPanel extends ReportPanel {

        @ExtProperty
        public String helloWorldText;

        public HelloWorldPluginPanel(final IPluginContext context,
                                     final IPluginConfig config) {
            super(context, config);
            helloWorldText = config.getString("helloworld.text");
        }

        @Override
        public void renderHead(IHeaderResponse response) {
            super.renderHead(response);
            response.render(JavaScriptHeaderItem.forReference(PANEL_JS));
        }
    }

    public HelloWorldPlugin(IPluginContext context, IPluginConfig config) {
        super(context, config);
        helloWorldPluginPanel = new HelloWorldPluginPanel(context, config);
        add(helloWorldPluginPanel);
    }

    @Override
    public ExtComponent getExtComponent() {
        return helloWorldPluginPanel;
    }

}

For this example create a custom Ext JS class and simply display a property which was defined in the configuration of the plugin in the repository (see next XML code snippets for more details).

Create the following Javascript file in the cms module (in the same package as the Java classes):

Hippo.Reports.HelloWorldPluginPanel.js:

(function(Ext) {

    // define the namespace
    Ext.ns('Hippo.Reports');

    // custom javascript class which gets initialised due to the annotations
    // in HelloWorldPlugin.java
    Hippo.Reports.HelloWorldPluginPanel = Ext.extend(Hippo.Reports.Portlet, {

         // config.helloWorldText holds the value of the @ExtProperty annotated
         // helloWorldText class member variable
         constructor : function(config) {

            // set the Ext html panel property to render the hello world text
            // in the panel
            config = Ext.apply(config, { html : config.helloWorldText });

            // call the super constructor
            Hippo.Reports.HelloWorldPluginPanel.superclass.constructor.call(
                                                                this, config);
        }

    });

    // register the class as xtype
    Ext.reg('Hippo.Reports.HelloWorldPluginPanel',
             Hippo.Reports.HelloWorldPluginPanel);
})(Ext);

Configuration of the plugins

The reporting dashboard is configured under the path /hippo:configuration/hippo:frontend/cms/hippo-reports. For this example, you need two YAML source definitions which bootstrap the configuration for the two plugins. These YAML representations can be imported through the Console:

definitions:
  config:
    /hippo:configuration/hippo:frontend/cms/hippo-reports/hello-world-portal-panel:
      jcr:primaryType: frontend:plugin
      plugin.class: com.onehippo.cms7.reports.plugins.HelloWorldPortalPanel
definitions:
  config:
    /hippo:configuration/hippo:frontend/cms/hippo-reports/hello-world-plugin:
      jcr:primaryType: frontend:plugin
      background: true
      height: 600
      helloworld.text: Hello World!
      plugin.class: com.onehippo.cms7.reports.plugins.HelloWorldPlugin
      wicket.id: service.reports.helloworld
      width: 0.5

Important is the reference by the property wicket.id. It references the previous defined service string constant HELLO_WORLD_PANEL_SERVICE in HelloWorldPortalPanel.java to associate the plugin with the plugin HelloWorldPlugin.

Layout and appearance

The layout of the plugins is dynamic to the browser size and can be influenced with the properties width ( Double) and height ( Long). width is defined in relative percentage and height in absolute pixels. To give the plugin a light grey gradient background you can set the boolean property background.

Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?