Install the package:
composer require aymdev/commonmark-bundle
This auto-registers the bundle for Symfony 4.4+.
Configure a converter in config/packages/aymdev_commonmark.yaml:
aymdev_commonmark:
converters:
default:
type: 'github' # or 'commonmark' for standard Markdown
First use case:
{{ markdown_content|commonmark('default') }}
use League\CommonMark\MarkdownConverter;
public function renderMarkdown(MarkdownConverter $converter) {
$html = $converter->convert('# Hello, World!');
return new Response($html);
}
Multi-Converter Setup:
Define distinct converters for different use cases (e.g., blog_post vs. comment):
aymdev_commonmark:
converters:
blog_post:
type: 'commonmark'
extensions:
- League\CommonMark\Extension\HeadingPermalink\HeadingPermalinkExtension
comment:
type: 'github'
options:
enable_emphasis: true
Use them in Twig:
{{ blog_content|commonmark('blog_post') }}
{{ user_comment|commonmark('comment') }}
Dynamic Converter Selection:
Inject the ConverterLocator service to resolve converters dynamically:
use AymDev\CommonMarkBundle\ConverterLocator;
public function __construct(private ConverterLocator $locator) {}
public function convert(string $content, string $converterName): string {
return $this->locator->get($converterName)->convert($content);
}
Custom Extensions: Register League CommonMark extensions (e.g., tables, footnotes) in config:
aymdev_commonmark:
converters:
advanced:
type: 'commonmark'
extensions:
- League\CommonMark\Extension\Table\TableExtension
- League\CommonMark\Extension\Footnotes\FootnotesExtension
API Responses: Convert Markdown in API controllers:
public function getPostContent(MarkdownConverter $converter): JsonResponse {
$markdown = $this->fetchMarkdownFromDB();
return new JsonResponse(['content' => $converter->convert($markdown)]);
}
Form Handling:
Use the empty converter type for inline parsing (e.g., previewing Markdown in forms):
aymdev_commonmark:
converters:
preview:
type: 'empty'
extensions:
- League\CommonMark\Extension\InlineParser\InlineParserExtension
Converter Not Found:
No converter named "X" found.aymdev_commonmark.yaml and the name matches exactly (case-sensitive).Extension Loading Issues:
Class "League\CommonMark\Extension\..." not found.league/commonmark (v2.x) and is spelled correctly. Example:
extensions:
- League\CommonMark\Extension\SmartPunct\SmartPunctExtension # Correct
- League\CommonMark\Extension\SmartPunct # Incorrect (missing class name)
Deprecated Service IDs:
Service "aymdev_commonmark.converter.X" not found (Symfony <5.1).MarkdownConverter $myConverter in autowiring). See changelog 1.3.0.Twig Filter Caching:
commonmark) may not reflect config changes immediately.php bin/console cache:clear
Empty Converter Misuse:
empty converter type does not parse blocks (e.g., paragraphs, headings). Use for inline content only (e.g., **bold** → <strong>bold</strong>).Log Converter Config: Dump the resolved converter to debug:
use League\CommonMark\MarkdownConverter;
public function debugConverter(MarkdownConverter $converter) {
\Symfony\Component\Debug\Debug::dump($converter->getEnvironment());
}
Validate Markdown:
Use the empty converter to test raw Markdown syntax:
aymdev_commonmark:
converters:
debug:
type: 'empty'
{{ markdown|commonmark('debug') }} {# Renders raw HTML entities #}
Extension Conflicts: Disable extensions one-by-one to isolate issues:
extensions:
- League\CommonMark\Extension\Table\TableExtension # Comment out to test
Reuse Converters: The bundle registers converters as singletons. Avoid recreating them manually.
Lazy-Load Extensions: For heavy extensions (e.g., tables), consider lazy-loading:
extensions:
- League\CommonMark\Extension\Table\TableExtension:
enabled: false # Disable by default
Enable dynamically in code:
$converter->getEnvironment()->addExtension(new TableExtension());
Cache HTML Output: Cache converted Markdown in a service or database to avoid reprocessing:
$cacheKey = 'markdown_' . md5($content);
if (!$html = $cache->get($cacheKey)) {
$html = $converter->convert($content);
$cache->set($cacheKey, $html, 3600);
}
Custom Converter Types:
Extend the bundle to support custom converter types. Override the ConverterFactory service:
services:
AymDev\CommonMarkBundle\ConverterFactory:
arguments:
$customTypes:
my_custom:
class: App\Custom\MarkdownConverter
Twig Filter Overrides: Replace the default Twig filter by binding a custom extension:
services:
app.commonmark.twig_extension:
class: App\Twig\CustomCommonMarkExtension
tags: ['twig.extension']
Environment Hooks: Modify the converter environment post-creation via an event subscriber:
use League\CommonMark\Environment;
public function onKernelRequest(GetResponseEvent $event) {
$converter = $this->locator->get('default');
$converter->getEnvironment()->addExtension(new MyExtension());
}
How can I help you explore Laravel packages today?