Repository navigation
Releases
6.0.0-rc.1
The first release for Silverstripe 6, and a ground-up rewrite. The toolbar is now built from components discovered by type: a module or project adds a menu, menu item, button or toggle by declaring a class, and removes one with enabled: false in YAML. The provider interfaces and the name-based disabled_* lists of 2.x are gone. The version jumps from 2.0.6 to 6.0.0 so the package major matches the Silverstripe major, the scheme wedevelopnl/silverstripe-grid uses.
Releases up to 2.0.6 (Silverstripe 4 and 5) predate this changelog. The 2.x line stays on main.
Upgrading
From 2.x, in order:
-
Require the release candidate explicitly.
composer require wedevelopnl/silverstripe-admintoolbar:^6.0@RC(or lower the project'sminimum-stability). It needs PHP ^8.3 and Silverstripe CMS ^6.0. -
Run
sake db:build --flush. Every class moved to a new namespace (Extensions\→Extension\,Controllers\→Controller\,Menus\→Menu\,Buttons\→Button\,Toggles\→Toggle\), so a stale manifest still names classes that no longer exist. TheMembercolumnsDisableAdminToolbarandAdminToolbarDefaultCollapsedare unchanged and keep their values. -
Replace
disabled_menus,disabled_menu_items,disabled_buttonsanddisabled_toggles. These lists onWeDevelop\AdminToolbar\AdminToolbarare no longer read, so a project that switched something off with them now shows it again, without an error. Setenabled: falseon the component's class instead:2.x name 6.x class Page(menu)WeDevelop\AdminToolbar\Menu\PageMenuUnpublishMenuItemWeDevelop\AdminToolbar\Menu\Page\UnpublishPageItemArchivePageWeDevelop\AdminToolbar\Menu\Page\ArchivePageItemUnpublishAndArchivePageWeDevelop\AdminToolbar\Menu\Page\UnpublishAndArchivePageItemMenu(CMS menu)WeDevelop\AdminToolbar\Menu\CMSMenuUser(menu)WeDevelop\AdminToolbar\Menu\UserMenuUsername/EditUserWeDevelop\AdminToolbar\Menu\User\UsernameItem/EditUserItemFlush CacheWeDevelop\AdminToolbar\Button\FlushCacheButtonQueries(button / toggle)WeDevelop\AdminToolbar\Button\QueriesButton/Toggle\QueriesToggleTiming(button / toggle)WeDevelop\AdminToolbar\Button\TimingButton/Toggle\TimingToggleEditPageandAddToCampaignhave no counterpart. See Changed and Removed. -
Port custom components to the component bases. A class implementing
AdminToolbarMenuProviderInterface,AdminToolbarMenuItemProviderInterface,AdminToolbarButtonProviderInterfaceorAdminToolbarToggleProviderInterfaceis no longer discovered. ExtendWeDevelop\AdminToolbar\Model\Menu,MenuItem,ButtonorToggleinstead. The README's "Adding a component from your module or project" section has worked examples. -
Check overridden templates. Templates moved with their classes (
Menus/Page/PageMenu.ss→Menu/PageMenu.ss,Models/AdminToolbarButton.ss→Model/Button.ss), and the stylesheet's Tailwind prefix changed fromss-at-tossat:. A theme override at an old path is silently ignored, and one copied from 2.x renders unstyled.
$AdminToolbar stays the template variable. It is now provided by ContentController rather than SiteTree, so it resolves in a page template's top scope. Inside a <% with %> or <% loop %> block, use $Top.AdminToolbar.
Members keep their collapsed/expanded state and their Queries/Timing toggles: the toolbar reads the same localStorage keys 2.x wrote.
Added
- A component model for extending the toolbar. Every concrete subclass of
Menu,MenuItem,ButtonorToggleis discovered and rendered, sorted byorder. Components are configured through config (title,icon,order,enabled,placement,menu,javascript,stylesheets) and behave through methods (isSupported()). They read the current page, member and request from aToolbarContextinstead of global state. A menu item names its menu by class, and a subclass of that menu keeps the item. A component renders with the template matching its class and falls back to its base's template. An Injector replacement for a built-in component is rendered once. - Menus can be placed at the end of the bar with
placement: end, to the right of the toggles. The User menu uses it. - The Page menu shows the page's publish state as a Published / Modified / Draft / Archived badge.
- Page actions report their outcome. A failed unpublish or archive shows the server's message inside the Page menu, falling back to a translated generic error when there is no response or it is not JSON. A successful one reloads the page.
- Dutch translations for every string the toolbar renders, including the page-action messages and the diagnostics labels. The Queries and Timing summaries (
{ms} ms ({count} queries)) were hard-coded English in 2.x.
Changed
- Page actions follow the member's own permissions on the page. Unpublish needs
canUnpublish, Archive and Unpublish-and-archive needcanDelete(Versioned 3 has nocanArchive), and an action is only offered when the page's state admits it. You can't unpublish a draft-only page, for example. The menu and the endpoint read the same rules fromPageActionItem, so the menu never offers an action the endpoint would refuse. - The page-action endpoint answers JSON
{message}for every outcome: 405 for a non-POST, 400 for a bad token or malformed body, 403 when not allowed, 404 for a missing page, 409 when the page changed since it was rendered, and 200 on success. Denials are logged as warnings with the reason, member, action and page ID. Messages are translated. - "Edit page" sits in the Page menu header rather than in the menu's item list, and appears only when the member can edit the page. 2.x always showed it.
- The "Last edited by" author links to their Security admin record only when the member may view the Security admin.
- The toolbar's CSS is built with Tailwind 4 under the
ssatprefix and ships as one stylesheet,client/dist/css/toolbar.css. Roboto and the Silverstripe icon font are self-hosted. Only the utilities the toolbar's own templates use are included, so a custom component template that needs other styles must ship them through itsstylesheetsconfig. - The toolbar's behaviour ships as one script,
client/dist/js/toolbar.js, instead of one file per button. The built-in components declare nojavascriptof their own. - Requirements: PHP ^8.3 (was ^8.1), and Silverstripe framework ^6.0, CMS ^6.0, admin ^3.0, versioned ^3.0 and vendor-plugin ^3.0.
Removed
- The provider interfaces (
AdminToolbar*ProviderInterface,AdminToolbarJavascriptProviderInterface,AdminToolbarStylesheetProviderInterface) and theAdminToolbar*Interfacemodel contracts. Use the component bases and theirjavascript/stylesheetsconfig. - The
disabled_menus,disabled_menu_items,disabled_buttonsanddisabled_togglesconfig. See Upgrading. - The Elemental Grid menu. It reached into
wedevelopnl/silverstripe-elemental-grid, an SS5 module. Its SS6 successorwedevelopnl/silverstripe-gridwill ship its own Grid menu as an ordinary toolbar component, so the toolbar no longer needs a release for every Grid change. - The "Add to campaign" menu item. It linked to
#and did nothing. URLTranslator. Components usegetCMSEditLink()and the CMS's own link helpers.
Fixed
- Page actions failed on a site installed in a subdirectory. The script posted to a hard-coded
/admintoolbaraction/pageAction. The endpoint is now built fromDirector::baseURL()and passed to the script through the template. - A page action that failed did nothing visible. Errors were only written to the browser console. See Added.
- Spacing between toolbar buttons and between menu entries. The CSS reset loaded after the utilities and zeroed every
space-x/space-ymargin, so buttons and dialog lists sat edge to edge. Labelled buttons now get 12px after their text while icon-only buttons stay square.
Security
- The 2.x page-action endpoint unpublished or archived any page for anyone holding a valid CSRF token.
admintoolbaraction/pageActionchecked the token and nothing else. It never checked that the requester was logged in, heldADMIN_TOOLBAR, or had permission to unpublish or delete that page, and it acted on whichever page ID the body named. The endpoint now requires a logged-in member withADMIN_TOOLBARand the page-level permission for the action (see Changed), accepts only POST, and logs every denial. 2.0.6 and earlier are affected.
Accessibility
- The collapse button reports its state through
aria-expanded/aria-controls. It and the toggles button carry anaria-label, and every dialog is labelled. Decorative icons arearia-hidden. - Every toolbar control is a
<button type="button">, so none of them submits a surrounding form. - Dialogs open as modal
<dialog>elements, close on Escape and on a backdrop click, and only react to triggers inside the toolbar, so a host site's own dialogs are left alone. - A page-action button is disabled while its request is in flight, and the flush-cache button is marked
aria-busy.
Developer Experience
- Docker test harness on Silverstripe 6 (PHP 8.3–8.5 matrix) driven by Task, with a committed Composer lock,
task verify-lockand a weekly relock pull request. - PHPUnit
unit,integrationandfunctionalsuites with a 90% coverage gate, PHPStan atlevel: maxwith no baseline, Rector, Infection (MSI ≥ 99) and class-leak. - TypeScript sources with Vitest (coverage gate), Biome,
tscand Stryker. Vite and the Tailwind CLI buildclient/dist, and CI fails when the committed build output drifts from the sources. - Playwright end-to-end suite in Chromium and Firefox, w...
2.0.6
2.0.5
What's Changed
- fix/early-return-when-disabled by @DRuiter in #14
- Introduce a new configuration option to disable individual menu items. by @erikfrerejean in #15
- Add phpstan & code cleanup by @erikfrerejean in #16
New Contributors
Full Changelog: 2.0.4...2.0.5
2.0.4
What's Changed
- Ensure that the safelist is actually applied. by @erikfrerejean in #13
Full Changelog: 2.0.3...2.0.4
2.0.3
2.0.2
What's Changed
- Correct variable by @erikfrerejean in #9
- Update npm dependencies. by @erikfrerejean in #11
- Correct the elemental grid check. by @erikfrerejean in #10
Full Changelog: 2.0.1...2.0.2
2.0.1
What's Changed
- Feature/development container by @erikfrerejean in #8
- Bring back the tailwind preflight. by @erikfrerejean in #7
New Contributors
- @erikfrerejean made their first contribution in #8
Full Changelog: 2.0.0...2.0.1
2.0.0
Version 2 launches a completely new version of the Admin Toolbar with support for ElementalGrid