sgrodzicki/fm-bbcode-bundle
Symfony bundle that integrates FM BBCode parsing, registering the parser as a service and adding Twig support so BBCode-formatted content can be converted into HTML in templates and application code.
This is a Symfony2-era bundle (the description says "Symfony2 project") that wires a BBCode parser into Twig, so treat it as a legacy integration first and a feature second.
Minimal setup:
composer require sgrodzicki/fm-bbcode-bundleapp/AppKernel.php:
new FMBbCodeBundle\FMBbCodeBundle(),
On Symfony 4+ you would need a compatibility pass (see Gotchas) because the bundle predates the Flex bundle registration conventions.bin/console cache:clear) so the Twig extension is picked up.Where to look first, in order:
Twig/ in the bundle. This tells you the exact filter/tag name and whether the returned markup is marked safe. Do not assume the filter name from the README; confirm it in the extension (getFilters() / getFunctions()).DependencyInjection/Configuration.php and the extension class – to learn the config alias (likely fm_bbcode) and any parser options.First real use case: a forum, comment block, or legacy content field that stores BBCode in the database and renders it to HTML at display time. In Twig that looks like:
{{ post.body|bbcode }}
(substitute the actual filter name found in the extension class).
Render at display time, store raw. Keep the BBCode source in the database and convert in the template. This preserves editability and lets you change parser behaviour without a migration. The trade-off is per-request CPU; for read-heavy pages, pre-render to HTML and store that alongside the source.
Use it through a service, not only in Twig. Inject the parser service into your own service so controllers, console commands, and mail builders can convert the same way the templates do. This keeps one code path for rendering and avoids duplicating parser configuration.
class PostRenderer
{
public function __construct(private BBCodeParser $parser) {}
public function render(string $bbcode): string
{
return $this->parser->parse($bbcode);
}
}
Mark output safe deliberately. The filter presumably returns HTML. If the extension does not mark it is_safe: ['html'], apply |raw in the template — but only where you control the parser's behaviour. Never |raw user content through a parser configured to pass raw HTML.
Wrap noisy markup in a Twig macro so the whole app uses one call site:
{% macro bbcode(content) %}
<div class="bbcode">{{ content|bbcode }}</div>
{% endmacro %}
This gives you a single place to add caching, sanitisation, or a parser swap later.
Cache aggressively. Parsed BBCode rarely changes. Wrap the service with a cache keyed on a hash of the source string (md5($bbcode)) and store the HTML in your cache backend. This is the single biggest day-to-day win on forums with long threads.
Integration tips. Use it wherever a legacy export or migrated forum dump arrives as [b], [url], [quote] text. Run a batch conversion in a console command, validate the output, and store rendered HTML in a new column. That is the most common real-world reason to reach for a bundle like this.
composer.json will constrain Symfony to the 2.x range. On Symfony 4+ you will almost certainly need to fork it, replace the bundle class with a plain Twig extension service, and register that in services.yaml. Budget for this up front.NOASSERTION). There is no clear license grant. For anything shipping to production or to a client, get legal sign-off or fork under a licence you can defend. This is the biggest adoption risk after the Symfony version.composer.lock, and assume you own the code once you install it. Prefer vendoring or a fork you control.bin/console debug:twig (Symfony 2.8+) or bin/console twig:debug and look for the bundle's filter in the output. On older versions, inspect the extension class directly.[url] (javascript: schemes) and [img] (remote content, tracking pixels). A BBCode parser is not a sanitiser; layer HTMLPurifier or html-sanitizer on top if the source is untrusted.<strong> tags on the page, the output is being escaped and needs marking safe. If you get unescaped output where you did not expect it, the extension is marking it safe for you — confirm that is intended.fm_bbcode but check DependencyInjection/Configuration.php before writing YAML. Options passed to the parser at container-build time will not be visible in the template unless the extension exposes them.bin/console debug:container <service_id>) and test the parser in isolation with a unit test before blaming Twig.Given the age, licence ambiguity, and zero ecosystem support, the honest recommendation is: use it as a reference for how to wire a BBCode parser into Twig, and consider lifting the extension into your own small bundle with a maintained parser underneath rather than depending on this one directly.
How can I help you explore Laravel packages today?