Erzwingen des Twig-Gebietsschemas

Lesezeit: 4 Minuten

Ich möchte das Twig-Vorlagensystem zum Erstellen von Vorlagen für meine E-Mails verwenden. Das Gebietsschema der E-Mail sollte auf einer Benutzereinstellung basieren, nicht auf dem Sitzungs- oder Anforderungsgebietsschema. Wie kann ich das Gebietsschema beim Rendern einer Twig-Vorlage erzwingen?

Das Handbuch erwähnt, wie um das Gebietsschema für den Übersetzer zu erzwingen. Aber ich möchte dieses Gebietsschema an die Methode render() übergeben, damit die Übersetzungen in der Zweigvorlage in diesem Gebietsschema gerendert werden.

Dies unterscheidet sich von der Verwendung hinein in der Vorlage, weil ich denke, dass dies eine Übersetzung innerhalb der Vorlage in einem bestimmten Gebietsschema erzwingt.

Wenn ich das Beispiel von Symfony nehme, suche ich nach so etwas:

public function indexAction($name)
{
    $message = \Swift_Message::newInstance()
        ->setSubject('Hello Email')
        ->setFrom('[email protected]')
        ->setTo('[email protected]')
        ->setBody(
            $this->renderView(
                'HelloBundle:Hello:email.txt.twig',
                array('name' => $name),
                'nl_NL' // <-- This would be nice!
            )
        )
    ;
    $this->get('mailer')->send($message);

    return $this->render(...);
}

Benutzer-Avatar
Markieren

Sie können das Gebietsschema als Argument übergeben, wenn Sie den trans-Filter verwenden (siehe diff: https://github.com/symfony/symfony/commit/3ea31a02630412b1c732ee1647a0724378f67665).

Sie könnten also eine andere user_locale-Variable in Ihrer Rendermethode in Ihrem Controller übergeben (oder das gesamte Benutzerobjekt durchlaufen, anstatt name und user_locale separat zu übergeben, oder app.user in Ihrer Vorlage verwenden, wenn der Benutzer angemeldet wird, etc … (abhängig von Ihrer Anwendung natürlich)), dann können Sie in Ihrer E-Mail-Vorlage so etwas haben:

{{ 'greeting' | trans({}, "messages", user_locale) }} {{ name | title }}
{# rest of email template with more translation strings #}

Dann haben Sie in Ihrer Übersetzungsdatei für dieses Gebietsschema (vorausgesetzt, Sie verwenden yaml) einfach so etwas und die Übersetzungen werden im Handumdrehen gut für Sie funktionieren:

# messages.fr.yml    
greeting: 'Bonjour'

Benutzer-Avatar
Marcel Hernández

Holen Sie sich die Translator-Komponente und ändern Sie ihr Gebietsschema, bevor Sie die Vorlage rendern. Diese Lösung tut es nicht erfordern, einen zusätzlichen Wert an das Array der Parameter der Methode render() zu übergeben und all Ihre Twig-Dateien mühsam umzugestalten.

public function indexAction($name)
{
    $translator = $this->get('translator');

    // Save the current session locale
    // before overwriting it. Suppose its 'en_US'
    $sessionLocale = $translator->getLocale();

    $translator->setLocale('nl_NL');

    $message = \Swift_Message::newInstance()
        ->setSubject('Hello Email')
        ->setFrom('[email protected]')
        ->setTo('[email protected]')
        ->setBody(
            $this->renderView(
                'HelloBundle:Hello:email.txt.twig',
                array('name' => $name)
            )
        )
    ;

    $this->get('mailer')->send($message);

    // Otherwise subsequent templates would also
    // be rendered in Dutch instead of English
    $translator->setLocale($sessionLocale);

    return $this->render(...);
}

Ein gängiger Ansatz für Benutzer-Mailing ist das Speichern des Gebietsschemas des Benutzers in der User-Entität und das direkte Weiterleiten an den Übersetzer, wie in diesem Code-Snippet:

$translator->setLocale($recipientUser->getLocale());

  • enthaltene Untervorlagen sind nicht betroffen

    – Jackie Chan

    3. November 2015 um 6:11 Uhr

  • Dies sollte die Standardantwort sein, da es das Gebietsschema an einer Stelle ändert, anstatt Hunderte (in unserem Fall) Vorlagen zu ändern.

    – Serhii Polishchuk

    23. Oktober 2020 um 8:42 Uhr

Hier ist eine Lösung (es funktioniert gut, außer Untervorlagen (Twig: render(controller(‘AppBundle:Invoice/Index:productTotalPartial’)))

<?php

namespace Main\BoBundle\Service;

use Symfony\Component\Translation\TranslatorInterface;

/**
 * Class LocaleSwitcher
 *
 * @package Main\BoBundle\Service
 */
class LocaleSwitcher
{
    /**
     * @var TranslatorInterface
     */
    private $translator;

    /**
     * @var string
     */
    private $previousLocale;

    /**
     * @param TranslatorInterface $translator
     */
    public function __construct(TranslatorInterface $translator)
    {
        $this->translator = $translator;
    }

    /**
     * Change the locale
     *
     * @param string $locale
     */
    public function setLocale($locale)
    {
        $this->previousLocale = $this->translator->getLocale();

        $this->translator->setLocale($locale);
        $this->setPhpDefaultLocale($locale);
    }

    /**
     * Revert the locale
     */
    public function revertLocale()
    {
        if ($this->previousLocale === null) {
            return;
        }

        $this->translator->setLocale($this->previousLocale);
        $this->setPhpDefaultLocale($this->previousLocale);

        $this->previousLocale = null;
    }

    /**
     * Use temporary locale in closure function
     *
     * @param string $locale
     * @param \Closure $c
     */
    public function temporaryLocale($locale, \Closure $c)
    {
        $this->setLocale($locale);

        $c();

        $this->revertLocale();
    }

    /**
     * Sets the default PHP locale.
     * Copied from Symfony/Component/HttpFoundation/Request.php
     *
     * @param string $locale
     */
    private function setPhpDefaultLocale($locale)
    {
        // if either the class Locale doesn't exist, or an exception is thrown when
        // setting the default locale, the intl module is not installed, and
        // the call can be ignored:
        try {
            if (class_exists('Locale', false)) {
                /** @noinspection PhpUndefinedClassInspection */
                \Locale::setDefault($locale);
            }
        } catch (\Exception $e) {
        }
    }
}

Beispiel:

if ($this->getLocale()) {
    $this->localeSwitcher->setLocale($this->getLocale());
}

$html = $this->templating->render($templatePath);

if ($this->getLocale()) {
    $this->localeSwitcher->revertLocale();
}

Sie können dies tun: Senden Sie einen Parameter (z. B. Gebietsschema) an die Vorlage

public function indexAction($name)
{
    $message = \Swift_Message::newInstance()
        ->setSubject('Hello Email')
        ->setFrom('[email protected]')
        ->setTo('[email protected]')
        ->setBody(
            $this->renderView(
                'HelloBundle:Hello:email.txt.twig',
                array('name' => $name, 'locale' => 'nl_NL'),
            )
        )
    ;
    $this->get('mailer')->send($message);

    return $this->render(...);
}

1176670cookie-checkErzwingen des Twig-Gebietsschemas

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy