Вот мы и дошли до очень важной темы — темы Роутинга в Кохане. Хочу поблагодарить Семёна 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», которое потом можно получить например в Базовом Контроллере.
В следующем уроке мы перепишем этот пример с использованием регулярного выражения и обойдемся одним роутом вместо двух, а также создадим еще несколько роутов для понимания (или закрепления) материала из этого урока.
<< Назад | Вперед >> |
Пожалуйста, зарегистрируйтесь для комментирования.
Прекрасно, — я это понимаю.
Но не понял что и куда прописывать, где и какой код должен остаться и почему.
Главная страница прекрасно отображается, а вот две остальные, — не хотят, пишут ошибки. Значит я так и не понял, (ступил) наверное, что и куда надо прописать, что бы все работало.
Перечитал эту статью уже в сотый раз, а воз и ныне там..!
В контроллере Controller_Static два метода — action_about() и action_contacts(). В контроллере Controller_Page только action_index(). Если не работает, может не в этом проблема ? Посмотрите названия файлов, названия контроллеров, роуты. Заготовка для блога у вас работала ? Индекс из адресной строки убирали ?
«В данном случае мы разделяем контроллер на два, чтобы один отвечал за статичные страницы (контакты и о сайте), а другой за динамические.»
Вот я и интересуюсь, что осталось в page.php?
И как оно выглядит?
Да, заготовка работала исправно!
Я все так и сделал, и как бы все было понятно, ясно.
Но на данном этапе, что-то пошло ни так.
Не работают: 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, когда пишете. А то половину кода потерло.