Если вы делаете более-менее серьезное веб-приложение на symfony, стоит задуматься о том, как вы будете предоставлять доступ до админки вашего проекта. Стандартный раутинг бэкенда, или любого другого вторичного приложения, может привести к недоумению неискушенного пользователя. Клиенты не привыкли видеть в строке адреса http://mysite.ru/backend.php/posts/. Да и вообще эстетической красоты урлов ради, стоит подумать о методах облагораживания ссылок.
Раутинг с использованием субдомена
Ресурс symfony-check.org предлагает решить проблему следующим тривиальным способом.
Добавить в конфигурацию виртуального хоста директиву
ServerAlias admin.mysite.ru
или другим способом заставить веб сервер отвечать по субдомену.
Добавить в .htaccess рерайт по префиксу "admin." на backend.php
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{HTTP_HOST} ^admin\..* RewriteRule ^(.*)$ backend.php [QSA,L]
поправить настройки в apps/backend/config/settings.yml
prod: .settings: no_script_name: true
и почистить кеш
php symfony cc
Таким образом, мы без особых усилий получим реально красивые урлы. Какие недостатки есть у этого способа? При генерации урлов из бэкенда, используя cross-application routing, мы должны генерить абсолютные урлы с именем домена фронта. Для этого можно, например, хранить имя домена где-то в конфиге.
Раутинг с использованием подпапки
Лично мне больше нравится, когда админку можно обнаружить в сабфолдере /admin/. Поэтому я начал думать как лучше реализовать это решение.
Первое что надо сделать — добавить правила в .htaccess
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_URI} ^/admin(/?|/.*$) RewriteRule ^(.*)$ backend.php [QSA,L]
и, также как и в прошлом способе, поправить apps/backend/config/settings.yml
prod: .settings: no_script_name: true
Далее надо как-то заставить экземпляры раутинга работать с подпапкой. Сначала в голову пришла идея добавить префикс /admin/ всем экземплярам.
Проблема в том, что невсегда разработчики плагинов дают возможность редактирования своих раутингов. Таким образом, наиболее очевидный вариант не подходит, если вы планируете использовать множество плагинов.
Я долго думал как справиться с этой проблемой. В результате решение нашел на одном из блогов.
Автор предлагает наследовать класс управления раутингов symfony. Правда используя его код, я так и не смог добиться нормальных результатов в dev среде. Так что привожу измененный код, который работает у меня.
class sfBackendRouting extends sfPatternRouting { public function initialize(sfEventDispatcher $dispatcher, sfCache $cache = null, $options = array()) { $options['context']['prefix'] .= isset($options['prefix']) ? $options['prefix'] : ''; parent::initialize($dispatcher, $cache, $options); } public function getRouteThatMatchesUrl($url) { if(isset($this->options['prefix'])) { if(strpos($url, $this->options['prefix']) === 0) $url = substr($url, strlen($this->options['prefix'])); else return false; } if($url == '') { $url = '/'; } return parent::getRouteThatMatchesUrl($url); } }
Далее надо поправить конфиг apps/backend/config/factories.yml
all: routing: class: sfBackendRouting param: generate_shortest_url: true extra_parameters_as_query_string: true prefix: /admin
Чистим кеш
php symfony cc
и voil? — наш бэкенд теперь отвечает по подпапке.