[6.x] Add custom dashboard widgets - #19319
Draft
riasvdv wants to merge 4 commits into
Draft
Conversation
Contributor
📚 Storybook previews@craftcms/ui — open Storybook No changed components detected in this Storybook. resources/js — open Storybook No changed components detected in this Storybook. |
Contributor
There was a problem hiding this comment.
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
CustomWidgetsdiscovery/parsing (frontmatter + Markdown body) and aCustomwidget 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\Customwith adefinitionId. - 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. |
…idgets # Conflicts: # src/Http/Controllers/Dashboard/DashboardController.php # src/Http/Controllers/Dashboard/WidgetsController.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds custom Dashboard widgets discovered from top-level
.mdfiles inresources/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, andsubtitlevalues through Twig, renders the body through Twig, and then converts the body from Markdown to HTML.Frontmatter
handlelabeliconnullmaxColspannull1to4.titlenullto hide the heading.subtitlenullshowByDefaultfalseProperty 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
handleis 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.