Контент


Новые возможности роутинга

Наверняка вы не раз обращали внимание на адреса записей в блогах (например, http://brotkin.ru/2009/02/12/что-то-там). Если использовать стандартный роутинг Kohana (а именно контроллер/метод/параметр), такого мы не добьемся. Я предлагаю рассмотреть дополнительный модуль Router3.

Наверняка вы читали статью о роутинге в Kohana v2.3, все описано красиво, однако приведенные там куски кода запускаться отказывались. Дело в том, что было решено перенести данный механизм в полностью переработанную «трешку» (Kohana v3.0), а в 2.3 довольствоваться старым роутингом. Однако Kohana v3.0 выйдет еще не скоро, а красивые ЧПУ хочется уже сейчас. Поэтому разработчики предоставили нам модуль Router3 (скачать его можно отсюда, нажав внизу на ссылку «Zip Archive»). Как и прочие модули, он подключается в config/config.php, необходимо для переменной $config['modules'] ручками прописать что-то вроде такой строки:

   MODPATH.'router3',   // Routing like Kohana v.3

Что он может-то?

Давайте посмотрим на конфигурационный файл modules/router3/config/routes.php (его необходимо будет скопировать в папку application/config/):

<?php defined('SYSPATH') or die('No direct access');
 
// Remove the standard default route
unset($configuration['_default'], $config['_default']);
 
$config['default'] = array
(
	'uri' => ':controller/:method/:id',
 
	'defaults' => array
	(
		'controller' => 'welcome',
		'method' => 'index',
		'id' => FALSE,
	),
);

В глаза бросается, что вместо однострочного правила появился целый массив условий. Ключ ‘uri‘ описывает составные части пути, каждая часть предваряется двоеточием. Ключ ‘defaults‘ содержит значения по умолчанию (в приведенном примере перенаправление пойдет на welcome/index).

Вы заметили, что в router3 для указания муршрутов по умолчанию используется ключ default, а не _default? Не перепутайте.

Однако это не все. Существуют дополнительные параметры:

  • regex — позволяет указать регулярное выражение, которое будет применено для проверки отдельных компонентов URL.
  • prefix — для любого компонента URL (кроме метода) можно добавить префикс.
  • request — если указать этот параметр, правило будет использоваться только для такого вида запросов. Может принимать значения, допустимые для $_SERVER['REQUEST_METHOD'] (‘get’, ‘head’, ‘post’, ‘put’) или ‘cli’, если скрипт запущен из командной строки. К сожалению, необходимо указывать этот параметр именно в нижнем регистре, иначе правило будет игнорироваться (судя по всему, невнимательность разработчиков).

В ходе экспериментов выяснилось, что если добавить к контроллеру префикс со знаком подчеркивания, то контроллер найден не будет. Например, при полученном в итоге имени ‘some_controller’ на самом деле система попробует открыть файл в controllers/some/controller.php, а не в controllers/some_controller.php. Все дело в том, что в новых версиях фреймворка можно будет использовать поддиректории для контроллеров (в качестве разделителя выступает как раз знак подчеркивания), но в 2.3.1 это еще не поддерживается. Так что если вы все же захотите использовать префиксы или в имени контроллера присутствует данный символ — имейте в виду, возможно придется поработать напильником над файлом router.php или пересмотреть принципы именования своих контроллеров.

Перейдем к практической части

Давайте реализуем простенькую задачу: после прошлых статей у нас есть возможность авторизоваться и регистрироваться на сайте. Однако URL выглядят довольно длинными (http://localhost/auth/login к примеру). Давайте их укоротим с помощью router3:

// файл config/routes.php
$config['auth'] = array
(
  'uri' => ':method',
 
  'defaults' => array
  (
    'controller' => 'auth',
  ),
  'regex' => array
  (
    'method' => '(login|logout|register|profile)',
  )
);

Т.е. теперь если пользователь вводит один из перечисленных методов, модуль его автоматически направит к контроллеру Auth_Controller. Если же метод не подходит ни под какой из перечисленных, правило не сработает. Ну и напоследок еще одна вкусность — Reverse Routing. Это возможность генерировать URL исходя из используемого правила. Например, мы использовали в представлении views/header/guest.php такой способ формирования ссылки:

<a href='<?=url::base()?>login'><?=Kohana::lang('auth.welcome_login')?></a>


, а теперь можем сделать так:

<a href='<?=url::base().Router::uri('auth', array('method'=>'login'))?>'><?=Kohana::lang('auth.welcome_login')?></a>

Первым параметром мы указали имя правила, а далее в массиве передаем значения известных нам компонентов URL. Таким образом, если вдруг поменяется принцип перенаправления на авторизацию (например, мы решим использовать URL вида http://localhost/user/login), нам не придется менять по всем шаблонам тексты ссылок, а всего лишь отредактировать правило в routes.php.

Не прощаюсь

Вы возможно скажете: «а как же ссылки вида /2009/02/12/что-то-там?». Собственно говоря, данная статья — всего лишь вступление. В ближайшее время планируется несколько статей, посвященных дальнейшему развитию нашего блога (Blog_Controller), который мы начали создавать ранее, и с моделями которого мы немного поигрались в ORM.

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Опубликовано в учебник.

Теги: , , , .


Комментарии (11)

Будьте в курсе обсуждения, подпишитесь на RSS ленту комментариев к этой записи.

  1. Xobb пишет:

    Отлично! Очень пригодилось. Приятно видет русского блогера на поддержке этого чудесного фреймворка.

  2. BIakaVeron пишет:

    Рад видеть завсегдатая оф.сайта :) Вместе проще и веселее продираться сквозь дебри неописанных возможностей.

  3. jleft.ru/ пишет:

    Да, роуты точно не помешало бы расширить.

    Это сами писали или откуда-то ?

  4. BIakaVeron пишет:

    Упомянутая в самом начале статья заинтриговала, но после попытки соорудить нечто подобное оказалось, что надо разбираться с отдельным модулем, где не все так просто :)

  5. jleft.ru/ пишет:

    Выжечь мои глаза :)
    Продолжим изучение ;)

  6. r0nin пишет:

    тоесть если у меня контроллеры находяться в дирректории controllers/admin теперь обращение к нему будет по урлу http://sitename/admin_controllername
    Так?

  7. BIakaVeron пишет:

    Именно. В данный момент я таким вот образом делаю доступ к админской части модулей (в контроллерах сделал папку admin и в нее кладу контроллеры):

    $config['admin'] = array
    (
    	'uri' => 'admin/:controller/:method/:id',
     
    	'defaults' => array
    	(
    		'controller' => 'dashboard',
    		'method' => 'index',
    		'id' => FALSE,
    	),
    	'prefix' => array
    	(
    		'controller' => 'admin_',
    	)
    );

    Такой вариант мне нравится больше, чем организация поддомена вида admin.localhost.

  8. r0nin пишет:

    Мне больше нравилось так, как в родном роутинге сделано.
    Что бы адрес получался типа admin/controllername. А то как то не привычно.

  9. BIakaVeron пишет:

    В приведенном мной примере именно так и получается. В адресной строке браузера никаких admin_controllername не появится, только старый-добрый admin/controllername.

    А разве в старом роутинге можно было указывать подпапки для контроллеров? Насколько я помню, перенаправить URL вида admin/controller к контроллеру admin_controller он мог, но насчет поддиректорий я сомневаюсь… Хотя глубоко я его не разбирал, так как почти сразу пересел на router3 :)

  10. cwer пишет:

    теперь оттуда скачать нельзя((
    да и что-то с пагинатором то что я качал не хочет работать(

  11. BIakaVeron пишет:

    Изменилась структура раздела Dev. Исправил ссылку.



Можно включить подсветку кода: <code><pre lang="">...</pre></code>
Разрешены некоторые HTML теги

или используйте trackback.