Symfony 3 - Маршрут, исключающий начало определенного пути (url)

Я создаю приложение с Symfony 3.2.9, и я хотел бы сделать панель администратора для управления приложением. Приложение работает как CMS, поэтому создает новые страницы с URL-адресами, такими как domain.com/pagename1, а также domain.com/pagename1/subpagelevel2 и т. д. Проблема заключается в том, что я хочу создать URL-адрес для панели администратора, и URL-адрес должен выглядеть так: domain.com/admin, но также панели администратора нужны некоторые подстраницы, такие как domain.com/admin/manage или domain.com/admin/manage/ редактировать/1 т.д.

Я создал DefaultController с маршрутизацией, например:

/**
 * @Route("/", name="homepage")
 */

и AdminController с маршрутизацией, например:

/**
 * @Route("/admin", name="admin")
 */

Проблема в том, что когда я хочу динамически создавать новую подстраницу приложения, мне нужно создать маршрутизацию, например:

/**
 * @Route("/{page}")
 */

Но это перезаписывает подстраницы моей панели администратора (например, domain.com/admin/manage).

Можно ли исключить или перезаписать путь из DefaultController по умолчанию с помощью AdminController? Я хочу иметь возможность создавать все URL-адреса из DefaultController, кроме путей, начинающихся как domain.com/admin ... и так далее.


person mcgoo    schedule 06.08.2017    source источник


Ответы (4)


Из документации в https://symfony.com/doc/current/routing.html вы можете использовать параметр requirements, чтобы указать более строгое соответствие

Я думаю, что-то вроде этого должно работать:

Контроллер по умолчанию:

/**
 * @Route("/", name="homepage")
 */

Админконтроллер:

/**
 * @Route("/admin", name="admin")
 */

Другой контроллер:

/**
 * we exclude page=admin from this controller
 * @Route("/{page}", requirements={"page": "^(?!admin).+"}))
 */
person Simonluca Landi    schedule 06.08.2017

Маршруты ищутся в том порядке, в котором они перечислены, поэтому поместите наиболее общий в конец списка, и он найдет и будет использовать /admin перед /{page}.

Например, один из моих последних маршрутов внизу app/conf/routing.yml:

# http://symfony.com/doc/current/routing/redirect_trailing_slash.html
remove_trailing_slash:
    path: /{url}
    defaults:
        _controller: AppBundle:Default:removeTrailingSlash
    requirements:
        url: .*/$
    methods: [GET]
person Alister Bulman    schedule 06.08.2017
comment
Спасибо за помощь. Я изменяю файл routing.yml и теперь он выглядит так: admin_show: path: /admin/{slug} defaults: { _controller: AppBundle:Admin:index } page_show: path: /{slug} defaults: { _controller: AppBundle:Default:index } Я получаю Не найден маршрут для ..., что-то не так в моем коде? Может быть, мне стоит что-то изменить в моем @Route над контроллером? /** * @Route("/", name="cms") */ - person mcgoo; 06.08.2017
comment
Если вы хотите использовать только аннотации @Route, вам нужно удалить определения path из .yml и поместить resource: @bundle-path/.../...Controller.php, чтобы система маршрутизации использовала их. - person Alister Bulman; 06.08.2017

Самый чистый в вашем случае использования:

Почему бы просто не создать отдельный пакет для администратора и не поставить префикс в маршрутах AdminBundle?

Зависеть от порядков маршрутизации и/или REGEX в маршрутах не рекомендуется только во избежание создания пакетов. Это то, для чего были задуманы Bundles.

приложение/config/routing.yml

admin:
  resource: "@AdminBundle/Controller/"
  type:     annotation
  prefix:   /admin

Тогда все контроллеры/маршруты в AdminBundle будут работать с префиксом /admin.

Например, IndexController/DefaultController/WhatEverController с этим маршрутом внутри AdminBundle:

 /**
 * @Route("/")
 */
public function indexAction()
{
    //My code
}

Будет соответствовать «/admin» вместо «/»

И:

 /**
 * @Route("/{page}")
 */
public function indexAction()
{
    //My code
}

Будет соответствовать "/admin/{page}" вместо "/{page}"

person sh4    schedule 07.08.2017

Начиная с Symfony 5.1, вы можете определить приоритет маршрута :

/**
 * @Route("/admin", name="admin", priority=10)
 */

/**
 * @Route("/{slug}", name="pages", priority=99)
 */
person Asenar    schedule 27.04.2021