Skip to content

Menu Management

A menu is the smallest unit in Erupt's permission system. It is more than the left-hand navigation: an Erupt class, an external link, a custom page, a button and an API are all registered as "menus", then ticked per role in Role Management.

Generated Automatically

Each module declares its menus through initMenus(), and they are written to the database on first start (controlled by erupt.init-method-enum, see Configuration). For table / tree menus Erupt also generates child function button menus from @Erupt(power): add, edit, delete, view details, export, import. Whatever buttons a role ticks are the only ones that appear in the UI, and the backend checks the same values.

Your own business models can declare menus in code instead of entering them by hand, see Plugin Development with EruptModule.

Menu TypeType ValueDescription
TableErupt class name (case-insensitive)Table view
TreeErupt class name (case-insensitive)Tree view
FormErupt class name (case-insensitive)Opens straight into the form view
LinkA URLOpens inside the menu container (iframe)
Micro-frontend LinkA URLOpens in the micro-frontend container (2.2.0+). For targets that refuse framing via X-Frame-Options / frame-ancestors but allow cross-origin reads
New TabA URLOpens in a new browser tab
Current WindowA URLFull-page navigation in the current window
Page RouteRoute pathFrontend router hash
Full ScreenRoute pathHides navigation and sidebar, fills the screen
ButtonPermission stringControls button visibility, not shown in navigation
Interface NameAPI nameAPI permission string, used with @EruptMenuAuth
ReportReport codeRequires the erupt-report module
TemplateTemplate filename (under the tpl directory)Requires the erupt-tpl module

Both Micro-frontend Link and Link embed an external site and take a full URL as the type value. They differ in what the target site has to allow.

The micro frontend is not affected by the target's X-Frame-Options or frame-ancestors, because the remote page is never navigated to as a frame — the host fetches it. The price is that the target must allow cross-origin reads: the HTML and every static asset need CORS headers that permit your admin domain.

Link (the iframe route) is the opposite: no CORS needed, but any one of the headers below makes the browser refuse it, leaving a blank area or a broken-document icon:

X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'none'

This is the target server's policy and cannot be worked around from the frontend. The only fix is to have them allow frame-ancestors for your admin domain.

Fields

FieldDescription
NameText shown in navigation, i18n-aware
StatusOpen / Hidden / Disabled. A hidden menu is not listed in navigation but its permission still applies, useful for pages reached only by link
Parent MenuAny depth; navigation expands one level by default
OrderLower values sort first
IconA Font Awesome class such as fa fa-users. Reference: https://www.thinkcmf.com/font/search/index.html
CodeUnique key, read-only once generated. Module initialization uses it to decide whether a menu already exists
Custom ParamExtra parameter passed to the page, readable from TPL pages and the frontend

Gating UI Elements by Menu

A menu value can also act as a switch in business code. ViaMenuValueCtrl implements ExprBool.ExprHandler and shows a field or button only when the current user holds a given menu:

java
@RowOperation(
    title = "Approve",
    show = @ExprBool(exprHandler = ViaMenuValueCtrl.class, params = "audit_btn"),
    operationHandler = AuditHandler.class
)

params is the menu's type value. Create a menu of type "Button" with value audit_btn, and whichever roles receive it can see the button.

Menu permissions are loaded and cached at login. After changing menus or roles, users must log in again or press the refresh button in the navigation bar.

Contributors

The avatar of contributor named as YuePeng YuePeng
The avatar of contributor named as Claude Opus 5 (1M context) Claude Opus 5 (1M context)

Changelog

Released under the Apache-2.0 License.