Seit kurzem ziehe ich meine Webseite Umzugshelfer.website von Cakephp auf Symfony. Ich gehe nicht davon aus, dass ich in Deutschland viele englisch sprechende Kunden haben werde, dies kommt aber das ein oder andere mal vor. Um es diesen wenigen Kunden zu vereinfachen und damit ich es direkt lerne, zeige ich euch kurz wie toll das mit Symfony und Annotations geht
Annotations
Wenn Ihr es noch nicht längst gemacht habt, ist nun der Zeitpunkt gekommen
composer require annotations
installiert euch das Annotions-Bundle von Symfony. Ich sage euch, Ihr werdet es brauchen und es lieben lernen. Das ganze sieht dann wie flolgt aus:
/**
* @Route("/preise", name="preise")
*/
Wichtig dabei ist, dass name im Projekt Unique sein muss, damit geniert Ihr euch in Kürze eure URLs. Preise ist dabei der Pfad der dabei generiert wird.
PHP
$url = $this->generateUrl('preise');
Twig
{{ path('preise') }}
Ihr solltet bei größeren Projekten euren Controller vorne anhängen, sonst kommt es schnell zu Überschneidungen -> pages_prices
Internationalisierung
Seit Symfony 4.1 gibt es die Annotationen auch für die Routen.
/**
* @Route({
* "de": "/kostenloses-angebot",
* "en": "/free-quote"
* }, name="free_quote")
*/
Das macht die ganze Sache wesentlich einfacher. Wenn Ihr nun beide Routen ausprobieren wollt, denkt daran euer locale mitzugeben.
http://127.0.0.1:8000/en/
Ich habe versucht die locale im Controller zu übergeben indem ich mir den Request mit DI hole, aber da ist es dafür schon zu spät.
Menu
{% if is_granted("ROLE_USER") %}
{% set mainMenu = [
{'path': 'Coming','name': 'Coming soon' }
] %}
{% else %}
{% set mainMenu = [
{'path': 'free_quote','name': 'menu.free_quote.name'|trans },
{'path': 'prices','name': 'menu.prices.name'|trans },
{'path': 'blog','name': 'menu.blog.name'|trans },
{'path': 'media','name': 'menu.media.name'|trans },
{'path': 'reviews','name': 'menu.reviews.name'|trans },
{'path': 'contact','name': 'menu.contact.name'|trans }
] %}
{% endif %}
<ul class="navbar-nav mr-auto">
{% for item in mainMenu %}
<li{{ app.request.get('_route') == item['path'] ? ' class="nav-item"' : '' }}>
<a href="{{ path(item['path']) }}" class="nav-link page-scroll">{{ item['name'] }}</a>
</li>
{% endfor %}
</ul>
Da ich unterschiedliche Menüs habe nutze ich in Twig is_granted – in unserem Fall gibt es für Benutzer noch kein Menü. Jeder nicht eingeloggte Benutzer bekommt allerdings das Standard-Menu. Dabei fülle ich mein mainMenu mit einem Array in dem ich den path (Unique Route) und den name übergebe. Dies nutze ich dann weiter unten um mein eigentliches HTML Menü zu generieren.
Language Switch
Theoretisch könnt Ihr euren language switch hart codiert hinterlegen, aber es gibt auch eine dynamischere Variante:
<a href="{{ path(app.request.attributes.get('_route'), app.request.query.all|merge({'_locale': 'de'})) }}" class="nav-link language-switch {% if app.request.locale == 'de' %}lang-active{% endif %}">DE</a>
<a href="{{ path(app.request.attributes.get('_route'), app.request.query.all|merge({'_locale': 'en'})) }}" class="nav-link language-switch {% if app.request.locale == 'en' %}lang-active{% endif %}">EN</a>
Damit kommt Ihr immer auf die entsprechende übersetzte Seite. Heißt bin ich auf /agb werde ich beim klick auf EN direkt auf /gtc weitergeleitet.
Translations
Im obigen Code habe ich ‚menu.free_quote.name’|trans genutzt. Diese wurden im Standardpfad von Symfony abgelegt translations/
cd translations && ls
messages.de.yaml messages.en.yaml
In diesen YAML Dateien (ihr könnt auch .po oder .mo nutzen) könnt Ihr nun auf zwei Arten Übersetzungen anlegen. Ich nutze folgende:
# MENU
menu.free_quote.name: Kostenloses Angebot
menu.prices.name: Preise
menu.blog.name: Blog
menu.media.name: Mediathek
menu.reviews.name: Bewertungen
menu.contact.name: Kontakt
Die andere und, wie ich finde, unübersichtlichere ist:
Menu Blog Name: Blog
Vorteil hierbei ist, dass bei vielen wörtlichen Übersetzungen seid ihr mit Sicherheit schneller, da ihr nicht immer wieder in die YAML File schauen müssen. Ist am Ende euch überlassen. Ihr müsst beim nutzen in Twig dann allerdings auch eine der beiden nutzen.
Option 1: {% trans %}menu.blog.name{% endtrans %}
Option 2: {% trans %}Menu Blog Name{% endtrans %}
Profiler
Ich empfehle euch im QA den Profiler, in dem seht Ihr auf einen Blick ob es bei den Übersetzungen zu Fehlern oder einer „Fallback“ Übersetzung kam. Schnell vergisst man einen Textbaustein oder macht einen Fehler im anlegen.
Ergebnis
Das Ergebnis sieht dann wie folgt aus