Роутинг — Часть 1

Комментарии: 56  Просмотры: 49 946

Вот мы и дошли до очень важной темы — темы Роутинга в Кохане. Хочу поблагодарить Семёна c phpforum.ru за разъяснение некоторых нюансов в этой достаточно сложной теме. Теперь можно приступать.
Роутинг — это процесс определения маршрута внутри нашего приложения после поступления запроса. Т.е. после того, как мы переходим по ссылке в адресной строке, происходит ее обработка, согласно определенным правилам. Мы с вами уже немного работали с роутами, когда прописывали свой Контроллер Page вместо Контроллера Welcome. И даже добавляли в него свои методы (кто забыл, смотрите урок Заготовка для блога — Часть1). Таким образом при переходе по ссылке http://kohana у нас вызывался Контроллер Page и метод index, а вот для вызова методов about и contacts нужно было уже писать http://kohana/page/about и http://kohana/page/contacts, т.е. название Контроллера, а потом название метода. Это не очень красиво. Но если написать в адресной строке http://kohana/about, то вместо нашей страницы «О сайте» мы все равно получим главную страницу. Еще надо отметить, что как-то не очень хорошо, когда все страницы лежат в одном Контроллере, тем более такие. Все-таки основная страница — это основная страница. Там будут выводиться статьи и всяческая динамическая информация вроде количества просмотров, количества комментариев и так далее. А страницы «О сайте» и «Контакты» — это статика, обычно их один раз написали и все. Давайте вынесем их в отдельный Контроллер. Для этого в папке с двумя нашими Контроллерами создадим еще один с названием static.php и со следующим кодом (я скопировал его из Контроллера Page, а там удалил):

<?php defined('SYSPATH') or die('No direct script access.');
 
class Controller_Static extends Controller_Common {
 
    // Страница о сайте
    public function action_about()
    {
        $content = View::factory('/pages/about');
        $this->template->content = $content;
    }
 
    // Страница контактов    
    public function action_contacts()
    {
        $content = View::factory('/pages/contacts');
        $this->template->content = $content;
    }	
 
} // End Static

В этом Контроллере пусть у нас будут такие вот статичные страницы (О сайте, Контакты, FAQ, Правила, Друзья итд). В принципе мы уже можем работать с этими страницами. Если доступ к главной странице таким же и остался — через http://kohana или http://kohana/page, то для этих страниц ссылки будут http://kohana/static/about и http://kohana/static/contacts. То есть сменили «шило на мыло». Было page, стало static. Как избавиться от сегмента static ? В этом нам помогут роуты. Для начала давайте рассмотрим структуру роута на примере роута по умолчанию (находится в файле bootstrap.php в самом низу).

Route::set('default', '(<controller>(/<action>(/<id>)))')
	->defaults(array(
            'controller' => 'page',
            'action'     => 'index',
	));

Здесь мы видим статический метод set, которому передаются два параметра. Первый параметр — это название данного роута. Второй — какое-то правило. На самом деле есть еще третий параметр, который используется по необходимости — это регулярное выражение. С первым параметром все ясно. Второй параметр выглядит у нас так:

(<controller>(/<action>(/<id>)))

Косая черта служит для разделения сегментов адреса друг от друга (в принципе вместо косой черты можно сделать что-то другое, подчеркивание например). Угловые скобки <> указывают, что то, что попадет в них, будет присвоено переменной с именем внутри этих скобок (если этот момент пока непонятен, не волнуйтесь, позже я покажу это на примере). Этих скобок может и не быть, если требуется, чтобы сегмент адреса четко совпадал с роутом (это мы рассмотрим чуть ниже). Круглые скобки означают, что данный параметр необязателен. Т.е. он может быть, а может и не быть. Вы можете сами это проверить. Главная страница будет работать по такому адресу http://kohana/page/index и по такому http://kohana/page и даже по такому http://kohana. Следовательно, чтобы сделать указание Контроллера обязательным, второй параметр нужно изменить на такой:

<controller>(/<action>(/<id>))

Естественно, необходимо соблюдать вложенность скобок. Не может быть, например, необязательный Контроллер, но обязательный Id. Думаю с этим все понятно.
Как Кохана определяет, какой Контроллер вызывать, если мы не указали его в адресной строке, например перешли по адресу http://kohana. Для этого у роута есть функция defaults, в которую передается некий массив параметров в виде ключ — значение, где ключом будет название параметра, а значением, как ни странно, его значение. Нам пока достаточно знать два параметра. Это controller — принимающий название Контроллера, который будет запущен и action — название метода этого Контроллера. Вот мы и написали туда наш Контроллер page и наш метод index, которые собственно и срабатывают. Но вернемся к нашей задачке со статическими страницами. Одним из вариантов ее решения будет два новых роута:

Route::set('about', 'about')
	->defaults(array(
            'controller' => 'static',
            'action'     => 'about',
	)); 
 
Route::set('contacts', 'contacts')
	->defaults(array(
            'controller' => 'static',
            'action'     => 'contacts',
	));

