flarum/markdown
Adds Markdown formatting to Flarum posts, letting users write bold, italic, links, lists, quotes, and code with familiar syntax. Integrates with the composer to render clean, consistent formatted content across discussions.
flarum/markdown is the Markdown formatting extension for Flarum (a PHP forum, not a Laravel app — it borrows Illuminate components but uses its own extender system). It wires s9e/text-formatter into Flarum's post rendering pipeline.
Minimal steps:
composer show flarum/markdown and php flarum extension:list first — most projects should not require it manually, and pulling a different version in can conflict with core.composer require flarum/markdown (matching your core major version), then enable it:
php flarum extension:enable flarum-markdown
php flarum assets:publish
php flarum cache:clear
extend.php (the extender array — this is Flarum's equivalent of a service provider), then js/src/forum/index.js for the composer/editor side.Flarum\Formatter\Formatter and call parse($post->content) / render($xml) to get safe HTML out for emails, feeds, search indexes, or API payloads that don't go through the normal serializer.Server-side rendering (the bread-and-butter pattern). Flarum stores raw Markdown in posts.content and derives contentHtml through the Formatter. Whenever you need HTML outside the normal request cycle (queued notification emails, static exports, sitemap descriptions), resolve the formatter rather than calling Parsedown/CommonMark directly:
$formatter = resolve(\Flarum\Formatter\Formatter::class);
$xml = $formatter->parse($post->content); // cached parse tree
$html = $formatter->render($xml); // safe HTML
Pass only $formatter->render() output to views — never htmlspecialchars-wrap it again or you'll get <em>.
Extending the syntax via extenders. Custom Markdown/BBCode is added through the Flarum\Extend\Formatter extender in your own extension's extend.php:
return [
(new Flarum\Extend\Formatter)
->configure(function ($configurator) {
$configurator->plugins->load('MyPlugin');
$configurator->Litedown; // or BBCodes, MediaEmbed, etc.
}),
];
Register tags/renderers there, or hook configurator.configure if you prefer event-listener style wiring over extenders.
Frontend integration. The forum side configures the same s9e runtime in JS. If you add a syntax on the server, mirror the tag registration in your extension's JS (js/src/forum/) so the live composer preview matches the final render. The extension bundles the composer toolbar and markdown-aware textarea behavior; extend rather than replace js/src/forum/index.js.
Workflows worth knowing:
parse/render but be aware of the formatter's internal cache keys — clear with php flarum cache:clear after changing formatter config.php flarum + the extension's PHPUnit suite is the fastest loop.MarkdownServiceProvider in the Laravel sense; registration is entirely via extend.php return arrays of extenders, and the JS half is a separate build. Don't look for config/markdown.php.<div> or <iframe>. Don't "fix" this with a custom configure() block that enables unsafe HTML unless you're also auditing the output — the security model assumes the default.php flarum cache:clear; after JS changes you must rebuild assets (php flarum assets:publish), otherwise the composer preview and server render disagree and users file "my formatting is broken" reports.RuntimeException from s9e. Wrap one-off batch scripts in try/catch and log the offending $post->id rather than dying mid-loop.@mention, :emoji:, and media embedding are handled by flarum/mentions, flarum/emoji, flarum/mediaembed — if syntax "doesn't work" on a server-rendered email, check whether those extensions are enabled in the same context that's doing the render.$formatter->parse() yields XML; inspect that intermediate tree before blaming your renderer. It's the fastest way to tell whether a plugin failed to register or merely failed to render.Flarum\Extend\Formatter::configure() is the sanctioned hook; for anything more invasive fall back to the underlying s9e configurator events (configurator.configure), but prefer the extender so your customization composes cleanly with other extensions.How can I help you explore Laravel packages today?