Search by

micschk / silverstripe-cmstweaks

micschk

This package is abandoned and no longer maintained. The author suggests using the restruct/silverstripe-admintweaks package instead.

Various admin tweaks & enhancements

Package info

github.com/restruct/silverstripe-admintweaks

Language:SCSS

Type:silverstripe-vendormodule

pkg:composer/micschk/silverstripe-cmstweaks

Statistics

Installs: 24

Dependents: 0

Suggesters: 0

Stars: 2

Open Issues: 10

4.1.0 2026-09-22 14:27 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-control class 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.graphqlGenerates: 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 MigrateFileTaskSS5 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

License

BSD-3-Clause