webentwicklung-frage-antwort-db.com.de

Twig-Gebietsschema erzwingen

Ich möchte das Twig-Vorlagensystem zum Erstellen meiner 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?

Im Handbuch wird erwähnt, wie das Gebietsschema für den Übersetzer erzwungen wird . 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 von in in der Vorlage, da dies meiner Meinung nach eine Übersetzung innerhalb der Vorlage in einem bestimmten Gebietsschema erzwingt.

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

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(...);
}
28
rolandow

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önnen also eine andere user_locale-Variable in Ihrer Render-Methode in Ihrem Controller übergeben (oder das gesamte Benutzerobjekt durchlaufen, anstatt Namen und user_locale separat zu übergeben, oder app.user in Ihrer Vorlage verwenden, wenn der Benutzer angemeldet ist, usw.). (abhängig von Ihrer Bewerbung natürlich)), dann können Sie in Ihrer E-Mail-Vorlage etwa Folgendes 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) nur etwas in der Art und die Übersetzungen werden im Handumdrehen für Sie funktionieren:

# messages.fr.yml    
greeting: 'Bonjour'
32
Mark

Holen Sie sich die Translator-Komponente und ändern Sie ihr Gebietsschema, bevor Sie die Vorlage rendern. Bei dieser Lösung muss nicht ein zusätzlicher Wert an das Parameterarray der render () - Methode übergeben werden, und alle Ihre Twig-Dateien müssen überarbeitet werden.

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 allgemeiner Ansatz für das Mailing von Benutzern besteht darin, das Gebietsschema des Benutzers in der Benutzerentität zu speichern und direkt an den Übersetzer zu übergeben, wie in diesem Code-Snippet:

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

Hier ist eine Lösung (es funktioniert gut, außer Sub-Templates (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();
}
2
Osoian Marcel

sie können dies tun: Senden Sie einen Parameter (z. B. ein 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(...);
}
0
Lhassan Baazzi