Укажите правила маршрута и маршрут к различным компонентам

Я знаю, как указать маршруты для компонентов страницы, используя 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});

Не слишком элегантно, но похоже, что оно делает свою работу.

Другие вопросы по тегам