Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Tinymce Bundle Laravel Package

gibilogic/tinymce-bundle

A Symfony bundle that integrates the TinyMCE rich text editor into your applications, providing configurable WYSIWYG editing for forms and content fields with minimal setup and easy customization.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the framing that matters: gibilogic/tinymce-bundle is a Symfony2 bundle, not a Laravel package. There is no service provider, no facade, no config/tinymce.php, no @tinymce Blade directive. Running composer require gibilogic/tinymce-bundle in a Laravel app will either fail dependency resolution or drag in symfony/framework-bundle ^2.x and its Form/Templating components that Laravel never uses. You cannot install your way to value here.

So the realistic first step is to read it, not install it. The bundle is small; the entire surface area is roughly:

  1. DependencyInjection/Configuration.php — the config tree (toolbar, plugins, theme, height, content_css, etc.). This is the spec you want to copy.
  2. Resources/config/services.xml — wiring for the Twig extension and/or form type.
  3. Form/Type/* and Twig/*Extension.php — how the init <script> is generated and attached to a field.
  4. Resources/public/ — the vendored TinyMCE assets, installed to web/ via assets:install.

If you are actually dropped into a legacy Symfony2 app (the only context where this is directly usable): register the bundle in AppKernel::registerBundles(), add a gibilogic_tinymce: block to config.yml, run php app/console assets:install --symlink, and swap a <textarea> for the bundle's field type. That is the entire onboarding.

Your first use case in Laravel is the same one the bundle exists for: take a plain <textarea name="body"> in an admin CRUD form and turn it into a WYSIWYG without hand-writing tinymce.init() in twenty Blade files. Read Configuration.php with that goal, then write a config/tinymce.php that mirrors its keys and a <x-tinymce> Blade component that renders the textarea plus an init script.

Implementation Patterns

Config-tree-as-defaults, per-field overrides. The bundle's real idea is that global defaults live in config and individual fields override a subset. Mirror it:

// config/tinymce.php
return [
    'default' => [
        'height' => 400,
        'menubar' => false,
        'plugins' => 'lists link table code',
        'toolbar' => 'undo redo | bold italic | bullist numlist | link table | code',
        'content_css' => '/css/editor.css',
    ],
    'profiles' => [
        'basic'  => ['toolbar' => 'bold italic | link'],
        'full'   => ['plugins' => 'lists link table code image media', 'height' => 600],
    ],
];

Blade component as the form-type equivalent. This is the direct analogue of the bundle's form type — one component, one place to change editor behavior:

{{-- resources/views/components/tinymce.blade.php --}}
@props(['name', 'value' => '', 'profile' => 'default'])
<textarea name="{{ $name }}" id="{{ $id = 'tinymce-'.Str::random(8) }}">{{ $value }}</textarea>
@once
    @push('scripts')
        <script src="{{ asset('vendor/tinymce/tinymce.min.js') }}"></script>
    @endpush
@endonce
@push('scripts')
    <script>
        tinymce.init({ target: document.getElementById('{{ $id }}'),
            ...@json(config('tinymce.profiles.'.$profile, config('tinymce.default'))) });
    </script>
@endpush

Asset handling: Vite, not the Symfony asset pipeline. Where the bundle copies Resources/public/ into Symfony's web/ directory, you install tinymce from npm and let Vite bundle it. npm i tinymce then import tinymce from 'tinymce' in resources/js/app.js, or reference it via @vite. This is the single most important port — it keeps version pinning and security patching under your control instead of relying on assets vendored years ago.

Initialization via a Stimulus-style controller or a small Alpine/Vanilla helper. The bundle lazily generates an init script per field. In Laravel, prefer a data-attribute-driven controller so multiple editors on a page stay independent:

document.querySelectorAll('[data-tinymce]').forEach(el => {
    tinymce.init({ target: el, ...JSON.parse(el.dataset.tinymce) });
});

Server-side integration. The bundle only injects config; it does not sanitize. In Laravel, route the editor output through a real sanitizer — mews/purifier (HTMLPurifier) or a strict allowlist — in a Form Request or model mutator, not in the editor. This is a deliberate divergence from the bundle, which assumes you handle it.

Multiple editors on one page. The bundle's per-profile config maps cleanly to data-tinymce attributes with the appropriate profiles.<name> JSON. Never rely on global tinymce.init targeting bare textarea selectors — that is the pattern that breaks when you add a second editor.

Gotchas and Tips

  • Category mismatch is the headline gotcha. Every assumption baked into the bundle — AppKernel, config.yml, assets:install, Twig extensions — has no Laravel equivalent. Budget for a port, not an install. If anyone frames this as "just composer require," correct them first.
  • TinyMCE version drift is a security issue, not a cosmetic one. The bundle's vendored assets are years old, and older 4.x/5.x releases carry known XSS advisories. When you copy its config shape, ignore its asset version entirely and pin a current TinyMCE (v6/v7) from npm.
  • Licensing and cloud keys. TinyMCE moved from MIT to a tiered model and often nudges you toward tinymce.cloud with an API key. The bundle implicitly assumes a self-hosted local bundle. If you take the cloud path, you inherit key rotation and CSP changes — treat that as a separate integration decision, not part of copying the bundle's pattern.
  • CSP breaks inline tinymce.init. The bundle emits inline <script> per field. Under a modern Content-Security-Policy that requires a nonce or hash; plan for a @nonce in your Blade component or move init into a compiled JS file with data attributes. This is the most common "editor works locally, blank in staging" failure.
  • Sanitization is 100% your responsibility. The bundle does nothing here and no wrapper can fix it. Validate on the server with an allowlist; never trust hidden <textarea> content because the editor is "safe." This is the highest-severity failure mode of a WYSIWYG integration.
  • Asset 404s. If you are somehow in Symfony and migrated to Symfony Flex, the bundle's assets expect web/, not public/. In Laravel, skip the question entirely by using Vite.
  • Config quirks worth knowing. TinyMCE options are flat-key JSON (toolbar, menubar, plugins, content_css, valid_elements); the bundle's config tree mirrors this but adds a Symfony DI layer you do not need. Copy the keys, not the DI structure.
  • Multiple editors and @once. If you copy the @once script-include pattern, make sure it appears exactly once per page or the browser will re-execute TinyMCE and re-initialize editors unpredictably. @once combined with @push('scripts') and a layout @stack('scripts') is the reliable combination.
  • Extending it. The only extensibility points that matter are: (1) the config keys — mirror them in config/tinymce.php; (2) the profile system — replicate it as a profiles array; (3) the form-type boundary — replicate it as a single Blade component. Everything else in the bundle (DI, Twig extension) is Symfony plumbing you should drop.
  • Debugging strategy. When the editor does not appear: check that tinymce.min.js actually loaded (Network tab), that tinymce.init ran without throwing (Console), that the target selector matched a real <textarea>, and that CSP did not block the init script. Those four cover ~95% of failures and none of them are fixed by the bundle.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core