nickjacobs / silverstripe-edit-links
Front-end edit badges for SilverStripe pages and Elemental blocks, linking editors straight to the CMS edit form. Auto-injects with no template changes.
Package info
github.com/nickjacobs/silverstripe-edit-links
Type:silverstripe-vendormodule
pkg:composer/nickjacobs/silverstripe-edit-links
Requires
- php: ^8.3
- silverstripe/cms: ^6.0
- silverstripe/framework: ^6.0
- silverstripe/siteconfig: ^6.0
- silverstripe/versioned: ^3.0
Requires (Dev)
None
Suggests
- dnadesign/silverstripe-elemental: Enables per-block edit badges and the CMS 'back to page' / preview buttons
- tractorcow/silverstripe-fluent: Edit links carry the locale being viewed, so editors land in the right one
Provides
None
Conflicts
None
Replaces
None
README
Front-end edit badges for SilverStripe pages and Elemental blocks. Editors browsing the live site see a small pencil badge on the page and on every block; hovering reveals the class name, record ID and title, and admins get a link straight to the CMS edit form.
By default the module auto-injects the badges into every HTML response, so no template changes are needed. A $EditLink template variable is available if you'd rather place them yourself.
Requirements
- SilverStripe Framework and CMS 6
dnadesign/silverstripe-elemental6 (optional, enables block badges and CMS buttons)tractorcow/silverstripe-fluent(optional, see Fluent)
Installation
composer require nickjacobs/silverstripe-edit-links
Run dev/build?flush=1, then go to Settings > Edit links in the CMS and tick the badges you want on. The tab is only shown to members with the settings_permission (ADMIN by default).
How it works
- A
SiteTreeextension captures the page being served. - After the page has rendered, an HTTP middleware builds a manifest: the page badge HTML plus one badge per Elemental block keyed by the block's anchor id, the same
id="$Anchor"Elemental writes on every holder. - It appends the manifest, the stylesheet and a small script before
</body>. - The script drops the page badge into
<body>and each block badge into its holder, addingposition: relativewhere needed.
Nothing is written to the response for visitors who can't see badges, and CMS preview requests are skipped.
Blocks are walked recursively, so nested areas (an element list, for example) get badges too. A block rendered without its holder, or with a custom holder that drops id="$Anchor", is simply skipped.
Manual placement
Set auto_inject: false and put $EditLink where you want the badge:
NickJacobs\EditLinks\EditLinkService: auto_inject: false
<%-- Page.ss --%> <body> $EditLink ... <%-- DNADesign/Elemental/Layout/ElementHolder.ss --%> <div class="element $SimpleClassName.LowerCase" id="$Anchor"> $Element $EditLink </div>
$EditLink renders nothing when badges are disabled or the visitor can't see them, and pulls in the stylesheet via Requirements when it does render. The badge is absolutely positioned; the stylesheet already makes an .element holder relative when it contains one.
Configuration
NickJacobs\EditLinks\EditLinkService: auto_inject: true # inject via middleware, no template edits view_permission: CMS_ACCESS_CMSMain # who sees the badge edit_permission: ADMIN # who sees the "edit" link inside it settings_permission: ADMIN # who sees Settings > Edit links show_public_in_dev: true # honour the SiteConfig "show to public" flag in dev/test show_titles: true # include the record Title in the badge open_in_new_tab: true # edit links open in a new tab cms_buttons: true # Back to page / View live / Preview draft on block edit forms carry_locale: true # append the viewed locale to edit links (Fluent only)
SiteConfig switches
| Field | Purpose |
|---|---|
PageEditLinkEnable |
Turn page badges on |
ElementEditLinkEnable |
Turn block badges on (Elemental only) |
ElementEditLinkShowPublic |
In dev or test mode, show badges to logged-out visitors. The edit link still requires edit_permission. |
Styling
Colours and sizing are CSS custom properties. Override them in your own stylesheet:
:root { --ss-edit-link-bg: #0ea5e9; --ss-edit-link-page-bg: #0369a1; --ss-edit-link-fg: #fff; --ss-edit-link-pill-bg: #fff; --ss-edit-link-pill-fg: #1f2937; --ss-edit-link-font-size: 11px; --ss-edit-link-offset: 12px; --ss-edit-link-z: 10; --ss-edit-link-page-z: 999; }
Extension hooks
EditLinkService::updateBadgeData(ArrayData $data, string $type, DataObject $record)to add fields to the badge template.EditLinkService::updateManifest(array &$manifest, SiteTree $page)to add or remove entries before injection.- Override the template at
templates/NickJacobs/EditLinks/EditLink.ssin your project.
Fluent
On a Fluent site, edit links carry the locale being viewed:
/admin/pages/edit/EditForm/196/field/ElementalArea/item/3563/edit?l=en_GB
This matters more than it looks. Fluent resolves the CMS locale from the query parameter first, then from a persisted cookie. Without the parameter, clicking a badge on a non-default locale opens whichever locale the editor last used in the CMS — usually the wrong one, and the record often will not resolve there at all. Worse, Fluent persists whatever it resolved, so an editor can carry on editing the wrong locale without an obvious signal.
The parameter name is read from Fluent's own query_param config rather than
hardcoded, and the locale is captured while the page is served, because Fluent
restores its state before the badges are injected.
Set carry_locale: false to turn this off.
Fluent is not a dependency. Without it installed, links are unchanged.
CMS buttons
With Elemental installed and cms_buttons on, a block's edit form in the CMS gains three actions: Back to page, View live and Preview draft. Set cms_buttons: false to drop them.
Development
The stylesheet is compiled from client/src/edit-links.scss; the built file is committed.
sass --no-source-map --style=compressed client/src/edit-links.scss client/dist/edit-links.css
Licence
BSD-3-Clause.