Укажите правила маршрута и маршрут к различным компонентам
Я знаю, как указать маршруты для компонентов страницы, используя Mason:: Plugin:: RouterSimple, например, учитывая URL:
/archives/2015/07
Я могу создать компонент archives.mc
как это:
<%class>
route "{year:[0-9]{4}}/{month:[0-9]{2}}";
</%class>
Archives for the month of <% $.month %>/<% $.year %>
и так же я могу создать news.mc
компонент, который будет обрабатывать URL:
/news/2012/04
и это хорошо (и очень элегантно!), но теперь я хочу иметь возможность обрабатывать URL-адреса, как показано ниже:
/john/archives/2014/12
/john/news/2014/03
/peter/news/2015/09
/bill/archives/2012/06
и т.д. Я знаю, что могу написать правила маршрута как:
<%class>
route "{user:[a-z]+}/archives/{year:[0-9]{4}}/{month:[0-9]{2}}", { action=> 'archives' };
route "{user:[a-z]+}/news/{year:[0-9]{4}}/{month:[0-9]{2}}", { action=> 'news' };
</%class>
но тогда запросы должны обрабатываться двумя разными компонентами. Как я могу направить запрос на разные компоненты? archives.mc
а также news.mc
Мейсон не будет соответствовать, потому что перед именем компонента стоит имя пользователя.
1 ответ
Проблема в том, что в то время как /archives/2014/12
может быть легко обработан /archives.mc
компонент, для URL, как /john/archives/2014/12
а также /bill/archives/2012/06
не ясно, куда поместить компонент архивов.
Мейсон попытается сопоставить следующие компоненты (это упрощенный список, см. Mason:: Manual:: RequestDispatch):
...
/john/archives.{mp,mc}
/john/dhandler.{mp,mc}
/john.{mp,mc}
но наконец...
/dhandler.{mp,mc}
Так что моя идея состоит в том, чтобы поставить dhandler.mc
компонент в корневом каталоге:
<%class>
route "{user:[a-z]+}/archives/{year:[0-9]{4}}/{month:[0-9]{2}}", { action=> 'archives' };
route "{user:[a-z]+}/news/{year:[0-9]{4}}/{month:[0-9]{2}}", { action=> 'news' };
</%class>
<%init>
$m->comp($.action.'.mi', user=>$.user, year=>$.year, month=>$.month);
</%init>
Если URL соответствует первому маршруту, он вызовет archives.mi
составная часть:
<%class>
has 'user';
has 'year';
has 'month';
</%class>
<% $.user %>'s archives for the month of <% $.month %>/<% $.year %>
(Я использовал .mi
компонент, поэтому он будет доступен только внутри).
Dhandler может быть улучшен (лучше регулярное выражение, может проверять пользователей из таблицы базы данных и отклонять запрос и т. Д.)
Поскольку мои архивы и новостные компоненты могут принимать данные POST/GET, и поскольку я хочу принимать любые данные, я могу просто передать все с помощью:
$m->comp($._action.'.mi', %{$.args});
Не слишком элегантно, но похоже, что оно делает свою работу.