Во многих веб-приложениях и веб-сайтах вы можете видеть даты и легко их читать, не зная, какой сегодня день, или не зная, какой день — 21 мая, январь и т. Д. Эта функция обычно достигается в браузере с использованием JavaScript. Так в чем проблема? Библиотеки для форматирования не являются (обычно) легкими, и у вас будет как минимум 3 библиотеки для достижения чего-то подобного. Если вы хотите реализовать такую функцию в своем приложении и вам не нужно динамически обновлять даты в представлении, вы можете выполнить эту задачу на своем собственном сервере.
В этой статье мы покажем вам 2 способа отображения даты в формате времени назад: с помощью KnpTimeBundle (a) или реализации Twig_Extensions_Extension_Date
продолжение Twig. Оба они предоставляют одинаковую функциональность, но реализация 1 может быть более длительной для некоторых разработчиков, поэтому вам решать, какой метод проще реализовать для вас.
А. Пучок (легкий) способ
Если вам не нужно беспокоиться о размере вашего приложения, и вам разрешено устанавливать сторонние пакеты, тогда вам будет легче достичь своей цели (намного проще):
1. Установите и зарегистрируйте KnpTimeBundle
Мы говорим о KnpTimeBundle. Этот пакет выполняет одну простую работу: принимает даты и возвращает дружественные сообщения типа «2 часа назад». Чтобы установить этот пакет в вашем проекте Symfony, выполните следующую команду на терминале:
composer require knplabs/knp-time-bundle
Для получения дополнительной информации об этом комплекте, пожалуйста, посетите официальный репозиторий на Github здесь. После завершения установки комплекта обязательно включите комплект в ядре Symfony (app/AppKernel.php
):
И вы готовы перейти к следующему шагу.
2. Добавить локаль приложения и включить переводчик
Обычно в каждом приложении Symfony по умолчанию локаль уже существует, и она по умолчанию en
(английский). Это значение используется во всем приложении, а не только в комплекте. Если он не существует, укажите для параметра locale идентификатор вашего языка:
Заметка
Есть много поддерживаемых языков, поэтому обязательно проверьте файлы переводов чтобы увидеть, какие языки поддерживаются.
parameters:
locale: en
# Or the locale of your language e.g : es,de,nl,pt,pl etc
Далее вам нужно включить переводчик, потому что он обычно комментируется, поэтому убедитесь, что вы установили переводчик в app/config/config.yml
Файл не закомментирован, и в качестве запасного варианта используется предыдущий объявленный параметр локали:
framework:
translator: { fallbacks: ['%locale%'] }
Как только это будет сделано, вы сможете использовать фильтр назад пакета для отображения удобочитаемого описания разницы во времени.
3. Использование фильтра Twig ago
KnpTimeBundle предоставляет новый фильтр веток, а именно ago
, Этот фильтр ожидает в качестве цели объект DateTime, который ссылается на $since
(дата происхождения) и необязательный параметр $to
это указывает, откуда следует делать различие (другой объект DateTime), например:
{#
In this example we convert the now string to a date
The date can be retrieven from the controller etc.
#}
{% set myDate = "now"|date %}
{#
Modify our date by removing 4 days
#}
{% set myDate = myDate|date_modify('-4 day') %}
{# Displays according to your locale:
4 days ago
vor 4 Tagen
hace 4 días
etc
#}
{{ myDate|ago}}
{#
And if you need to differentiate the date from another day but not now
provide the first argument:
#}
{% set fromTomorrow = "now"|date_modify('+1 day') %}
{# Displays according to your locale:
5 days ago
vor 5 Tagen
hace 5 días
etc
#}
{{ myDate|ago(fromTomorrow)}}
Легко не так ли?
B. Самореализованный способ
Если вы счастливы сегодня и можете тратить время впустую, вы можете узнать что-то новое. Самостоятельно реализованный способ требует немного больше времени для реализации, но если вы не можете установить сторонний пакет, тогда это ваш лучший вариант.
1. Создайте расширение Twig_Extensions_Extension_Date
Первое, что вам нужно сделать, это создать в своем проекте Twig_Extensions_Extension_Date
расширение в вашем проекте. Этот класс относится к официальное продление даты Twig Фабьен Потенсье. Преимущества следующего класса в том, что он также может использовать модуль-переводчик Symfony, поэтому он похож на пакет первого шага.
Создайте файл расширения, а именно Twig_Extensions_Extension_Date.php
в некотором каталоге вашего приложения и измените пространство имен в соответствии с вашим. В этом случае мы создаем класс внутри Extensions
папка в AppBundle
:
'year',
'm' => 'month',
'd' => 'day',
'h' => 'hour',
'i' => 'minute',
's' => 'second',
);
/**
* @var TranslatorInterface
*/
private $translator;
public function __construct(TranslatorInterface $translator = null)
{
$this->translator = $translator;
}
/**
* {@inheritdoc}
*/
public function getFilters()
{
return array(
new Twig_SimpleFilter('time_diff', array($this, 'diff'), array('needs_environment' => true)),
);
}
/**
* Filter for converting dates to a time ago string like Facebook and Twitter has.
*
* @param Twig_Environment $env a Twig_Environment instance
* @param string|DateTime $date a string or DateTime object to convert
* @param string|DateTime $now A string or DateTime object to compare with. If none given, the current time will be used.
*
* @return string the converted time
*/
public function diff(Twig_Environment $env, $date, $now = null)
{
// Convert both dates to DateTime instances.
$date = twig_date_converter($env, $date);
$now = twig_date_converter($env, $now);
// Get the difference between the two DateTime objects.
$diff = $date->diff($now);
// Check for each interval if it appears in the $diff object.
foreach (self::$units as $attribute => $unit) {
$count = $diff->$attribute;
if (0 !== $count) {
return $this->getPluralizedInterval($count, $diff->invert, $unit);
}
}
return '';
}
protected function getPluralizedInterval($count, $invert, $unit)
{
if ($this->translator) {
$id = sprintf('diff.%s.%s', $invert ? 'in' : 'ago', $unit);
return $this->translator->transChoice($id, $count, array('%count%' => $count), 'date');
}
if (1 !== $count) {
$unit .= 's';
}
return $invert ? "in $count $unit" : "$count $unit ago";
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'date';
}
}
2. Добавить локаль приложения и включить переводчик
Обычно в каждом приложении Symfony по умолчанию локаль уже существует, и она по умолчанию en
(английский). Это значение используется во всем приложении, а не только в комплекте. Если он не существует, укажите для параметра locale идентификатор вашего языка:
parameters:
locale: en
# Or the locale of your language e.g : es,de,nl,pt,pl etc
Далее вам нужно включить переводчик, потому что он обычно комментируется, поэтому убедитесь, что вы установили переводчик в app/config/config.yml
Файл не закомментирован, и в качестве запасного варианта используется предыдущий объявленный параметр локали:
framework:
translator: { fallbacks: ['%locale%'] }
Как только это будет сделано, вы сможете использовать модуль переводчика в своем добавочном номере.
3. Зарегистрируйте расширение
Далее, зарегистрируйте расширение с помощью службы переводчика в качестве аргумента и укажите путь к классу предыдущего шага:
services:
twig.extension.date:
# the namespace with the name of the Twig Extensions created class
class: AppBundle\Extensions\Twig_Extensions_Extension_Date
arguments: ["@translator"]
tags:
- { name: twig.extension }
4. Создание файлов перевода
Следующим шагом вам нужно создать файлы перевода, однако для таких ленивых разработчиков, как я, всегда есть способ сделать все просто. Файлы перевода в этом случае будут в формате xliff, потому что мы можем копировать переводы KnpTimeBundle, и поэтому нам не нужно будет писать наши собственные файлы перевода. Однако обратите внимание, что пространство имен в KnpTimeBundle
время, но в этом расширение date
из-за предоставленного названия услуги twig.extension.date
,
Идти к файлы перевода KnpTimeBundle здесь и выберите те, которые вам нужны, и скопируйте их в app/Resources/translations/
папка вашего проекта (если папка переводов не существует, то создайте ее). Например, следующий файл (app/Resources/translations/date.de.xliff
) обеспечивает перевод наших дат на немецкий язык:
Важный
Обратите внимание, что id
каждого trans-unit
это строка В хранилище KnpTimeBundle идентификаторы являются числами, поэтому обязательно измените идентификатор на содержание атрибута источника, в противном случае Symfony не найдет ничего для перевода. Имя файлов xliff должно соответствовать шаблону имени файла (в этом случае) date..xliff
,
diff.ago.year
vor einem Jahr|vor %count% Jahren
diff.ago.month
vor einem Monat|vor %count% Monaten
diff.ago.day
vor %count% Tag|vor %count% Tagen
diff.ago.hour
vor einer Stunde|vor %count% Stunden
diff.ago.minute
vor einer Minute|vor %count% Minuten
diff.ago.second
vor einer Sekunde|vor %count% Sekunden
diff.empty
jetzt
diff.in.second
in einer Sekunde|in %count% Sekunden
diff.in.hour
in einer Stunde|in %count% Stunden
diff.in.minute
in einer Minute|in %count% Minuten
diff.in.day
in einem Tag|in %count% Tagen
diff.in.month
in einem Monat|in %count% Monaten
diff.in.year
in einem Jahr|in %count% Jahren
5. Используйте фильтр time_diff в представлениях
Точно так же, как делает фильтр назад из KnpTimeBundle, time_diff
фильтр ожидает в качестве цели объект DateTime, который ссылается на $since
(дата происхождения) и необязательный параметр $to
это указывает, откуда следует делать различие (другой объект DateTime), например:
{#
In this example we convert the now string to a date
The date can be retrieven from the controller etc.
#}
{% set myDate = "now"|date %}
{#
Modify our date by removing 4 days
#}
{% set myDate = myDate|date_modify('-4 day') %}
{# Displays according to your locale:
4 days ago
vor 4 Tagen
hace 4 días
etc
#}
{{ myDate|time_diff}}
{#
And if you need to differentiate the date from another day but not now
provide the first argument:
#}
{% set fromTomorrow = "now"|date_modify('+1 day') %}
{# Displays according to your locale:
5 days ago
vor 5 Tagen
hace 5 días
etc
#}
{{ myDate|time_diff(fromTomorrow)}}