amjadiqbal / blockcraft-plugin
The modern TipTap block editor & document builder for October CMS.
Package info
github.com/amjadiqbal/oc-blockcraft-plugin
Type:october-plugin
pkg:composer/amjadiqbal/blockcraft-plugin
Requires
- php: >=8.2
- composer/installers: ^1.0 || ^2.0
- october/rain: >=4.2
Requires (Dev)
- phpunit/phpunit: ^10.0 || ^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
A FormWidget (blockcraft) that replaces October's native Froala
richeditor with a Vue 3 + TipTap block editor -
clean HTML or structured JSON output, native Media Manager integration, and
stable behavior inside nested Tailor/FormController repeaters.
Why
October's built-in rich text editor ships a pinned, several-major-versions- old Froala build, has limited toolbar customization, and has documented breakage when combined with Tailor repeater fields. BlockCraft is a drop-in-shaped alternative: a real Vue 3 SFC built on TipTap's ProseMirror foundation, with server-side sanitization independent of anything configured in the browser.
Requirements
- October CMS 4.2+ (needs the Vue 3 / native ESM backend)
- PHP 8.2+
Installation
composer require amjadiqbal/blockcraft-plugin
(Composer package name ends in -plugin per October's own naming
convention; it still installs at plugins/amjadiqbal/blockcraft.)
Usage
# fields.yaml body: label: Body type: blockcraft outputFormat: html # or 'json' for a structured TipTap document height: 400px
Options
| Option | Type | Default | Description |
|---|---|---|---|
outputFormat |
html | json |
html |
Persisted shape of the field's value. |
height |
string | 400px |
CSS height of the editor's content area. |
buttons |
array | null | null (full default toolbar) |
Restrict visible toolbar buttons - see the full list in formwidgets/BlockCraft.php's docblock. |
readOnly |
bool | false |
Renders the content non-editable. |
outputFormat: json stores TipTap's own document schema
({type: 'doc', content: [...]}) rather than an HTML string - useful when
your frontend wants to render content itself instead of trusting stored
markup, or when you want a stable structure for programmatic transforms.
Media Manager
Clicking the toolbar's Image button launches October's real, built-in Media
Manager (oc.mediaManager.popup) when the current backend user has
media.library access - no extra setup needed, no custom AJAX handler on
BlockCraft's side. Selected images can be aligned left/center/right from the
toolbar once selected in the editor.
Sanitization
Both output modes are sanitized server-side, independent of anything the browser sent:
htmlmode:classes/HtmlSanitizer.phpstrips any tag/attribute outside an explicit allow-list (matching BlockCraft's own extension set - nothing the editor can't already produce), stripsjavascript:/data:URIs, and forcesrel="noopener noreferrer"ontarget="_blank"links.jsonmode:classes/JsonSanitizer.phpvalidates the decoded value is a well-formed TipTap document and recursively drops any node/mark type or attribute key outside that same allow-list.
Malformed input in either mode degrades to a safe empty value - it never throws and never reaches the database unsanitized.
Repeater lifecycle
BlockCraft's ESM hydrator (assets/js/blockcraft.ts) watches for its mount
elements being removed from the DOM (a Tailor/FormController repeater row
deleted) and destroys the corresponding TipTap/Vue instance via a
MutationObserver - this prevents the memory leaks and detached event
listeners a naive integration would accumulate as rows are added and removed.
Development
npm install
npm run dev # Vite dev server with HMR
npm run build # production bundle -> assets/dist/
npm run typecheck
npm test # Vitest, mounts the real TipTap editor under jsdom
Testing
The PHPUnit suite (tests/) needs October's own base classes
(PluginTestCase, Backend\Classes\FormField/FormWidgetBase) to mean
anything, so it must run from inside a real October CMS application with
this plugin installed under plugins/amjadiqbal/blockcraft:
composer create-project october/october octoberapp
rsync -a --exclude=node_modules --exclude=assets/dist --exclude=.git \
./ octoberapp/plugins/amjadiqbal/blockcraft/
cd octoberapp
php artisan october:migrate
vendor/bin/phpunit --configuration path/to/phpunit.blockcraft.xml
See .github/workflows/tests.yml for the exact, working invocation (this is
literally the same script CI runs).
Support & Community
Custom Development
Hire me on Upwork for:
- Package integration
- Custom feature development
- Technical consultation
- Project implementation
Community Support
For priority support and enterprise solutions, please reach out via Upwork for direct assistance.
Changelog
Please see CHANGELOG.md for details on what changed in each release.
Security
If you discover a security vulnerability, please reach out privately via Discord or Upwork instead of opening a public issue. It will be addressed promptly.
Contributing
Contributions, issues, and feature requests are welcome - see open issues or open a pull request.
License
MIT. See LICENSE.