runio / mde
A Symfony bundle providing a Markdown editor with WYSIWYG capabilities and first-class RTL/LTR support
v1.0.2
2026-03-15 17:23 UTC
Requires
- php: ^8.1
- league/commonmark: ^2.4
- league/html-to-markdown: ^5.1
- symfony/asset: ^6.0|^7.0
- symfony/form: ^6.0|^7.0
- symfony/framework-bundle: ^6.0|^7.0
- symfony/twig-bundle: ^6.0|^7.0
- symfony/yaml: ^6.0|^7.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.0
- symfony/browser-kit: ^6.0|^7.0
- symfony/css-selector: ^6.0|^7.0
- symfony/phpunit-bridge: ^6.0|^7.0
This package is auto-updated.
Last update: 2026-04-15 17:42:00 UTC
README
A Symfony bundle providing a WYSIWYG Markdown editor with first-class RTL and LTR support for Arabic, Hebrew, Persian, Urdu, and all LTR languages. Built on top of Toast UI Editor with deep Symfony integration.
Why This Bundle?
- Perfect RTL + LTR Support - Designed for Arabic, Hebrew, Persian, Urdu, and all LTR content
- WYSIWYG & Markdown - Switch between visual editing and markdown mode seamlessly
- Security First - Built-in XSS protection and HTML sanitization
- Highly Customizable - Themes, toolbars, preview modes, and more
- Production Ready - 119 tests, fully documented
- Easy Integration - Drop-in Symfony Form Type, ready in minutes
- Multi-language - Automatic RTL detection, mixed LTR/RTL content support
Requirements
- PHP: 8.1 or higher
- Symfony: 6.0 or 7.0+
- Composer: 2.0 or higher
Installation
Step 1: Install via Composer
composer require runio/mde
Step 2: Enable the Bundle (Symfony Flex does this automatically)
If you're not using Symfony Flex, manually enable the bundle:
// config/bundles.php return [ // ... Runio\MarkdownEditorBundle\RunioMarkdownEditorBundle::class => ['all' => true], ];
Step 3: Install Assets
php bin/console assets:install --symlink
Step 4: Register Form Theme
# config/packages/twig.yaml twig: form_themes: - '@RunioMarkdownEditor/form/markdown_editor_widget.html.twig'
Quick Start
1. Create a Form Type
use Runio\MarkdownEditorBundle\Form\Type\MarkdownEditorType; class PostType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('title') ->add('content', MarkdownEditorType::class, [ 'rtl_enabled' => true, 'language' => 'ar', 'editor_height' => '500px', ]); } }
2. Render in Template
{{ form_start(form) }}
{{ form_row(form.title) }}
{{ form_row(form.content) }}
<button type="submit">Save</button>
{{ form_end(form) }}
3. Display Rendered Content
{{ post.content|markdown }}
Configuration
# config/packages/runio_markdown_editor.yaml runio_markdown_editor: default_config: editor_height: '500px' editor_mode: 'wysiwyg' # wysiwyg, markdown, or both rtl_enabled: true language: 'ar' toolbar: 'full' # full, basic, minimal preview_style: 'vertical' # vertical or tab theme: 'light' # light or dark enable_upload: false upload_url: null markdown: html_input: 'escape' allow_unsafe_links: false enable_table_extension: true enable_strikethrough_extension: true enable_tasklist_extension: true enable_autolink_extension: true rtl: languages: ['ar', 'he', 'fa', 'ur'] auto_detect: true arabic_font: 'Noto Naskh Arabic' sanitization: enabled: true allowed_tags: [p, br, strong, em, u, s, blockquote, ul, ol, li, a, img, h1, h2, h3, h4, h5, h6, pre, code, table, thead, tbody, tr, th, td, hr, div, span] allowed_attributes: [href, src, alt, title, class, id, dir, lang]
Per-Field Override
$builder->add('content', MarkdownEditorType::class, [ 'editor_height' => '600px', 'editor_mode' => 'both', 'theme' => 'dark', 'toolbar' => 'basic', 'rtl_enabled' => true, 'language' => 'ar', ]);
Twig Integration
Filters
{{ post.content|markdown }}
{{ post.summary|markdown_inline }}
Functions
{% set html = markdown_to_html(post.content) %}
{% if detect_rtl(post.content) %}
<div dir="rtl">{{ html }}</div>
{% endif %}
Security
All HTML output is sanitized by default:
- Script tag removal
- Event handler blocking (onclick, onerror, etc.)
- JavaScript URL blocking
- Whitelist-based tag and attribute filtering
- Safe URL validation (http, https, mailto, tel only)
Testing
vendor/bin/phpunit
119 tests covering: Form Type (24), Markdown Parser (23), RTL Detector (16), Sanitization (34), Twig Runtime (22).
Documentation
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Write tests for your changes
- Ensure all tests pass (
vendor/bin/phpunit) - Commit and push
- Open a Pull Request
License
MIT License. See LICENSE for details.
Credits
Made for the multilingual developer community by RunIO