micschk / silverstripe-cmstweaks
Various admin tweaks & enhancements
Package info
github.com/restruct/silverstripe-admintweaks
Language:SCSS
Type:silverstripe-vendormodule
pkg:composer/micschk/silverstripe-cmstweaks
Requires
- php: ^8.3
- guzzlehttp/guzzle: ^7.0
- silverstripe/framework: ^6
- silverstripe/vendor-plugin: ^3
Requires (Dev)
Suggests
- axllent/silverstripe-cms-tweaks: Some complemental tweaks by Axllent
- restruct/silverstripe-login-branding: Reduce Silverstripe branding of the admin login and make it easily configurable
- symbiote/silverstripe-grouped-cms-menu: Group CMS menu items into nested lists
- wedevelopnl/silverstripe-webp-images: WEBP image support (output resized jpeg/png images as webp, GD with WEBP required)
Provides
None
Conflicts
None
Replaces
- micschk/silverstripe-cmstweaks: 1.*
- restruct/silverstripe-cmstweaks: *
- dev-main
- 4.1.0
- 4.0.2
- 4.0.1
- 4.0.0
- 3.x-dev
- 3.20.8
- 3.20.7
- 3.20.6
- 3.20.5
- 3.20.4
- 3.20.3
- 3.20.2
- 3.20.1
- 3.20.0
- 3.19.0
- 3.18.0
- 3.17.1
- 3.17.0
- 3.16.0
- 3.15.0
- 3.14.0
- 3.13.0
- 3.12.0
- 3.11.1
- 3.11.0
- 3.10.0
- 3.9.0
- 3.8.1
- 3.8.0
- 3.7.1
- 3.7.0
- 3.6.3
- 3.6.2
- 3.6.1
- 3.6.0
- 3.5.0
- 3.4.2
- 3.4.1
- 3.4.0
- 3.3.2
- 3.3.1
- 3.3.0
- 3.2.0
- 3.1.0
- 3.0.x-dev
- 3.0.9
- 3.0.8
- 3.0.7
- 3.0.6
- 3.0.5
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- v2.x-dev
- 2.4.0
- 2.3.3
- 2.3.2
- 2.3.1
- 2.2.16
- 2.2.15
- 2.2.14
- 2.2.13
- 2.2.12
- 2.2.11
- 2.2.10
- 2.2.9
- 2.2.8
- 2.2.7
- 2.2.6
- 2.2.5
- 2.2.4
- 2.2.3
- 2.2.2
- 2.2.1
- 2.2
- 2.1.15
- 2.1.14
- 2.1.13
- 2.1.12
- 2.1.11
- 2.1.10
- 2.1.9
- 2.1.8
- 2.1.7
- 2.1.6
- 2.1.5
- 2.1.4
- 2.1.3
- 1.2
- 1.1
- 1.0
- dev-docs/error-email-env
- dev-archive/ss6-attempt-2025-10
- dev-main-ss3
This package is auto-updated.
Last update: 2026-09-22 15:34:59 UTC
README
A portable toolkit of admin UI enhancements, form field utilities, template helpers, and development conveniences for SilverStripe projects.
Namespace: Restruct\Silverstripe\AdminTweaks
| Module line | Silverstripe | PHP | Status |
|---|---|---|---|
^4 (branch main) |
6.x | ^8.3 |
active development |
^3 (branch v3) |
4.13+, 5.x | ^7.4 | ^8 |
security and bug fixes until Silverstripe 5 EOL (April 2027) |
Installation
composer require restruct/silverstripe-admintweaks:^4 # Silverstripe 6 composer require restruct/silverstripe-admintweaks:^3 # Silverstripe 4 / 5
Upgrading from 3.x? See UPGRADING.md - the CMS menu behaviour and the task invocations both changed.
Quick Start
Most features are opt-in via configuration. The module provides sensible defaults for:
- Secure session cookies
- GDPR-compliant UserDefinedForm (no server storage)
- Higher image quality defaults
- 24-hour default cache, 1-hour app cache
Features Overview
| Category | Features | Documentation |
|---|---|---|
| Admin UI | Page icons, Bootstrap Icon classes, menu grouping, permission badges | Icons |
| Form Fields | CopyTextField, MultivalueSortField, Bootstrap styling | Form Fields |
| GridField | Editable+orderable configs, versioned ordering | GridField |
| Templates | 30+ helper methods, iterators, image placeholders | Template Helpers |
| SiteConfig | Contact info, social media, theme settings, raw HTML | SiteConfig |
| Caching | HTTP request caching, JSON/JSON-LD parsing | Caching & Helpers |
| Email & Logging | SMTP config, error email reports | Email & Logging |
| QueuedJobs | Throttled broken job notifications, scheduled method calls | QueuedJobs |
Feature Highlights
Admin UI Enhancements
- Page Icons - Stylish icons for common page types using Bootstrap Icons (FA optional)
- Bootstrap Icon Classes - Standard
bi bi-*classes mirroring.font-icon-*pattern (CDN-compatible) - Menu Grouping - Groups admin sections under "Advanced" (requires
symbiote/silverstripe-grouped-cms-menu) - Permission Badges - Shows permission codes in Security admin
- Checkbox Fixes - Proper handling of unchecked checkboxes in editable GridFields
- Search-popover fixes - GridField 'Search options' popover: checkboxset/optionset holders no
longer collapse/overlap when a
form-controlclass leaks onto the field holder (eg from project code that decorates scaffolded search fields for front-end reuse), and long option lists scroll within the popover (automatic, CSS-only)
Per-ModelAdmin Tweaks (opt-in via config)
ModelAdminExtension is registered on ModelAdmin; enable per subclass (or project-wide via
yml on SilverStripe\Admin\ModelAdmin, with per-subclass overrides):
class ProductAdmin extends ModelAdmin { // Open the GridField search bar on load instead of hiding it behind the magnifier icon private static bool $auto_expand_gridfield_search = true; // Hide the framework-scaffolded Export to CSV / Print / Import CSV buttons // (the scaffolded export just dumps summary_fields; the default CsvBulkLoader // import is a data-integrity risk on synced/managed models) private static bool $hide_scaffolded_csv_buttons = true; }
// Add Bootstrap icon to a button FormAction::create('add', 'Add Item')->addExtraClass('bi bi-plus-circle');
Form Fields
- CopyTextField - Read-only field with copy-to-clipboard button
- MultivalueSortField - Sortable multi-value field
- Bootstrap Styling - Auto-adds Bootstrap classes to form fields (opt-in)
CopyTextField::create('ApiKey', 'API Key', $apiKey) ->setButtonLabel('Copy') ->setShowAlert(true);
GridField Configurations
// Inline editing with drag-drop ordering $config = GridFieldConfigs::editable_orderable(); // Filterable, orderable with record editor $config = GridFieldConfigs::filterable_orderable_recordeditor();
Template Helpers
<!-- Environment checks --> <% if $IsDev %>Debug mode<% end_if %> <!-- Image placeholder SVG --> <% include ImagePlaceholder W=180, H=50, Label='logo' %> <!-- Theme resource URL --> <video src="{$themeDirResourceURL('my-theme')}/video.mp4"></video> <!-- Extra iterators --> <% loop $Items %> <div class="col-{$GroupSize}-of-4">$Title</div> <% end_loop %>
Cached HTTP Requests
use Restruct\Silverstripe\AdminTweaks\Helpers\CacheHelpers; // Cached JSON API request (1 hour TTL) $data = CacheHelpers::cached_json_request('https://api.example.com/data', 'GET', [], 3600); // Extract JSON-LD from a webpage $jsonLd = CacheHelpers::cached_jsonLD_request('https://example.com/product');
QueuedJobs Enhancements
Scheduled Method Calls
use Restruct\Silverstripe\AdminTweaks\Jobs\ScheduledMethodCall; // Schedule a method call ScheduledMethodCall::schedule( MyClass::class, 'myMethod', ['arg1', 'arg2'], '+1 hour' );
Cleanup Broken Jobs Task
Quickly delete all broken queued jobs:
vendor/bin/sake tasks:cleanup-broken-jobs
Configuration
Email & SMTP (via .env)
APP_SYSTEM_EMAIL_SENDER="My App" APP_SYSTEM_EMAIL_ADDRESS="noreply@example.com" APP_SMTP_HOST="smtp.mailgun.org" APP_SMTP_PORT="587" APP_SMTP_ENCRYPTION="tls" APP_SMTP_USERNAME="postmaster@mg.example.com" APP_SMTP_PASSWORD="secret" # Error email logging (omit on dev/test to disable) APP_LOG_MAIL_RECIPIENT="admin@example.com" APP_LOG_MAIL_SUBJECT="Error on MyApp" APP_LOG_MAIL_SENDER="noreply@example.com" APP_LOG_MAIL_LEVEL="error"
SiteConfig Extension (opt-in)
SilverStripe\SiteConfig\SiteConfig: extensions: - Restruct\Silverstripe\AdminTweaks\Extensions\SiteConfigExtension enable_contact_social_media_fields: true enable_raw_head_body_fields: true enable_browser_color_theme_field: true
Bootstrap Form Classes (opt-in)
SilverStripe\Forms\FormField: extensions: - Restruct\Silverstripe\AdminTweaks\Extensions\FormFieldBootstrapExtension
Optional Module Integration
The module enhances functionality when these modules are installed:
| Module | Enhancement |
|---|---|
symbiote/silverstripe-grouped-cms-menu |
Groups admin sections under "Advanced" |
symbiote/silverstripe-queuedjobs |
Enables ScheduledMethodCall |
wilr/silverstripe-googlesitemaps |
Auto-activates sitemap generation |
silverstripe/mimevalidator |
Auto-activates MIME upload validation |
wedevelopnl/silverstripe-webp-images |
Activates WEBP format support |
restruct/silverstripe-shortcodable |
Registers CurrentYear/FeaturedImage shortcodes |
Traits
EnforceCMSPermission
Require CMS access for DataObject CRUD operations:
use Restruct\Silverstripe\AdminTweaks\Traits\EnforceCMSPermission; class MyDataObject extends DataObject { use EnforceCMSPermission; }
Default Behaviors
These are applied automatically:
Session.cookie_secure: true- Secure session cookies- UserDefinedForm submissions disabled by default (GDPR)
- Higher image quality (90% JPEG, 8 PNG compression)
- URL segment character replacements (umlauts, special chars)
Hiding the Reports and Campaigns CMS sections is opt-in since 4.1 (#54), and applied at
runtime so no After: ordering is needed to override it:
SilverStripe\Admin\LeftAndMain: hide_rarely_used_menu_sections: true
SS3/SS4 → SS5 migration repair tasks
Three BuildTasks that fix asset artifacts left behind by a migration to SS5. All are dry-run by
default — pass --apply to write. Run them in this order:
| # | Task | Fixes |
|---|---|---|
| 1 | sake tasks:fix-folder-filefilename |
/admin/assets dies with HashFileIDHelper::buildFileID requires an $hash value. Folder rows must have an EMPTY FileFilename (a folder derives its path from the parent chain); a populated value makes the folder's visibility lookup build a file ID with no hash. Also reports empty-FileHash File rows, which trip the same exception. |
| 2 | sake tasks:fix-misclassified-images |
Image files carried over with ClassName = File instead of Image. Blank tiles in the asset-admin grid — but more importantly, a has_one Image relation pointing at such a record renders nothing on the front end, because Fill()/FitMax()/ScaleWidth() don't exist on File. Resolves the target class via File::get_class_for_file_extension(), so .svg correctly becomes your registered SVG image class rather than Image. |
| 3 | sake tasks:generate-cms-thumbnails |
Blank tiles in the asset-admin file grid. The grid is served by GraphQL and asset-admin deliberately injects a non-generating thumbnail generator (ThumbnailGenerator.graphql → Generates: false), so it emits the __FitMax[...] URL but never creates the variant. Normal uploads generate variants on save; migrated files never went through SS5, so their variants don't exist and the <img> 404s. SS4 ran ImageThumbnailHelper inside MigrateFileTask — SS5 removed the task but kept the helper. This runs it. |
Order matters: (2) before (3), because the thumbnail helper skips anything whose getIsImage() is
false — a file still stuck on ClassName = File would be passed over.
Prerequisite for (3): the files must actually be migrated (a populated FileHash). On a database
where FileHash is empty there are no stored bytes to make a thumbnail from, and the task will
correctly report that it generated nothing.
Task (3) requires silverstripe/asset-admin; it hides itself if that isn't installed.
Building Assets
cd _dev/admintweaks npm install npm run dev # Development build npm run production # Production build npm run watch # Watch mode
Detailed Documentation
- Icons & Bootstrap Icon Classes
- Form Fields
- GridField Configurations
- Template Helpers
- SiteConfig Extension
- Caching & General Helpers
- Email & Logging Configuration
License
BSD-3-Clause