Refactor package registry - #628
Merged
Merged
Conversation
Field config JS can refer to a third-party plugin class by name, e.g. `extraPlugins: [Tokens]`, to enable it without its toolbar button. Now that third-party packages are only imported when their buttons are in the toolbar, and via namespace imports, that reference would throw a ReferenceError. When a field's JS config mentions a third-party plugin by name, import its package with a bare named import and register its asset bundle, unless more than one package provides a plugin with that name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
i-just
approved these changes
Sep 28, 2026
i-just
left a comment
Contributor
There was a problem hiding this comment.
I tested it, and all looked good.
With the event removed from this, the user can simply use the methods that were mentioned in the README since v5 was released, which is great. And the plugin’s name doesn’t affect the load order anymore.
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.
I'm opening this because it's interesting, but it does touch more than #625 does.
Plugin::registerCkeditorPackage()now works regardless of plugin load order, frominit()or aCraft::$app->onInit()callback. CKEditor doesn't read the package list until it actually needs it, and any package registered after that is loaded immediately. With this change, the import map is built atView::EVENT_END_PAGE(#625 usesEVENT_BEGIN_PAGE; end page is the last point before the<head>gets written, so it also catches anything registered while the page renders, but either works).This takes things even further by also fixing some potential bugs where two packages could export a plugin with the same name. That used to generate duplicate imports, which would break all CKEditor instances. Third-party plugins are now referenced through namespace imports (
import * as __ckePackage0 from '…'). Field config JS can still refer to a third-party plugin by name (e.g.extraPlugins: [Tokens]), and that package gets imported for the field as long as the name is unique.This also only loads third-party packages that are active within the toolbar (plus packages with no toolbar items, no plugins, or that the field's config JS refers to by name).
A few smaller fixes came along for the ride:
[['cardInsert', 'cardEdit']]never matched the toolbar, so their plugins were always removed, and the toolbar builder threwMissing component: cardInsert,cardEdit. They work now.Asset recipes
Load for every field
Only side effects (the bundle is registered for every field)
A little of everything
Grouped buttons (any one of them in the toolbar loads the package)
CKEditor features
Potentially breaking changes
CkeditorAssetwill now have to callPlugin::registerCkeditorPackageBundles($view). This is already handled by CKEditor fields and field settings, so this is probably an edge case.['a', 'b']used to show up as one locked group in the toolbar builder, and now shows two separate items (which is whatBaseCkeditorPackageAssetdocuments). Use[['a', 'b']]to keep them grouped. Saved toolbars aren't affected.registerCkeditorPackage()that don't extendBaseCkeditorPackageAssetare no longer registered. That was never documented, but it did happen before.CkeditorConfig::getImportStatements()is deprecated.