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

Markdown Bundle Laravel Package

kwattro/markdown-bundle

A Symfony bundle that integrates Markdown parsing into your application, offering a configurable parser service and Twig helpers for rendering Markdown content in templates. Useful for lightweight docs, CMS content, and user-authored text.

View on GitHub
Deep Wiki
Context7

Getting Started

Know what you're actually installing first. This bundle is a thin Symfony wrapper around the Sundown markdown parser — which means the real dependency is the native sundown PHP extension (PECL), not just a Composer package. Check that before anything else:

php -m | grep -i sundown
composer require kwattro/markdown-bundle

If sundown isn't in php -m, Composer will install fine but the parser will fail at runtime — see Gotchas.

Register the bundle. This is a Symfony 2/3-era bundle, so it goes in app/AppKernel.php:

new Kwattro\MarkdownBundle\KwattroMarkdownBundle(),

(Symfony 4+ projects will need config/bundles.php instead, and may hit compatibility issues.)

Find the service before you guess its ID. Documentation is sparse, so let the container tell you:

bin/console debug:container | grep -i markdown

You're looking for a parser service (conventionally something like kwattro_markdown or ...markdown.parser) exposing a render()/transform()-style method.

First use case — the 90% case. Render markdown stored in an entity field into HTML in a template:

{{ post.body|markdown }}

Most usage of this bundle is exactly that one line, plus the safety caveat below.

Implementation Patterns

Twig filter for read-time rendering. The bundle registers a Twig extension so you can render inline. Note the escape interaction — the filter typically returns HTML that Twig may still escape; either the extension is marked is_safe: html or you need |raw:

{{ post.body|markdown|raw }}

Test this once and standardise, because getting it wrong produces either escaped tags or an XSS hole.

Inject the service for anything non-trivial. Don't scatter render logic through templates. Wrap it in your own service:

class MarkdownRenderer
{
    public function __construct(private $parser) {}

    public function toHtml(string $md): string
    {
        return $this->parser->render($md);
    }
}

The indirection matters here: this package is effectively unmaintained (5 stars, 0 dependents), so isolating the call behind one small class means swapping in league/commonmark later is a one-file change.

Store both source and output. For content-heavy apps, render on save into a body_html column and cache it. This keeps the C parser out of hot read paths and decouples display from the parser being present on every node.

Enable Sundown extensions via config. Sundown supports tables, fenced code blocks, autolinking, and strikethrough through a flag bitmask. Check the bundle's config tree (bin/console config:dump-reference <alias>) and enable what your content needs — these are off by default and their absence is a common "why doesn't my table render" complaint.

Test the parser boundary. Assert on output HTML for a handful of representative inputs (headings, code fences, links, raw HTML). This gives you a regression suite you can run against a replacement parser when you migrate.

Gotchas and Tips

The native extension is the whole ballgame. Sundown upstream has been unmaintained since ~2014, and the PECL bindings generally will not compile against modern PHP (7.4+, and certainly not 8.x). If pecl install sundown fails, this bundle is a dead end on that runtime — plan the exit before you start. The bundle's low score and zero dependents reflect exactly this.

Sundown does not sanitise. It converts markdown to HTML faithfully, including any raw <script> you feed it. Markdown is not an XSS defence. Either strip raw HTML (Sundown has an option for this) or pipe the output through HTMLPurifier before display. For user-generated content this is non-negotiable.

Autowiring will probably not work. Old bundles often don't declare services with proper type-hints, so __construct(SomeParser $p) may fail to resolve. Fall back to the container id you found in debug:container, or alias it explicitly in your services config.

Debugging checklist: (1) is sundown in php -m? (2) does the service appear in debug:container? (3) is output escaped — try |raw? (4) is your table/code-fence extension flag actually enabled? Those four cover nearly every failure mode.

Performance is a strength, ironically. The C parser is fast — much faster than pure-PHP parsers. If you're doing high-volume rendering and can run the extension, that's the one genuine argument for this package over CommonMark.

Migration target. league/commonmark is the maintained, spec-compliant, actively developed option with a comparable API shape ($converter->convert($md)). Parsedown is the lighter-weight alternative. Because the extension dependency is fragile, treat this bundle as a stopgap or an archival reference rather than a long-term dependency — but the wrapper pattern above makes leaving cheap.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource