twig扩展

twig模板引擎默认提供了一些函数和标签,但是有时内置的函数满足不了要求时就需要对twig进行扩展了。

现在我们想让博客的评论时间显示为多久之前发布的,如:发布于3小时前。

之前在模板中渲染发布时间的用法是:{{ comment.created|date('l, F j, Y') }},而现在想变为:{{ comment.created|created_ago }}这种形式。

由于twig没有提供created_ago方法,因此这得我们自己实现。

新建文件src/Blogger/BlogBundle/Twig/Extensions/BloggerBlogExtension.php

  1. <?php
  2. namespace Blogger\BlogBundle\Twig\Extensions;
  3. /**
  4. * BloggerBlogExtension
  5. */
  6. class BloggerBlogExtension extends \Twig_Extension
  7. {
  8. /**
  9. * @return array
  10. */
  11. public function getFilters()
  12. {
  13. return array(
  14. 'created_ago' => new \Twig_Filter_Method($this, 'createdAgo'),
  15. );
  16. }
  17. /**
  18. * @param \DateTime $dateTime
  19. *
  20. * @return string
  21. */
  22. public function createdAgo(\DateTime $dateTime)
  23. {
  24. $delta = time() - $dateTime->getTimestamp();
  25. if ($delta < 0) {
  26. throw new \InvalidArgumentException("createdAgo is unable to handle dates in the future");
  27. }
  28. $duration = "";
  29. if ($delta < 60) {
  30. // Seconds
  31. $time = $delta;
  32. $duration = $time . " second" . (($time > 1) ? "s" : "") . " ago";
  33. } else if ($delta <= 3600) {
  34. // Mins
  35. $time = floor($delta / 60);
  36. $duration = $time . " minute" . (($time > 1) ? "s" : "") . " ago";
  37. } else if ($delta <= 86400) {
  38. // Hours
  39. $time = floor($delta / 3600);
  40. $duration = $time . " hour" . (($time > 1) ? "s" : "") . " ago";
  41. } else {
  42. // Days
  43. $time = floor($delta / 86400);
  44. $duration = $time . " day" . (($time > 1) ? "s" : "") . " ago";
  45. }
  46. return $duration;
  47. }
  48. /**
  49. * @return string
  50. */
  51. public function getName()
  52. {
  53. return 'blogger_blog_extension';
  54. }
  55. }

这里我们定义一个类继承自Twig_Extension。要创建自定义过滤器,只需要覆盖getFilters()方法即可。如果要创建自定义方法,则覆盖getFunctions()方法。

定义了扩展类之后再将其注册为一个服务,编辑文件src/Blogger/BlogBundle/Resources/config/services.yml

  1. services:
  2. blogger_blog.twig.extension:
  3. class: Blogger\BlogBundle\Twig\Extensions\BloggerBlogExtension
  4. tags:
  5. - { name: twig.extension }

现在就可以在模板中使用我们刚刚定义的created_ago过滤器了。更新模板,将{{ comment.created|date('l, F j, Y') }}替换成{{ comment.created|created_ago }}