Ответ 1
Как насчет расширения Intl Twig?
Использование в шаблоне ветки:
{{ my_date | localizeddate('full', 'none', locale) }}
Чтобы отформатировать дату в ветке, вы обычно используете что-то вроде:
{{ meeting.date|date("m/d/Y") }}
Теперь мне нужно локализовать эту дату (US m/d/y, NL d/m/y). Какая была бы лучшая практика для этого в ветке? Я использую Symfony 2, обходным решением было бы сделать перевод в контроллере, но я хотел бы сделать это на веточке.
Как насчет расширения Intl Twig?
Использование в шаблоне ветки:
{{ my_date | localizeddate('full', 'none', locale) }}
Я не хотел устанавливать целые расширения только для этого материала и должен делать несколько вещей автоматически: также можно написать helperclass (или расширить существующий помощник) в Bundle/Twig/Extensions, например, так
public function foo(\Datetime $datetime, $lang = 'de_DE', $pattern = 'd. MMMM Y')
{
$formatter = new \IntlDateFormatter($lang, \IntlDateFormatter::LONG, \IntlDateFormatter::LONG);
$formatter->setPattern($pattern);
return $formatter->format($datetime);
}
веточка-шаблон:
{{ yourDateTimeObject|foo('en_US', 'd. MMMM Y') }}
В результате "12. февраля 2014 года" (или "12. Februar 2014" в de_DE и т.д.)
Я действительно хотел, чтобы имена дня и месяца были переведены в соответствии с языковым стандартом и написали это расширение ветки. Он принимает нормальные параметры DateTime->format()
и преобразует имена дней и месяцев, используя strftime()
, если это необходимо.
<?php
namespace AppBundle\Twig\Extension;
use Twig_Extension;
use Twig_SimpleFilter;
use DateTimeZone;
use DateTime;
class LocalizedDateExtension extends Twig_Extension
{
protected static $conversionMap = [
'D' => 'a',
'l' => 'A',
'M' => 'b',
'F' => 'B',
];
public function getFilters()
{
return [
new Twig_SimpleFilter('localizeddate', [$this, 'localizeDate']),
];
}
protected static function createLocalizableTodo(&$formatString)
{
$newFormatString = '';
$todo = [];
$formatLength = mb_strlen($formatString);
for ($i = 0; $i < $formatLength; $i++) {
$char = $formatString[$i];
if ('\'' === $char) {
$newFormatString = $formatString[++$i]; //advance and add new character
}
if (array_key_exists($char, static::$conversionMap)) {
$newFormatString.= '\!\L\O\C\A\L\I\Z\E\D\\'; //prefix char
$todo[$char] = static::$conversionMap[$char];
}
$newFormatString.= $char;
}
$formatString = $newFormatString;
return $todo;
}
public function localizeDate(DateTime $dateTime, $format, $timezone = null, $locale = null)
{
if (null !== $timezone && $dateTime->getTimezone()->getName() !== $timezone) {
$dateTime = clone $dateTime;
$dateTime->setTimezone(new DateTimeZone($timezone));
}
$todo = static::createLocalizableTodo($format);
$output = $dateTime->format($format);
//no localizeable parameters?
if (0 === count($todo)) {
return $output;
}
if ($locale !== null) {
$currentLocale = setlocale(LC_TIME, '0');
setlocale(LC_TIME, $locale);
}
if ($timezone !== null) {
$currentTimezone = date_default_timezone_get();
date_default_timezone_set($timezone);
}
//replace special parameters
foreach ($todo as $placeholder => $parameter) {
$output = str_replace('!LOCALIZED'.$placeholder, strftime('%'.$parameter, $dateTime->getTimestamp()), $output);
}
unset($parameter);
if (isset($currentLocale)) {
setlocale(LC_TIME, $currentLocale);
}
if (isset($currentTimezone)) {
date_default_timezone_set($currentTimezone);
}
return $output;
}
}