silverstripeltd / betamask-bao
Betamask Admin Overlay (BAO)
Package info
github.com/silverstripeltd/betamask-feab
Type:silverstripe-vendormodule
pkg:composer/silverstripeltd/betamask-bao
Requires
- php: ^8.1
- silverstripe/admin: ^2.1
- silverstripe/siteconfig: ^5.1
- silverstripeltd/featureflag: dev-main
Requires (Dev)
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is not auto-updated.
Last update: 2026-11-14 09:49:49 UTC
README
Adds an admin tool bar, styled with betamask, to the front end of a Silverstripe CMS site. Each CMS user turns it on for themselves.
Requirements
- PHP ^8.3
- Silverstripe CMS 6.1+ (
silverstripe/admin^3.1,silverstripe/siteconfig^6.1) silverstripeltd/featureflag
Installation
Both packages are private, so add their repositories to your project's composer.json. Composer does
not read repositories from a dependency:
"repositories": [ { "type": "vcs", "url": "git@github.com:silverstripeltd/betamask-feab.git" }, { "type": "vcs", "url": "git@github.com:silverstripeltd/featureflag.git" } ]
composer require silverstripeltd/betamask-bao
Turning the bar on
- Go to
/admin/myprofile - Tick Admin tool bar in the features section and save
The bar only appears for users who have ticked it.
How it works
The page is rendered exactly as it is for any other visitor. For members with the bar turned on, two tags are then added to the HTML, and nothing else in the page changes:
- a stylesheet in
<head>that moves the page content down by the bar's height (60px, or 50px on phones) while the bar is expanded, so it starts below the bar instead of under it - a small loader script before
</body>
The loader shows the bar in an iframe that sits above the page:
- The bar is a separate document, so the site's CSS and scripts cannot change how it looks or behaves, and clicks on it never reach the site's own click handlers or analytics.
- The iframe lives in a closed shadow root, so site selectors and
querySelectorAll()never match it. - The bar sits in the browser's top layer (the popover API), above anything the site can stack,
whatever its
z-index,transformoroverflow. Browsers without popover support keep it fixed at the highestz-index.
The site's own fixed and sticky elements at the top of the page, such as a sticky header, are not
moved. The bar sits over them while expanded. Members can collapse the bar with the three-line button at its
start, or with Esc, to a small pull-tab at the top left of the page. The page then returns to its normal position, and the choice is
remembered in the betamask_bar_collapsed cookie.
The layout follows the Silverstripe CMS designs at three sizes. Desktop (1200px and wider) shows everything. Tablet (768px to 1199px) drops the site name. Below 992px, the profile menu shows the member's first name and "Site settings" becomes "Settings". Phones (below 768px) show a 50px bar of icon-only buttons and no version label.
Dropdown menus are never clipped: while one is open, the iframe grows to fit it, with a transparent background. A click outside the menu closes it.
A Draft (yellow) or Published (green) label before Edit page shows which version of the page is being
viewed. Clicking it reloads the page as the other version (?stage=Stage or ?stage=Live).
The bar is only added to top-level GET navigations to HTML pages. These are always left untouched:
fetch()/XHR calls, sub-resources, frames, and anything that does not accept HTML- responses that are not HTML pages: redirects, files, JSON, XML, and HTML fragments
- URLs with a file extension (
sitemap.xml,robots.txt, downloads) andassets/ - the CMS (
admin/),dev/, the Security login, logout and password pages, and the CMS preview panel
Pages that carry the bar are marked as uncacheable, as they are personalised. Pages for every other visitor are not changed in any way.
A site with a Content Security Policy needs 'self' allowed for scripts, styles and frames.
Configuration
SilverStripe\Betamask\Frontend\TopBar\TopBarUI: # Never show the bar under these URL prefixes (relative to the site root) disable_on_url: - 'shop/checkout/' SilverStripe\Betamask\Frontend\TopBar\TopBarRenderer: # Where the Silverstripe logo links to (opens in a new tab) logo_url: 'https://www.silverstripe.org/' # Label shown for each environment type; others show "uat" or "test" environments: dev: 'dev' live: 'prod'
Extending the bar
Menu items
Apply an extension to TopBarMenu and implement updateItems(). Items are keyed by id. The built-in
ids are available as constants: ITEM_EDIT, ITEM_SETTINGS, ITEM_HELP and ITEM_PROFILE.
use SilverStripe\Betamask\Frontend\TopBar\TopBarMenu; use SilverStripe\Core\Extension; class TopBarMenuExtension extends Extension { protected function updateItems(array &$items): void { // A dropdown $items['reports'] = [ 'label' => 'Reports', 'icon' => 'font-icon-chart-line', 'items' => [ ['label' => 'Broken links', 'link' => '/admin/reports/broken-links'], ['label' => 'Analytics', 'link' => 'https://analytics.example.com', 'target' => '_blank'], ], ]; // A link added to an existing dropdown $items[TopBarMenu::ITEM_HELP]['items'][] = ['label' => 'Style guide', 'link' => '/style-guide']; // Remove an item unset($items[TopBarMenu::ITEM_SETTINGS]); } }
SilverStripe\Betamask\Frontend\TopBar\TopBarMenu: extensions: - App\Extension\TopBarMenuExtension
The array order is the display order. Each item supports:
| Key | Description |
|---|---|
label |
Required. Visible text, and the item's accessible name. |
short_label |
Shorter text shown on narrow screens, e.g. Settings. |
link |
Makes the item a plain link instead of a dropdown. |
target |
Link target. Defaults to _top, the page; use _blank for a new tab. |
icon_url |
URL of a 22px icon image. |
mobile_icon_url |
Icon image for phones, where items show only their icon (34px). |
icon |
Admin font icon class, e.g. font-icon-chart-line, used when there is no icon_url. |
items |
Dropdown entries, each with label, link and optional target. |
heading |
HTML shown at the top of the dropdown. It is rendered as-is, so only pass trusted markup. |
css_modifier |
Modifier for the item's topbar__action--* class. |
Items without a label, and dropdown entries without a label or link, are dropped.
Turning the bar off for more requests
Apply an extension to TopBarUI and implement updateIsEnabled(bool &$enabled). getOwner()->getRequest()
gives you the request being considered.
Edit page link
The Edit page link uses the CMS edit link of the record returned by the page controller's
data(). Any controller can provide its own link instead by implementing getPageEditUrl(): string.
Development
nvm use # Node 20 yarn install yarn build # writes client/dist, which is committed yarn lint
Run the PHP tests from a project that has the module installed:
vendor/bin/phpunit vendor/silverstripeltd/betamask-bao/tests
