short-edition/tinymce-bundle
TinyMCE bundle for Laravel from short-edition: quickly add the TinyMCE rich text editor to your PHP app with packaged assets, config publishing, and Blade integration for fast, framework-friendly WYSIWYG editing.
Read this first: short-edition/tinymce-bundle is a Symfony2 bundle, not a Laravel package. There is no service provider, no facade, no config/tinymce.php publish tag. composer require short-edition/tinymce-bundle in a Laravel app pulls in a class tree that references Symfony\Component\HttpKernel\Bundle\Bundle, the Symfony DI container, and Twig 1.x — none of which Laravel wires up. For a Laravel codebase, the realistic "getting started" is to read the repo as a reference implementation and re-implement its ~150 lines of useful logic yourself.
Where to look in the source, in order:
tinymce_init() function that emits a <script> block calling tinymce.init({...}).theme: map that ships with sensible defaults for default, simple, full variants.First use case (Symfony context, for reference): register new ShortEdition\Bundle\TinymceBundle\ShortEditionTinymceBundle() in AppKernel.php, add a short_edition_tinymce: block to config.yml with tinymce_js_url and theme:, drop {{ tinymce_init() }} in your base layout, and put class="tinymce" on any <textarea>. The extension's init script targets .tinymce and auto-bootstraps.
For Laravel: skip the bundle. npm install tinymce plus a small Blade component gives you the same result with a maintained, versioned editor. Treat the repo as a spec for how to wire TinyMCE into a server-rendered form layer.
Named themes, one global default. The bundle's core idea is a theme: map in config — a default entry plus named variants (simple, full, minimal). A textarea opts in with data-theme="simple", and the Twig helper emits one tinymce.init({...}) per theme actually present on the page. Copy this pattern: keep toolbar/plugin config out of templates and in a versioned config array.
Layout-level include, view-level opt-in. Call tinymce_init() once in the base layout (cheap when no .tinymce textareas exist) and let individual forms opt in via class/data attributes. Do not call it from partials — duplicate tinymce.init calls on the same selector are a classic source of double-initialized editors and ghost toolbars.
Laravel analogue. A Blade component that mirrors the bundle's form-helper ergonomics:
<x-tinymce name="body" :value="old('body', $post->body)" theme="simple" />
The component renders the textarea and pushes a per-page @push('scripts') block containing tinymce.init. Keep the init payload in a PHP config array (config/tinymce.php) and json_encode it — that mirrors the bundle's config-merge behaviour exactly.
Asset strategy. The bundle exposes tinymce_js_url (and a base URL) so you point at a CDN, a protocol-relative URL, or a locally served copy. In Laravel, prefer Vite/npm and @vite('resources/js/tinymce.js') so the editor version is pinned in package.json rather than in a URL string in YAML.
Server-side config rendering. The interesting part of the bundle is that the editor config is server-rendered — theme variants are resolved from YAML at render time and injected into the init call. That means your toolbar/plugin set is versioned with your app and can be gated by user role or feature flag. Preserve this: do not hardcode tinymce.init in a static JS file.
Multiple editors per page. One tinymce.init with a selector array (selector: '.tinymce-simple, .tinymce-full' — or per-theme init calls) is correct. Do not loop over textareas and call tinymce.init per element; TinyMCE re-scans the DOM each call and you get duplicates.
AppKernel, and Twig 1.x. Installing it in a Laravel app or a Symfony 5/6/7 app yields Composer conflicts and runtime class-not-found errors. The composer.json almost certainly pins PHP 5.x / Symfony ~2.x — modern Laravel requires PHP 8.1+ and Symfony 6/7 components.<script> from tinymce_init() runs before TinyMCE's JS bundle has loaded, or after a Turbo/Livewire navigation replaces the DOM. Check the network tab for tinymce.min.js, then check init ordering. With Livewire/Turbo, re-initialize on navigation by listening to the navigation event.tinymce_js_url may be emitted protocol-relative or as a raw path. With HTTPS-only apps serving mixed-content, or with a CDN that requires a versioned path, override it explicitly rather than relying on the default.tinymce_init() in both layout and a view partial, or including it twice in a composable template, initializes each textarea twice. Add a one-shot guard in the extension or a data-tinymce-inited attribute on the base element.How can I help you explore Laravel packages today?