Блог Мазепина Василия

Пишу о том, что кажется интересным

Кастомные функции Twig в Symfony

2015-03-11 13:28 | Комментарии

Доброго времени суток, коллеги и гости… Недавно в одном из своих проектов мне понадобилось создать пользовательскую функцию, которая использовалась бы на стороне twig-шаблонизатора. Задача состояла в следующем. Необходимо было отрисовать иерархическую структуру. У каждой ноды в качестве родителя выступает такая же по типу нода, при этом у каждой ноды может быть несколько детей. На стороне модели данных детей и родителя можно взять так:

1
2
$category->getChildren(); //Получаем коллекцию детей
$category->getParent(); //Получаем родителя

В поисках путей создания такой функции я нашел несколько мануалов(некоторые из них даже правдивые), и думаю не будет лишним разместить объяснение и у себя. Так вот, в корне своего Бандла я создаю директорию Twig, где буду размещать все свои расширения шаблонизатора. В качестве расширений могут выступать функции, фильтры, и кое что еще. Но нас интересуют функции. Я создал файл-класс такого формата:

TreeExtension.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php

namespace SmartBoss\StoreBundle\Twig;

class TreeExtension extends \Twig_Extension {

  public function getFunctions()
  {
      $function = function($tree) {
          $result = $this->build_tree($tree);
          return $result;
      };
      return array(
          new \Twig_SimpleFunction('tree', $function),
      );
  }

  /**
  * Строит дерево категорий
  * @param array $cats
  * @return string
  */
  public function build_tree(array $cats){
      $tree = '<ul>';
      foreach($cats as $cat){
          $tree .= '<li>'.$cat->getName();
          $childs = $cat->getChildren()->toArray();
          $tree .=  $this->build_tree($childs);
          $tree .= '</li>';
      }
      $tree .= '</ul>';
      return $tree;
  }
  public function getName()
  {
      return 'tree';
  }
}

Как видно из примера, я в качестве параметра функции даю массив нод, и сама иерархия будет рисоваться «сверху вниз». Как только функция описана, ее теперь нужно «познакомить» с нашим шаблонизатором, ведь пока что это незнакомая нашему шаблонизатору функция. Для того, чтобы твиг понимал нашу функцию, в файле services.yml я пропишу вот такое заклинание:

services.yml
1
2
3
4
5
6
services:
  twig.extension.tree:
          class: PathTo\Bundle\Twig\TreeExtension
          public: true
          tags:
              - { name: twig.extension }

После вот таких манипуляций, наша функция стала прекрасно работать, и мы добились нужных нам результатов.

1
{{ tree(categories) | raw }}
Надеюсь, статья была вам полезна, хорошего вам настроения и безбажного кода)

Комментарии