Skip to content

[6.x] Add custom dashboard widgets - #19319

Draft
riasvdv wants to merge 4 commits into
6.xfrom
rias/cms-1243-custom-widgets
Draft

[6.x] Add custom dashboard widgets#19319
riasvdv wants to merge 4 commits into
6.xfrom
rias/cms-1243-custom-widgets

Conversation

@riasvdv

@riasvdv riasvdv commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Description

Adds custom Dashboard widgets discovered from top-level .md files in resources/widgets/.

Widget files are trusted control panel Twig templates, and authored HTML is not sanitized. Twig continues to escape values interpolated into the Markdown body.

Creating a widget

Create a Markdown file such as resources/widgets/welcome.md:

---
handle: welcome
label: 'Welcome, {{ currentUser.friendlyName }}'
icon: hand-wave
maxColspan: 2
subtitle: Getting started
showByDefault: true
---

## Hello {{ currentUser.friendlyName }}

Welcome to your Craft CMS installation.

The frontmatter block is optional and must begin on the first line when present. Craft parses the frontmatter and renders the label, title, and subtitle values through Twig, renders the body through Twig, and then converts the body from Markdown to HTML.

Frontmatter

Property Type Default Description
handle string or null The filename A stable widget identifier matching Craft's standard handle format.
label string or null Humanized filename The label shown in the New widget menu. An empty rendered label falls back to the filename.
icon string or null null A system icon name, SVG path, or raw SVG markup.
maxColspan integer or null null The maximum widget width, from 1 to 4.
title string or null The rendered label The widget heading. Set it to null to hide the heading.
subtitle string or null null The widget subheading.
showByDefault boolean false Whether to add the widget when a user's Dashboard is initialized. Existing Dashboards are not changed.

Property names are case-sensitive. Unknown properties are ignored. Invalid supported values, malformed YAML, and duplicate handles prevent the Dashboard from loading so definition errors are visible immediately. Invalid icons retain the generated fallback icon and produce a warning.

Widget identity

When handle is present, Craft stores it as the widget's identity. The file can be renamed without affecting existing widgets, but changing or removing the handle creates a new widget identity.

Without a handle, Craft uses the filename as the identity. Renaming the file therefore creates a new widget identity. Adding a handle later has the same effect.

Handles must be unique case-insensitively. If a widget file is removed or its identity changes, existing widget records are preserved but hidden. Restoring a file with the same identity restores those widgets.

@linear-code

linear-code Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

CMS-1243

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

📚 Storybook previews

@craftcms/uiopen Storybook

No changed components detected in this Storybook.

resources/jsopen Storybook

No changed components detected in this Storybook.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new “Custom” Dashboard widget type that is discovered from top-level Markdown files in resources/widgets/, allowing admins to ship CP widgets as trusted Twig+Markdown templates. This integrates into the existing legacy Dashboard UI by treating each discovered widget definition as a selectable widget type while persisting only the server-resolved widget identity.

Changes:

  • Introduces CustomWidgets discovery/parsing (frontmatter + Markdown body) and a Custom widget implementation that renders frontmatter/body through Twig and the body through Markdown.
  • Updates Dashboard/Widget controller flows to support custom widget “types” in the add-widget menu and to persist custom widgets as Dashboard\Widgets\Custom with a definitionId.
  • Adds feature tests covering discovery, rendering, validation errors, duplicate handles, persistence, menu selectability, default widget initialization, and missing/renamed widget files.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/Feature/Dashboard/Widgets/CustomTest.php Adds end-to-end coverage for discovery, rendering, persistence, and dashboard behavior of custom widgets.
src/Http/Controllers/Dashboard/WidgetsController.php Accepts custom widget definition “types” when creating widgets; preserves custom widget settings on update.
src/Http/Controllers/Dashboard/InteractsWithWidgets.php Switches widget type/icon/name/maxColspan retrieval to instance methods to support per-definition values.
src/Http/Controllers/Dashboard/DashboardController.php Populates add-widget menu with discovered custom widget definitions and marks selected ones as unselectable.
src/Dashboard/Widgets/Widget.php Adds default implementations for new instance getters (type/icon/displayName/maxColspan).
src/Dashboard/Widgets/Custom.php Implements the custom widget rendering behavior driven by a definitionId.
src/Dashboard/Data/CustomWidgetDefinition.php Defines the parsed/validated widget definition and its stable identity + menu “type” string.
src/Dashboard/Dashboard.php Adds custom widgets to default dashboard initialization when showByDefault is set.
src/Dashboard/CustomWidgets.php Implements discovery + frontmatter parsing + duplicate-handle detection and lookup by id/type.
src/Dashboard/Contracts/WidgetInterface.php Extends the widget contract with new instance getter methods used by controllers.
CHANGELOG.md Documents the new Markdown-based custom dashboard widget support.

Comment thread src/Dashboard/CustomWidgets.php
Comment thread src/Dashboard/Contracts/WidgetInterface.php
riasvdv added 3 commits July 27, 2026 15:21
…idgets

# Conflicts:
#	src/Http/Controllers/Dashboard/DashboardController.php
#	src/Http/Controllers/Dashboard/WidgetsController.php
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants