Dynamic UI Extensions

Bloomreach Content uses a plugin architecture to enable a customizable user interface. The UI rendering is based on Apache Wicket. All standard UI components are implemented as plugins. The application provides a default configuration for these plugins. You can customize Bloomreach Content by editing this configuration, adding additional plugins, or developing your own plugins.

Customization by Configuration

Frontend plugins can extend the Wicket component model. Wicket HTML fragments may reference plugins that are not explicitly added in Java code. The repository configuration resolves these references.

Example

Consider a Wicket panel named RootPanel with three child panels: ListPanel, TreePanel, and SimplePanel. In a standard Wicket implementation, you add these child panels directly in the Java constructor:

public class RootPanel extends Panel { public RootPanel { add("list", new ListPanel()); add("tree", new TreePanel()); add("custom", new SimplePanel()); } }

If you want to replace SimplePanel with AdvancedPanel, you must update the code and recompile. The component hierarchy is fixed in Java.

Frontend plugins in Bloomreach Content use extension points instead. With extension points, you do not need to add plugins explicitly in code. The following example shows how to implement RootPanel as a RenderPlugin with extension points. (Prefixing extension point names with extension. is optional but improves configuration readability.)

public class RootPlugin extends RenderPlugin { public RootPlugin(IPluginContext context, IPluginConfig config) { super(context, config); addExtensionPoint("extension.list"); addExtensionPoint("extension.tree"); addExtensionPoint("extension.custom"); } }

The corresponding HTML file, RootPlugin.html, defines the extension points. RenderPlugin is a Wicket Panel.

<html xmlns:wicket="http://wicket.apache.org/"> <wicket:panel> <h1>RootPlugin</h1> <div wicket:id="extension.list">A list</div> <div wicket:id="extension.tree">A tree</div> <span wicket:id="extension.custom">A custom component</span> </wicket:panel> </html>

At this stage, the framework renders an EmptyPanel for each extension point because no plugins are connected yet. To connect a plugin to an extension point, add a property with the extension point name (such as extension.list, extension.tree, or extension.custom) and set its value to the wicket.id of the plugin to render.

Example configuration:

/rootPlugin: plugin.class: org.example.RootPlugin wicket.id: service.root extension.list: services.list extension.tree: services.tree extension.custom: services.custom /listPlugin: plugin.class: org.example.ListPlugin wicket.id: services.list /treePlugin: plugin.class: org.example.TreePlugin wicket.id: services.tree /customPlugin: plugin.class: org.example.SimplePlugin wicket.id: services.custom

To replace SimplePlugin with AdvancedPlugin, update the configuration only. No code changes or recompilation are required. This configuration is stored in repository nodes of primary type frontend:plugin. The plugin.class property specifies the Java class to instantiate.

You can further simplify plugin development by defining extension points in the configuration. In this approach, you do not need to write Java code for extension points. Add the extension points to the plugin's HTML file and use the wicket.extensions property to declare them.

Updated configuration example:

/rootPlugin: plugin.class: org.example.RootPlugin wicket.id: service.root wicket.extensions: [extension.list, extension.tree, extension.custom] extension.list: services.list extension.tree: services.tree extension.custom: services.custom /listPlugin: plugin.class: org.example.ListPlugin wicket.id: services.list /treePlugin: plugin.class: org.example.TreePlugin wicket.id: services.tree /customPlugin: plugin.class: org.example.SimplePlugin wicket.id: services.custom

With this configuration, the RootPlugin implementation is reduced to:

public class RootPlugin extends RenderPlugin { public RootPlugin(IPluginContext context, IPluginConfig config) { super(context, config); } }
Share Feedback
Page: /build/plugins/core-plugins/ui-extensions
Section: Build
Category *
Dynamic UI Extensions | Bloomreach Content Documentation