本文概述
在许多Web应用程序和网站上, 你都可以查看日期并轻松阅读日期, 而无需知道今天是星期几, 也可以不知道哪一天是5月21日, 一月等。通常在浏览器中使用JavaScript即可实现此功能。所以有什么问题?用于格式化的库不是(通常)轻量级的, 你最终将获得至少3个库来实现类似的目的。如果你想在应用程序中实现这种功能, 而无需在视图上动态更新日期, 则可以在自己的服务器上执行此任务。
在本文中, 我们将向你展示两种显示时间格式的日期的方法:使用KnpTimeBundle(a)或实现Twig的Twig_Extensions_Extension_Date扩展。两者都提供相同的功能, 但是对于某些开发人员来说, 1的实现可能会更长一些, 因此由你决定哪种方法更容易实现。
A.捆绑(简单)方式
如果你不必担心应用程序的大小, 并且可以安装第三方捆绑软件, 则可以更轻松地实现目标(容易得多):
1.安装并注册KnpTimeBundle
我们正在谈论KnpTimeBundle。该捆绑包完成一项简单的工作:记录日期并返回友好的” 2小时前”类型的消息。要在你的Symfony项目中安装此捆绑包, 请在终端上执行以下命令:
composer require knplabs/knp-time-bundle
有关此捆绑包的更多信息, 请访问Github上的官方存储库。捆绑软件安装完成后, 请确保在Symfony内核(app / AppKernel.php)中启用捆绑软件:
<?php
// app/AppKernel.php
public function registerBundles()
{
$bundles = [
// ...
new Knp\Bundle\TimeBundle\KnpTimeBundle(), // ...
];
// ...
}
你已经准备好继续下一步。
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文件中的翻译器设置未添加注释, 并且回退使用先前声明的locale参数:
framework:
translator: { fallbacks: ['%locale%'] }
完成此操作后, 你将能够使用捆绑软件的前一个过滤器来显示时差的可读描述。
3.使用Twig ago过滤器
KnpTimeBundle即在以前公开了一个新的树枝过滤器。此过滤器期望将引用$ since的DateTime对象(起始日期)作为目标, 并使用可选参数$ 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扩展。此类是指Fabien Potencier对Twig进行的正式日期扩展。此类的优点是, 它也可以使用Symfony的翻译器模块, 因此它类似于第一步的捆绑软件。
在应用程序的某些目录上创建扩展文件, 即Twig_Extensions_Extension_Date.php, 并根据你的名称空间更改名称空间。在这种情况下, 我们将在AppBundle的Extensions文件夹内创建类:
<?php
namespace AppBundle\Extensions;
/**
* This file is part of Twig.
*
* (c) 2014 Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Symfony\Component\Translation\TranslatorInterface;
use Twig_Environment;
use Twig_SimpleFilter;
use Twig_Extension;
/**
* @author Robin van der Vleuten <robinvdvleuten@gmail.com>
*/
class Twig_Extensions_Extension_Date extends Twig_Extension
{
public static $units = array(
'y' => '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文件中的翻译器设置未添加注释, 并且回退使用先前声明的locale参数:
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中的名称空间是时间, 但由于服务twig.extension.date的提供者名称, 此扩展名中的日期是date。
转到此处的KnpTimeBundle的翻译文件, 然后选择所需的文件并将其复制到项目的app / Resources / translations /文件夹中(如果不存在translations文件夹, 则创建它)。例如, 以下文件(app / Resources / translations / date.de.xliff)用德语提供了我们日期的翻译:
重要
请注意, 每个反式交易单元的ID是一个字符串。在KnpTimeBundle的存储库中, id是数字, 因此请确保通过source属性的内容更改ID, 否则Symfony将找不到任何要翻译的项目。 xliff文件的名称必须遵循文件名模式(在这种情况下)日期。<lang-identifier> .xliff。
<?xml version="1.0"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="file.ext">
<body>
<trans-unit id="diff.ago.year">
<source>diff.ago.year</source>
<target>vor einem Jahr|vor %count% Jahren</target>
</trans-unit>
<trans-unit id="diff.ago.month">
<source>diff.ago.month</source>
<target>vor einem Monat|vor %count% Monaten</target>
</trans-unit>
<trans-unit id="diff.ago.day">
<source>diff.ago.day</source>
<target>vor %count% Tag|vor %count% Tagen</target>
</trans-unit>
<trans-unit id="diff.ago.hour">
<source>diff.ago.hour</source>
<target>vor einer Stunde|vor %count% Stunden</target>
</trans-unit>
<trans-unit id="diff.ago.minute">
<source>diff.ago.minute</source>
<target>vor einer Minute|vor %count% Minuten</target>
</trans-unit>
<trans-unit id="diff.ago.second">
<source>diff.ago.second</source>
<target>vor einer Sekunde|vor %count% Sekunden</target>
</trans-unit>
<trans-unit id="diff.empty">
<source>diff.empty</source>
<target>jetzt</target>
</trans-unit>
<trans-unit id="diff.in.second">
<source>diff.in.second</source>
<target>in einer Sekunde|in %count% Sekunden</target>
</trans-unit>
<trans-unit id="diff.in.hour">
<source>diff.in.hour</source>
<target>in einer Stunde|in %count% Stunden</target>
</trans-unit>
<trans-unit id="diff.in.minute">
<source>diff.in.minute</source>
<target>in einer Minute|in %count% Minuten</target>
</trans-unit>
<trans-unit id="diff.in.day">
<source>diff.in.day</source>
<target>in einem Tag|in %count% Tagen</target>
</trans-unit>
<trans-unit id="diff.in.month">
<source>diff.in.month</source>
<target>in einem Monat|in %count% Monaten</target>
</trans-unit>
<trans-unit id="diff.in.year">
<source>diff.in.year</source>
<target>in einem Jahr|in %count% Jahren</target>
</trans-unit>
</body>
</file>
</xliff>
5.在视图中使用time_diff过滤器
以与KnpTimeBundle的前一个过滤器相同的方式, time_diff过滤器期望将引用$ since(原始日期)的DateTime对象作为目标, 并使用可选参数$ 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)}}
编码愉快!
评论前必须登录!
注册