Вот мы и дошли до очень важной темы — темы Роутинга в Кохане. Хочу поблагодарить Семёна 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», которое потом можно получить например в Базовом Контроллере.
В следующем уроке мы перепишем этот пример с использованием регулярного выражения и обойдемся одним роутом вместо двух, а также создадим еще несколько роутов для понимания (или закрепления) материала из этого урока.
<< Назад | Вперед >> |
Пожалуйста, зарегистрируйтесь для комментирования.
Наконец-то!!!
Земной поклон вам добрые люди!)
С нетерпением жду следующих уроков.
Хотелось бы сказать всем. Если вам нравится ресурс, был бы очень рад, если бы вы разместили ссылочку на него у себя на сайте или например порекомендовали его на форуме по программированию, где вы бываете (только пожалуйста без спама). Больше ссылок — сильнее «любят» поисковики. Может получится хоть какой-то доход с рекламы, да и мне стимул почаще выпускать уроки
Денис, так а вы сочините кнопку с кодом чтобы копипаст и все)
Ага. Сделаю )
сделал кнопку. смотрите на главной
Все это хорошо, но как по мне это не совсем удачный способ делать статические страницы.
Лучше создать общий контроллер который будет тянуть с базы статические страницы. Надеюсь понятно что при этом чтобы узнать какую нам нужно взять страницу просто передаем параметром в адресной строке.
Ну вот мы и создали общий контроллер для статических страниц. А до базы мы еще не добрались. В любом случае, я не считаю рентабельным использовать базу данных для статических страниц, если мы знаем сколько их будет и какие они. Можно вообще все в базу засунуть, как в этом вордпрессе, только вот ложится он при мало-мальски приличной нагрузке.
Ну скорее мой вариант подходит для людей которые будут работать исключительно с админкой, а не с кодом.
Ну да. Это все уже нюансы работы, зависящие от условий. Моя задача — рассказать про сам фреймворк. А как этим пользоваться-уже решать вам.
Извиняюсь, но с правилом ((/(/))) что-то не ясно… почему в роуте мы его не используем, а пишем просто ‘about’ или ‘static’? почему не написать так:
Route::set(‘about’, ‘((/(/)))’)
->defaults(array(
‘controller’ => ‘static’,
‘action’ => ‘about’,
));
и вот тут: ‘Просто в параметр about попадет слово «faq», которое потом можно получить например в Базовом Контроллере.’
что-то недопонял… как это слово попадает в параметр?
извиняюсь, если туплю.
Фильтр обрезал часть кода, попробую догадаться
Так писать можно, но тогда на about мы напишем как у вас, на faq тоже прийдется писать, только поменяется ‘action’ => ‘faq’. Будет еще какая-то статичная страница, еще один роут прийдется создавать. А так все в одном. Появилась новая страница, в регулярку слово добавили и все. В action оно автоматом подставится.
Упс. походу я не то ответил. Я думал это к уроку Роутинг Часть-3. Там мы регулярку уже применяем.
Вообщем еще раз напишите код. Только поместите его в теги
Уже вкурил сам. Как и предполагалось, — тупил. Во второй части Вы все разъяснили.
А вопрос был таким: зачем прописывать роуты для каждой статической страницы, когда можно прописать общее правило.
что-то не прописывается правило )))
да и бес с ним, проехали )
Ну да. Я как бы плавно к этому подвел. Сначала показал на двух роутах, потом вариант получше
Здравствуйте.
Очень понравились ваши уроки, сам я из начинающих, давно пытался освоить Kohana но везде так заумно объясняют что после первых строк дальше и заниматься не хочется а у вас все просто и доходчиво.
Вот по этому уроку, как нужно настроить денвер чтобы роуты срабатывали, у меня в любом варианте выдает ошибку.Если это ((/(/))) меняю на это (/(/)) то вообще главная не грузится.
Не видно кода. Обрамляйте код тегами pre. Или пишите на форуме, поможем.
Помогите, пожалуйста, разобраться с проблемой.
Ввожу http://kohana/about, получаю
HTTP_Exception_404 [ 404 ]: The requested URL вып was not found on this server.
SYSPATH\classes\kohana\request\client\internal.php [ 87 ]
Это ещё до редактирования роутинга, описнного в данном уроке.
Пару дней назад впервые поставил Кохану и прошёл все этапы — проблема была аналогичная. Предположил, что я где-то напутал, решил взять, и проделать всё с нуля. Проделал всё с нуля — проблема осталась.
Грубо говоря, она заключается в том, что любая ссылка, кроме реально существующей, выдаёт сообщение об ошибке парсера. Вы же говорите о том, что должен выдаваться редирект на главную. Это не так и принципиально до момента, описанного в следующем уроке, когда идёт описание работы с articles.
Всё проделываю на Denwer, все шаги дословно повторил с первого урока, релиз качал с офф. сайта. В чём может быть проблема?
свои Роуты пишите перед основным.
архитектура такая.
если иначе то будут ошибки т.к. сначала будет идти Роут по умолчанию, а он всегда верный.
и все что ниже него просто игнорируется.
если не верно поправьте, я недано изучаю php и с ООП практически не знаком.
но именно так я избавился от такой ошибки.
В первом примере кода, где Controller_Static, заменить последнюю строчку
} // End Page
на
} // End Static
А так — всё отлично. Спасибо
Поменял, благодарю. Приятно, когда люди внимательно читают и вникают, а не копипастят код 1 в 1.
Здравствуйте!
К сожалению с данного урока я так и не понял, — какой же все-таки код должен остаться в Controller_Static и какой в Controller_Page?
Все начиналось так хорошо, — понятно..!
Но почему-то в один момент, — раз и все..»Для этого в папке с двумя нашими Контроллерами создадим еще один с названием static.php и со следующим кодом (я скопировал его из Контроллера Page, а там удалил):»
Что удалил, — все, что там было или как..? А что осталось? Или как изменилось?
Вы уж, пожалуйста, пропишите все четко, — что удалилось и где, и что осталось, так же где! И самое главное, — как это должно выгладить.
Ведь, Вы же делаете урок для начинающих..!!!!
А такие провалы подойдут только для уже искушённых товарищей в CMS Kohana.!
Вы хорошо рассказываете, но вот такие провалы ставят людей в тупик, по этому и много комментов к каждому уроку, к сожалению..! Потому, как многое не понятно.
Я смотрю, у Вас в ссылках мелькает Е.Попов, — у него таких провалов в объяснениях практически нет. Я начинал с чистого листа с его уроков и видеоуроков, — молодцом парень, честь и хвала!!!
Если можно, то пропишите более точно, что, куда, где, когда и почему. А самое главное, — как это будет выглядеть в окончательном варианте!
С Уважением, msgraf!
Код, как выглядит Controller_Static есть здесь в самом верху:
http://kohanaframework.su/starting/blog_p1
В нем три метода: action_index(), action_about() и action_contacts(). Соответственно если мы «создадим еще один с названием static.php и со следующим кодом (я скопировал его из Контроллера Page, а там удалил)», а следующий код — это два метода action_about() и action_contacts(), то в Controller_Static мы их удаляем и там останется только action_index(). Куда уж проще ?
Старайтесь вникать в текст, а не только копировать код. А то тут было, когда я, чтобы не копировать весь код, который был рассмотрен в предыдущем уроке, поставил многоточие. Так люди вместе с многоточием копировали и еще удивлялись, почему в этой строке ошибка.
Поправлюсь.
Я все это написал не потому, что есть желание скопировать 1 к 1-му, потому, что бы разобраться в мелочах.
А как мы все понимаем, — это и есть суть Ваших уроков…, или я не прав?!
Tще раз, с Уважением, msgraf!
Тут главное не разобраться, какой код мы куда копируем, а понять, для чего это делается. В данном случае мы разделяем контроллер на два, чтобы один отвечал за статичные страницы (контакты и о сайте), а другой за динамические.