SonataAdminBundle: как добавить произвольную страницу к сущности

У меня часто возникает необходимость добавлять произвольные страницы (например для ajax’a), связанные с конкретной сущностью, или для целого класса сущностей.

Добавление страницы начинается с добавления роута в админ классе. За это отвечает метод configureRoutes:

<?php
    protected function configureRoutes(RouteCollection $collection)
    {
        $collection->add('members', $this->getRouterIdParameter() . '/members');
        $collection->add('getProjects');
    }

В примере я рассмотрел два случая:

  1. Роут привязан к конкретной сущности, о чем свидетельствует наличие метода $this->getRouterIdParameter() в роуте, на место которого будет подставлен id сущности, в итоге на страницу можно будет попасть по роуту вида bla/bla/12/members
  2. Роут привязан не к конкретной сущности, а к админ классу, на страницу можно попасть по роуту вида bla/bla/getProjects
Далее в дело вступает контроллер для админ класса, в котором необходимо добавить соответствующий action:
<?php
    public function membersAction($id = null)
    {
        $id = $this->get('request')->get($this->admin->getIdParameter());

        $object = $this->admin->getObject($id);

        if (!$object) {
            throw new NotFoundHttpException(sprintf('unable to find the object with id : %s', $id));
        }
        ...
    }

    public function getProjectsAction()
    {

        $choice = array();

        ...

        return $this->renderJson($choice);

    }
Первый action предназначен для работы с конкретной сущностью, пример получения самой сущности взят из стандартного editAction(). Второй action предназначен для вывода json, к счастью в сонате предусмотрен соответствующий метод.
Напомню, что контроллер указывается в аргументах, в описании сервиса админ класса. Более подробно об этом я писал в другой статье.
 Ну и последний шаг - создание шаблона для страницы. Если страницы без кастомного дизайна, и вы намерены придерживаться общего стиля Sonata, то вам необходимо унаследовать стандартный шаблон сонаты:
\{\% extends 'SonataAdminBundle:Core:dashboard.html.twig' %}

\{\% block content%}
      blabla
\{\% endblock%}
Разумеется, вы можете свободно переопределять такие блоки как javascripts и stylesheets. На этом вроде все =)