Installation:
composer require colibo/parsedown-bundle:dev-master
Enable the bundle in config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 3):
// config/bundles.php
Colibo\ParsedownBundle\ColiboParsedownBundle::class => ['all' => true],
First Use Case:
{{ markdownContent|md }} {# Standard Parsedown #}
{{ markdownContent|mde }} {# Parsedown Extra #}
use Symfony\Component\DependencyInjection\ContainerInterface;
public function __construct(private ContainerInterface $container) {}
public function renderMarkdown(string $content): string
{
return $this->container->get('parsedown')->text($content);
}
Dynamic Parsing in Controllers:
use Symfony\Component\HttpFoundation\Response;
public function showMarkdown(ContainerInterface $container, string $content): Response
{
$parsed = $container->get('parsedown_extra')->text($content);
return new Response($parsed);
}
Twig Extensions for Custom Logic: Extend the bundle’s Twig filters by creating a custom extension:
// src/Twig/AppExtension.php
namespace App\Twig;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
class AppExtension extends AbstractExtension
{
public function getFilters(): array
{
return [
new TwigFilter('custom_md', [$this, 'customMarkdownFilter']),
];
}
public function customMarkdownFilter(string $content): string
{
// Custom logic (e.g., pre-process content)
return $this->container->get('parsedown_extra')->text($content);
}
}
Register the extension in services.yaml:
services:
App\Twig\AppExtension:
tags: ['twig.extension']
Reusable Services in Forms: Use the parsers to sanitize or pre-process user input (e.g., in form types):
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('description', TextType::class, [
'attr' => ['class' => 'markdown-input'],
'mapped' => false,
]);
}
// In a controller or subscriber:
$form->get('description')->setData(
$container->get('parsedown_extra')->text($rawInput)
);
API Responses: Parse markdown in API responses for consistency:
return $this->json([
'content' => $container->get('parsedown')->text($markdown),
]);
Symfony 4+ Compatibility:
config/bundles.php is used instead of AppKernel.php.dev-master branch or fork the repo to update for Symfony 4+ autowiring.Twig Filter Overrides:
md or mde filters globally, ensure the new filter accepts the same input/output contract:
{{ some_var|md }} {# Expects string, returns HTML string #}
{{ some_var|raw|md }} if you need to bypass Twig auto-escaping before parsing.Performance with Large Content:
$cacheKey = md5($content);
$parsed = $cache->get($cacheKey, function() use ($content) {
return $container->get('parsedown_extra')->text($content);
});
Security:
htmlspecialchars() or a whitelist if needed.use HTMLPurifier;
$config = HTMLPurifier_Config::createDefault();
$purifier = new HTMLPurifier($config);
$safeHtml = $purifier->purify($parsedown->text($content));
Check Parser Output:
file_put_contents(
'debug/markdown.html',
$container->get('parsedown_extra')->text($content)
);
Twig Debugging:
config/packages/twig.yaml:
twig:
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
{{ dump(_context) }} to inspect variables in templates.Service Not Found:
erusev/parsedown, erusev/parsedown-extra) are installed:
composer require erusev/parsedown erusev/parsedown-extra
Custom Parsedown Extensions:
use Parsedown;
class CustomParsedown extends Parsedown
{
protected $MarkdownExtra = true;
public function __construct()
{
parent::__construct();
// Add custom rules
$this->setBreaksEnabled(true);
}
}
services.yaml:
services:
custom.parsedown:
class: App\Parsedown\CustomParsedown
tags: ['parsedown']
Hook into Parsedown Events:
setMarkupEscaped() or setUrlScheme() for global config:
$parsedown = $container->get('parsedown');
$parsedown->setUrlScheme('https');
Integrate with CMS:
// Entity
#[ORM\Column(type: 'text')]
private string $markdownContent;
// Repository/Service
$htmlContent = $container->get('parsedown_extra')->text($entity->markdownContent);
CLI Usage:
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class MarkdownCommand extends Command
{
protected static $defaultName = 'app:parse-markdown';
protected function execute(InputInterface $input, OutputInterface $output, ContainerInterface $container)
{
$parsed = $container->get('parsedown')->text(file_get_contents('input.md'));
file_put_contents('output.html', $parsed);
$output->writeln('Markdown parsed!');
}
}
How can I help you explore Laravel packages today?