Understanding Gadget URI: Is a Fragment Project Mandatory?

In the world of iDempiere ERP development, creating custom Dashboard Gadgets is a powerful way to enhance user experience. However, developers often hit a wall when their Gadget URIs fail to resolve. A common question arises: “Is it mandatory to use a fragment project to invoke Dashboard Content via Gadget URI?”

The short answer is: Yes, effectively. In this post, we’ll dive into the technical “why” and the best practices for implementation.


The Challenge: Why Your Standard Bundle Fails

When defining a Gadget URI, developers often attempt to reference a ZUL file inside a standard OSGi bundle. However, iDempiere’s UI is powered by the ZK Framework, which utilizes specific resource loading logic.

1. The ~./ Prefix and the Web Context Root

In iDempiere, the ~./ prefix in a URI refers to the Web Context Root of the running application—specifically the org.adempiere.ui.zk bundle.

  • Standard Bundles (Isolated): A standard OSGi bundle is isolated by design. Its internal resources (like .zul files) are not automatically exposed to the web context of the ZK UI bundle. If you point a URI to ~./your.bundle.symbolic.name/my_gadget.zul, the Host bundle will look within its own context, fail to find the file, and return a 404 error.
  • Fragment Bundles (Merged): When you create a Fragment Bundle and attach it to org.adempiere.ui.zk (the Host), its resources—such as those located in the theme/ folder—are effectively merged into the Host’s classpath. This makes them accessible as if they were part of the core UI bundle.

Can You Implement Gadgets Without a Fragment?

Technically, it is possible, but it is rarely recommended for standard enterprise environments.

  1. Web Application Bundles (WAB): You could register your bundle as a separate WAB or use an HttpContext service to expose resources via a specific alias.
  2. The Drawback: Dashboard Gadgets are designed to run within the main iDempiere UI session. Loading a ZUL from a completely separate web context often leads to broken session states, authentication issues, and inconsistent theming.

Step-by-Step Recommendation

For a stable and maintainable ZUL-based Gadget implementation, follow these guidelines:

Step 1: Use a Fragment Project

Always create a Fragment Project and set the Host Plug-in to org.adempiere.ui.zk.

Step 2: Organize Your Directory

Place your files within the fragment, following a structure like:

your.fragment.project/theme/default/zul/dashboard/my_custom_gadget.zul

Step 3: Correct URI Syntax

When registering the Gadget in the iDempiere Window “Dashboard Content”, use the absolute path starting with /.

Recommended Syntax:

Plaintext

/theme/default/zul/dashboard/my_custom_gadget.zul

Note: While ~./ is used for Classpath Web Resources, using the direct absolute path / within a Fragment is the proven method for resource resolution in the iDempiere Dashboard.


Verification Results

Based on our technical testing, here is how different configurations behave:

ConfigurationURI PatternResultReason
Standard Bundle/my_path/file.zulFailIsolated Context
Fragment Project~./theme/.../file.zulFailIncorrect mapping for this context
Fragment Project/theme/.../file.zulSUCCESSResources merged into Host Root

To implement the solution discussed, your Fragment Project must have a correctly configured MANIFEST.MF file. This file tells the OSGi container to “attach” your resources to the main iDempiere ZK web bundle.

Here is the template for the MANIFEST.MF file, specifically tailored for an iDempiere environment:

MANIFEST.MF Configuration

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: iDempiere Custom Dashboard Gadgets Fragment
Bundle-SymbolicName: com.yourcompany.ui.zk.fragment;singleton:=true
Bundle-Version: 1.0.0.qualifier
Fragment-Host: org.adempiere.ui.zk;bundle-version="[11.0.0,12.0.0)"
Bundle-Vendor: Your Company
Bundle-RequiredExecutionEnvironment: JavaSE-17

Key Attributes Breakdown

  • Bundle-SymbolicName: A unique ID for your fragment. It is good practice to include .fragment in the name to distinguish it from standard bundles.
  • Fragment-Host: This is the most critical line. It specifies org.adempiere.ui.zk as the host.
    • Note: The bundle-version range [11.0.0,12.0.0) ensures compatibility with iDempiere 11 (adjust this if you are using a different version like iDempiere 12).
  • singleton:=true: Prevents multiple versions of this specific fragment from being active at the same time, which is standard for UI customizations.

Directory Structure Requirement

For the /theme/... URI to resolve correctly, ensure your project folder structure looks exactly like this:

com.yourcompany.ui.zk.fragment/
├── META-INF/
│   └── MANIFEST.MF
└── theme/
    └── default/              <-- or your custom theme name
        └── zul/
            └── dashboard/
                └── my_gadget.zul

Summary

To ensure your iDempiere Gadgets work seamlessly with the existing UI, stick to Fragment Projects. It aligns with the OSGi architecture used by iDempiere and ensures that the ZK engine can resolve your resources without complex workarounds.

Reference

iDempiere Gadget

By Ray Lee (System Analyst)

iDempeire ERP Contributor, 經濟部中小企業處財務管理顧問 李寶瑞

Leave a Reply

Your email address will not be published. Required fields are marked *