heyday / silverstripe-menumanager
Allows complex menu management to be handled through the CMS when a simple tree structure is not enough.
Package info
github.com/WPP-Public/akqa-nz-silverstripe-menumanager
Type:silverstripe-vendormodule
pkg:composer/heyday/silverstripe-menumanager
Requires
Requires (Dev)
- phpunit/phpunit: ^11.5
- squizlabs/php_codesniffer: ^3.7.2
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-main
- 6.1.0
- 6.0.1
- 6.0.0
- 5.x-dev
- 5.0.3
- 5.0.2
- 5.0.1
- 5.0.0
- 4.x-dev
- 4.3.1
- 4.3.0
- 4.2.1
- 4.2.0
- 4.1.2
- 4.1.1
- 4.1.0
- 4.0.0
- 3.x-dev
- 3.4.0
- 3.3.0
- 3.2.1
- 3.2.0
- 3.1.0
- 3.0.6
- 3.0.5
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 3.0.0-alpha.1
- 3.0.0-alpha
- 2.2.2
- 2.2.1
- 2.2.0
- 2.1.3
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.6
- 2.0.5
- 2.0.4
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- 1.0.2
- 1.0.1
- 1.0.0
- dev-fix/menu-item-save
- dev-docs/admin-screenshot
- dev-fix/display-issues
This package is auto-updated.
Last update: 2026-09-22 23:18:00 UTC
README
The menu management module is for creating custom menu structures when the site tree hierarchy just won't do.
Installation
composer require heyday/silverstripe-menumanager
Run sake db:build afterwards.
Usage
Creating a MenuSet
Open the Menus section and choose Add menu, then fill in the Settings tab.
Publish the menu once you are happy with it.
A menu has two labels:
- Title is what editors see, in the menu picker and everywhere else in the CMS. It is free text and safe to change at any time.
- Name is the reference templates use, as in
$MenuSet('MainMenu'). Spaces are stripped from it on save so we recommendUpperCamelCase.
A new menu starts without a name, so the first thing to do on the Settings tab
is give it one. Menus listed under default_sets have a readonly name, because
templates and configuration refer to them by it. Other menus keep their name
editable, with a warning that changing it can break those references.
A menu listed under default_sets cannot be deleted either, because the site
depends on it. Its title can be changed.
Heyday\MenuManager\MenuSet: default_sets: - Main - Footer
Usage in templates
$MenuItems returns the top level of the menu.
<% loop $MenuSet('YourMenuName').MenuItems %> <a href="{$URL}" class="{$LinkingMode}">{$MenuTitle}</a> <% end_loop %>
For a nested menu, descend into $Children on each link:
<% loop $MenuSet('YourMenuName').MenuItems %> <a href="{$URL}" class="{$LinkingMode}">{$MenuTitle}</a> <% if $Children %> <ul> <% loop $Children %> <li><a href="{$URL}" class="{$LinkingMode}">{$MenuTitle}</a></li> <% end_loop %> </ul> <% end_if %> <% end_loop %>
To loop through all MenuSets and their items:
<% loop $MenuSets %> <% loop $MenuItems %> <a href="{$URL}" class="{$LinkingMode}">{$MenuTitle}</a> <% end_loop %> <% end_loop %>
Optionally you can also limit the number of MenuSets and MenuItems that are looped through.
The example below will fetch the top 4 MenuSets (as seen in Menu Management), and the top 5 MenuItems for each:
<% loop $MenuSets.Limit(4) %> <% loop $MenuItems.Limit(5) %> <a href="{$URL}" class="{$LinkingMode}">{$MenuTitle}</a> <% end_loop %> <% end_loop %>
Limiting how deep a menu goes
Menus can be nested three levels deep. A design often has less room than that,
such as a footer that only shows a heading and the links under it, so a menu can
set its own limit with max_menu_depth, keyed by the menu's name:
Heyday\MenuManager\MenuSet: max_menu_depth: FooterMenu: 2 FooterBottomMenu: 1
The depth counts top level links as 1, so:
1allows top level links only.2allows links nested under top level links, but the + is not offered on a second level link, and nothing can be dragged or moved there.4or more raises the limit above the default for that menu alone.
Heyday\MenuManager\TreeField\MenuItemTreeSource: max_depth: 3
Setting a limit does not change links that already sit deeper than it. They still show and render, but nothing more can be added below the limit, and they can only be moved somewhere that fits.
Drafts and publishing
Menus are versioned. Adding, editing, moving and reordering changes the draft only, and the tree marks anything not yet live: draft rows are italic and show an orange status dot, and the menu picker marks a menu that has never been published.
Publish menu sends the menu and all of its links live in one go. Unpublish takes it off the live site while keeping the draft. Deleting is immediate rather than staged: it archives the record, taking it off live too.
Previewing
Menus are previewable, so the site opens beside the tree in the CMS preview panel with draft and published toggles, the same as editing a page. A menu is not a page, so the preview opens the site's home page, which is where a menu is actually seen. Point it somewhere else per site:
Heyday\MenuManager\MenuSet: preview_url: 'https://example.com/about-us'
History and rollback
Each menu and each link has a History tab showing who changed it and when,
with the option to roll back to an earlier version. History needs the
silverstripe/versioned-admin module, which is installed as a dependency.
Anyone with MANAGE_MENU_SETS or MANAGE_MENU_ITEMS can see draft menus. That
is configured through non_live_permissions.
Disable creating Menu Sets in the CMS
Sometimes the defined default_sets are all the menu's a project needs. You can
disable the ability to create new Menu Sets in the CMS:
Heyday\MenuManager\MenuAdmin: enable_cms_create: false
Note: Non-default Menu Sets can still be deleted, to help tidy unwanted CMS content.
Enabling partial caching
Partial caching can be enabled with your menu to speed up rendering of your templates.
<% with $MenuSet('YourMenuName') %> <% cached 'YourMenuNameCacheKey', $LastEdited, $MenuItems.max('LastEdited'), $MenuItems.count %> <% if $MenuItems %> <nav> <% loop $MenuItems %> <a href="{$URL}" class="{$LinkingMode}"> $MenuTitle.XML </a> <% end_loop %> </nav> <% end_if %> <% end_cached %> <% end_with %>
Subsite Support
If you're using SilverStripe Subsites, you can make MenuManager subsite aware via applying an extension to the MenuSet.
app/_config/menus.yml
Heyday\MenuManager\MenuSet: create_menu_sets_per_subsite: true extensions: - Heyday\MenuManager\Extensions\MenuSubsiteExtension Heyday\MenuManager\MenuItem: extensions: - Heyday\MenuManager\Extensions\MenuSubsiteExtension
License
Menu Manager is licensed under an MIT license
