kunstmaan/languagechooser-bundle
A Symfony bundle from Kunstmaan that provides a language chooser for switching between available locales in Kunstmaan-based applications. Small, focused, and easy to integrate into existing CMS setups.
This is a small companion bundle to Kunstmaan Bundles CMS that renders a "switch language" widget for a multi-locale site. It is not a router, not a locale negotiator, and not a translation layer — it assumes you already have localized pages (typically via kunstmaan/node-bundle) and just gives you a ready-made list of available locales with links to the same page in another language.
1. Install (pin deliberately). The last tagged release is from May 2014, so treat the version constraint as an archaeological artefact, not a range:
"require": {
"kunstmaan/languagechooser-bundle": "dev-master"
}
Match whatever kunstmaan/bundles-cms / Symfony version your project already uses — mixing this with a newer Kunstmaan stack is the fastest way to break your kernel.
2. Register it in app/AppKernel.php:
new Kunstmaan\LanguageChooserBundle\KunstmaanLanguageChooserBundle(),
3. Look here first. Open Resources/config/ (service definitions), Resources/views/ (Twig templates — this is 80% of the bundle's value), and the page-part/entity class if one ships in the release. grep -ri "view.html.twig" src/ in the bundle directory is faster than reading the README, which is thin.
4. First use case. Drop the language chooser into your page layout's header, above the navigation:
{% if app.request.attributes.get('_route_params') %}
{% include 'KunstmaanLanguageChooserBundle:LanguageChooser:view.html.twig' %}
{% endif %}
Then verify against a locale-prefixed route (e.g. /en/about → /fr/about). If your URLs do not carry a _locale parameter, this bundle cannot do anything for you — fix routing first.
Two integration styles, and you should pick one consciously.
Page part style (Kunstmaan-native). If the release ships a page part / block admin type, users can drag the chooser into a page in the CMS admin. This is the intended path: you get editor control over placement and per-page visibility for free, at the cost of being locked into the Kunstmaan admin form plumbing. Register it as you would any other page part and define its default view in Resources/views/PagePart/.
Template style (explicit include). More common in practice for a header widget: include the template directly from layout.html.twig. No editor control, but trivially testable and no admin coupling.
Driving the locale list. Do not let the template hardcode locales. In Kunstmaan Bundles the canonical source is the set of locales the node/page actually has translations for — usually the node's available languages rather than %locales% from config. Wrap that in a small Twig extension or a language_chooser service of your own so the template stays a dumb iterator:
// src/Acme/SiteBundle/Twig/LanguageChooserExtension.php
public function getAvailableLocales(NodeInterface $node)
{
// delegates to kunstmaan_node / your own translation repository
}
If you keep the bundle's own provider, assert that it filters to published translations. A switcher that links to a draft-only or 404-ing locale is the single most common complaint from editors.
Locales and URL shape. The chooser is only correct if the target URL differs solely by locale. Two patterns work well:
/{_locale}/about — the chooser can regenerate the current route with _locale swapped, which is cheap and reliable.example.com / example.fr) — you must map locale → host explicitly in config, since _locale alone won't reproduce the URL.For anything slug-based (translated slugs per language), you need the node/slug router to resolve the current node to its sibling translation. Do that in the provider, not in Twig.
SEO cross-links. The same source of locales should emit hreflang alternates in your <head>. Keep one provider and consume it twice; duplicated "which languages exist" logic diverges within a month.
Overriding the markup. Bundle inheritance still works on the Symfony 2.x generation this targets: create app/Resources/KunstmaanLanguageChooserBundle/views/LanguageChooser/view.html.twig and Symfony will prefer it. Copy the original first — the file is short, and you want to keep any conditional logic (e.g. "hide the chooser when only one locale exists") intact.
{# app/Resources/KunstmaanLanguageChooserBundle/views/LanguageChooser/view.html.twig #}
{% if locales is defined and locales|length > 1 %}
<ul class="lang-switch">
{% for locale in locales %}
<li class="{{ locale.active ? 'is-active' }}">
<a href="{{ locale.url }}" lang="{{ locale.locale }}">{{ locale.label|upper }}</a>
</li>
{% endfor %}
</ul>
{% endif %}
It is effectively unmaintained. Six stars, zero dependents, last release 2014. Do not expect fixes for Symfony deprecations, PHP 7+ notices, or Twig 2/3 syntax changes. Treat it as reference code you may vendored-copy into src/ rather than a live dependency — a hand-rolled switcher is ~30 lines and you'll own it entirely.
Bundle inheritance is retired. If you are on Symfony 3.4+ or 4.x, app/Resources/<Bundle>/views no longer takes precedence. Override with twig.paths config or an explicit template directory instead. Bundles of this vintage are the usual culprit when "my override isn't picked up".
Locale negotiation is not included. The bundle does not set _locale, does not read Accept-Language, and does not persist a choice in session. Add a LocaleListener on kernel.request if you want those; don't assume the chooser does it.
The chooser renders the current route with a new locale. On routes without _locale (homepage, search, 404), naive implementations produce duplicate URLs or a link back to the same page. Guard with app.request.attributes.get('_route_params') or generate from the resolved node, not the raw route.
Debugging checklist, in order:
php app/console debug:container | grep -i language — confirm the service is registered and not silently skipped by a compiler pass.php app/console debug:twig | grep -i chooser — confirm the template namespace resolves to the bundle, not your override (or vice versa).php app/console cache:clear — Twig caches template lookup paths aggressively; overrides appear "ignored" until you clear.{{ dump(locales) }} with the debug bundle) — if it's empty, the problem is your provider, not the bundle.Extension points worth knowing: the Twig template, the provider that returns available locales, and (if present) the page part's admin type for controlling which fields editors see. There is no meaningful event dispatcher surface — don't go looking for one.
Cache and ESI. If the chooser is inside a cached fragment, make sure the fragment cache varies by _locale, or French visitors will get English switchers.
Bottom line for day-to-day use: viable only as a starting reference on a legacy Kunstmaan 2.x project. On anything current, lift the ~40-line Twig template and the locale-provider idea, and leave the composer entry behind.
How can I help you explore Laravel packages today?