Installation:
composer require avensome/commonmark-bundle
Register the bundle in config/bundles.php:
Avensome\CommonMarkBundle\AvensomeCommonMarkBundle::class => ['all' => true],
First Use Case: Convert a Markdown string to HTML in Twig:
{{ '# Hello, CommonMark!' | markdown }}
Or in a service:
use League\CommonMark\CommonMarkConverter;
class MyService {
public function __construct(private CommonMarkConverter $converter) {}
public function render(string $markdown): string {
return $this->converter->convertToHtml($markdown);
}
}
Verify Configuration:
Check config/packages/avensome_commonmark.yaml (auto-generated). Defaults are safe but can be overridden:
avensome_commonmark:
html_input: allow # Allows HTML in Markdown input
Twig Integration:
markdown filter for inline conversion:
{{ article.content | markdown }}
{% markdown %} tag for multi-line blocks (avoids escaping issues).Service-Based Conversion:
CommonMarkConverter into controllers/services for programmatic use:
$html = $converter->convertToHtml($markdown);
$html = $sanitizer->sanitize($converter->convertToHtml($markdown));
Dynamic Configuration:
# config/packages/dev/avensome_commonmark.yaml
avensome_commonmark:
allow_unsafe_links: true # Only in dev
$converter = $container->get('avensome_commonmark.converter');
$converter->getEnvironment()->addExtension(new MyExtension());
Extensions:
services.yaml:
services:
My\CommonMark\Extension:
tags:
- { name: avensome_commonmark.extension }
webuni/table-extension.API Responses:
return new JsonResponse([
'content' => $converter->convertToHtml($request->get('markdown'))
]);
Symfony Forms: Use with Symfony\Component\Form\Extension\Core\Type\TextareaType for Markdown input:
$builder->add('description', TextareaType::class, [
'attr' => ['class' => 'markdown-input'],
]);
Then process with CommonMarkConverter in the controller.
Doctrine Entities: Store Markdown in a TextType column and convert on-the-fly:
$entity->setContent($converter->convertToHtml($rawMarkdown));
Event Listeners: Modify conversion behavior via events (e.g., pre-process Markdown):
$converter->getEnvironment()->addEventListener(
CommonMarkEvents::PRE_PROCESS,
function (PreProcessEvent $event) {
$event->getMarkdown()->replace('# ', '## ');
}
);
HTML Input Security:
html_input: allow enables raw HTML in Markdown (risky). Use sparingly or sanitize output:
$html = $converter->convertToHtml($markdown);
$sanitized = filter_var($html, FILTER_SANITIZE_FULL_SPECIAL_CHARS);
html_input: strict (default) to block HTML.Extension Conflicts:
{% markdown %}
| Header 1 | Header 2 |
|----------|----------|
| Cell 1 | Cell 2 |
{% endmarkdown %}
var_dump($converter->getEnvironment()->getExtensions()).Caching:
$converter->getEnvironment()->clearCache();
avensome_commonmark:
cache: false
Twig Auto-escaping:
|raw to bypass:
{{ markdown_content | markdown | raw }}
{% autoescape false %}
{{ markdown_content | markdown }}
{% endautoescape %}
PHP 7.4+ Deprecations:
createCommonMarkConverter() (deprecated in League/CommonMark). Use dependency injection:
// ❌ Avoid
$converter = CommonMarkConverter::createCommonMarkConverter();
// ✅ Prefer
$converter = $container->get('avensome_commonmark.converter');
Log Raw Output:
file_put_contents(
'debug.html',
$converter->convertToHtml($markdown)
);
Extension Debugging:
dd($converter->getEnvironment()->getExtensions());
# services.yaml
My\ProblematicExtension:
tags: []
Configuration Overrides:
config/packages/avensome_commonmark.yaml:
avensome_commonmark:
safe_mode: true # Disables dangerous features
CommonMark CLI:
commonmark --input=test.md --output=test.html
Custom Extensions:
League\CommonMark\Extension\ExtensionInterface:
class MyExtension implements ExtensionInterface {
public function register(ContainerInterface $environment) {
$environment->addRenderer('my_block', function () {
return new MyBlockRenderer();
});
}
}
services.yaml:
My\Extension:
tags:
- { name: avensome_commonmark.extension }
Environment Hooks:
$environment = $converter->getEnvironment();
$environment->addExtension(new MyExtension());
$environment->addEventListener(CommonMarkEvents::PRE_PROCESS, $listener);
Twig Customization:
services.yaml:
services:
avensome_commonmark.twig.markdown_filter:
class: My\CustomMarkdownFilter
arguments: ['@avensome_commonmark.converter']
tags: ['twig.filter', 'twig.test']
How can I help you explore Laravel packages today?