Configuring admin menu items

Introduction

As of Preside 10.17.0, the main navigation sytem was updated to introduce a core concept of configured admin menu items.

These are implemented in the side bar navigation and in the System drop down menu in the top navigation. See Modifying the administrator left hand menu and Modifying the administrator system menu.

Config.cfc implementation

Each named menu item, e.g. "sitetree", must be specified in the settings.adminMenuItems struct in your Config.cfc file. An entry takes the following form:

settings.adminMenuItems.sitetree = {
    feature       = "sitetree"                                // optional feature flag. Only show menu item when feature is enabled
  , permissionKey = "sitetree.navigate"                       // optional admin perm key. Only show menu item if current user has access
  , activeChecks  = { handlerPatterns="^admin\.sitetree\.*" } // see 'Active checks' below
  , buildLinkArgs = { linkTo="sitetree" }                     // Structure of args to send to event.buildAdminLink
  , gotoKey       = "s"                                       // Optional global shortcut key for the nav item
  , icon          = "fa-sitemap"                              // Optional fontawesome icon
  , title         = "cms:sitetree"                            // Optional i18n uri for the title
  , subMenuItems  = [ "item1", "item2" ]                      // Optional array of child menu items (each referring to another menu item)
};

Reference

Key Default Description
feature empty Optional feature flag. Only show menu item when feature is enabled
permissionKey empty Optional admin permission key. Only show menu item if current user has access
activeChecks empty Optional struct describing common checks to make to decide whether or not the item is active in any given request
buildLinkArgs empty Structure of args to send to `event.buildAdminLink()`
gotoKey empty Optional global shortcut key for the nav item
icon admin.menuitem:{menuItemName}.iconClass Font awesome icon class name, or i18n URI that translates to one
title admin.menuitem:{menuItemName}.title Title of the menu item, or i18n URI that translates to the title
subMenuItems empty Optional array of child menu items (each referring to another menu item)

Active checks structure

Two keys can be used in the activeChecks structure to instruct the system to make common checks for the active state of the menu item: handlerPatterns and datamanagerObject.

handlerPatterns

Specify either a plain string regex pattern to match the current handler event, or supply an array of patterns. e.g.

settings.adminMenuItems.myItem = {
    // ...
    activeChecks  = { handlerPatterns="^admin\.myhandler\.myaction" }
}

// or
settings.adminMenuItems.myItem = {
    // ...
    activeChecks  = { handlerPatterns=[ "^admin\.myhandler\.myaction", "^admin\.anotherhandler\." ] }
}

datamanagerObject

Specify either a single object name (string), or array of object names. When any datamanager page using the specified object(s) is viewed, the item will be considered active. e.g.

settings.adminMenuItems.myItem = {
    // ...
    activeChecks  = { datamanagerObject="my_object" }
}

// or
settings.adminMenuItems.myItem = {
    // ...
    activeChecks  = { datamanagerObject=[ "my_object", "my_object_two" ] }
}

Extending with dynamic functionality

At times, you may wish to have more dynamic control over the behaviour of your items. In addition to any configuration set above, you may also create a convention based handler to extend the item's behaviour. Create the handler at /handlers/admin/layout/menuitem/{nameOfYourItem}.cfc. It can then implement any of the methods below:

component {

    /**
     * System will run this once in application life-time
     * to ascertain whether or not to include the menu item.
     * Useful for more complex feature combination checks.
     */
    private boolean function neverInclude( args={} ) {
        return false;
    }

    /**
     * Implement this method to run more complex logic
     * to decide whether or not the current user has
     * access to the menu item. 
     *
     */
    private boolean function includeForUser( args={} ) {
        return true;
    }

    /**
     * Implement this method to run more complex logic
     * to decide whether or not the item is active for
     * the current request
     *
     */
    private boolean function isActive( args={} ) {
        return false;
    }

    /**
     * Implement this method to run more complex
     * / dynamic logic for building the link to the item
     *
     */
    private string function buildLink( args={} ) {
        return "";
    }

    /**
     * Run this method to dynamically decorate
     * the item configuration structure (passed in as args)
     *
     */
    private void function prepare( args={} ) {
        var dynamicChildren = [ /* ... */ ];
        ArrayAppend( args.subMenuItems, dynamicChildren, true );
    }


}