Попробуйте зайти на http://kohana/about или http://kohana/contacts. Все должно работать (не забудьте поправить ссылки в шаблоне). Получается, что когда вы переходите по ссылке http://kohana/about, то сегмент с about попадает под правило первого роута, поэтому вызывается Контроллер static и Метод about. Со второй ссылкой аналогично, только теперь уже срабатывает второй роут.
Обратите внимание, угловые скобки мы не использовали. Т.е. нам нужно именно четкое совпадение или с about, или с contacts. Если все же использовать угловые скобки, то мы все время будем попадать на страницу «О сайте», причем даже при вводе таких адресов как http://kohana/faq так как будет выполняться первый же роут, как соответствующий условию. Просто в параметр about попадет слово «faq», которое потом можно получить например в Базовом Контроллере.
В следующем уроке мы перепишем этот пример с использованием регулярного выражения и обойдемся одним роутом вместо двух, а также создадим еще несколько роутов для понимания (или закрепления) материала из этого урока.

<< Назад | Вперед >> | Обсудить на форуме


К записи оставлено 56 коммент.

Прекрасно, — я это понимаю.
Но не понял что и куда прописывать, где и какой код должен остаться и почему.
Главная страница прекрасно отображается, а вот две остальные, — не хотят, пишут ошибки. Значит я так и не понял, (ступил) наверное, что и куда надо прописать, что бы все работало.
Перечитал эту статью уже в сотый раз, а воз и ныне там..!

В контроллере Controller_Static два метода — action_about() и action_contacts(). В контроллере Controller_Page только action_index(). Если не работает, может не в этом проблема ? Посмотрите названия файлов, названия контроллеров, роуты. Заготовка для блога у вас работала ? Индекс из адресной строки убирали ?

«В данном случае мы разделяем контроллер на два, чтобы один отвечал за статичные страницы (контакты и о сайте), а другой за динамические.»

Вот я и интересуюсь, что осталось в page.php?
И как оно выглядит?

<?php defined('SYSPATH') or die('No direct script access.');
 
class Controller_Page extends Controller_Common {
 
    // Главная страница
	public function action_index()
    {
        $content = View::factory('/pages/show');
        $this->template->content = $content;
    }
 
} // End Page

Да, заготовка работала исправно!
Я все так и сделал, и как бы все было понятно, ясно.
Но на данном этапе, что-то пошло ни так.
Не работают: kohana/page/about и kohana/page/contacts

в прописал так: bootstrap.php

<<defaults(array(
‘controller’ => ‘static’,
‘action’ => ‘about’,
));

Route::set(‘contacts’, ‘contacts’)
->defaults(array(
‘controller’ => ‘static’,
‘action’ => ‘contacts’,
));

Route::set(‘default’, ‘((/(/)))’)
->defaults(array(
‘controller’ => ‘page’,
‘action’ => ‘index’,
)); >>>

в static.php, как было указанно в статье.

в page.php
<<< template->content = $content;
}

} // End Page >>>

Код комменты съели. Но думаю, что вы поймете из остатков.

Вообще адреса должны быть
http://kohana/about или http://kohana/contacts
Про это же написано в самом низу урока. Для этого мы здесь роуты и разбирали, чтобы лишние сегменты адреса убрать.

Все, огромное спасибо, — разобрался!
Отлично работает!
С Уважением, msgraf!

Убрал в main.php /page для about и contacts.
И оставил все скобки для:
Route::set(‘default’, ‘((/(/)))’)
Только так заработало.
По другому не хочет. Выдает ошибки.

Все пока шло отлично, но вот в этот момент
«если написать в адресной строке http://kohana/about, то вместо нашей страницы «О сайте» мы все равно получим главную страницу»
я получаю «HTTP_Exception_404 [ 404 ]: The requested URL about was not found on this server» вместо главной страницы. Ткните пожалуйста носом где я пропустил)

Здравствуйте. Спасибо за понятные и доступные объяснения. Вот только у меня вопрос появился.
Существует ли встроенный механизм автоматического создания рутов? Например, пишу я движок, и надо мне из админки создать новый раздел, или, как тут в примере, новую статическую страницу. И надо это сделать средствами движка. Прийдется ли создавать код вставки кода добавления рута (извиняюсь за тавтологию) в файл bootstrap.php или в кохане уже реализован аналогичный механизм?

здравствуйте у меня не работает роут помогите пожалюста я устоновил язык может из за этого ?

bootstrap.php :

// Set the routes. Each route must have a minimum of a name, a URI and a set of

// user route
Route::set(‘user’, ‘/user(/)’)
->defaults(array(
‘controller’ => ‘user’,
‘action’ => ‘index’,
));

// catching 404 error
//set_exception_handler(array(‘Exceptionhandler’, ‘handle’));

controller/user.php :

class Controller_User extends Controller_Template {

public $template = ‘template’;

public function action_register()
{
include_once(«./application/blocks/reading.php»);

$data['language']=$lang;

$this->template->body=View::factory(‘userreg’,$data)->render();

}

views/template.php:

views/userreg.php:

<form action="/user/checkregister» method=»post»>

<input type="text" name="name" value="» />
<input type="text" name="email" value="» />
<input type="text" name="tel" value="» />
<input type="text" name="mtel" value="» />
<input type="text" name="adress" value="» />
<input type="text" name="login" value="» />

Пожалуйста на форум. Или здесь обрамляйте код тегами pre, когда пишете. А то половину кода потерло.



Оставить комментарий или два

Пожалуйста, зарегистрируйтесь для комментирования.