В позапрошлый раз мы составляли скрипт Hello World. Мы написали простейший контроллер, который организует прямой вывод в HTML. Но то что подходит для простого примера не подойдёт для серьёзных веб-приложений.
Правильным подходом здесь считается выделение визуального представления от логики. Это с одной стороны позволяет создавать многократно используемые шаблоны (views, представления), а с другой стороны отделить работу программиста от работы дизайнера.
Kohana2. Простейший пример.
==============================
Создадим простенький файл application/views/hello_content.php
1 2 | <h1>Работаем с шаблонами</h1> <?php echo $content ?> |
Это самое простейшее представление, которое выдаёт некий заголовок и содержимое переменной $content. Тем кто работал с CodeIgniter должен показаться непривычным отказ от альтетнативного синтаксиса сокращённых тегов. Он доступен только с помощью дополнительных библиотек.
Теперь рассмотрим пример контроллера application/controllers/hello.php, работающего с этим представлением.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php defined('SYSPATH') or die('No direct script access.'); class Hello_Controller extends Controller { public function index() { // Создать представление $hello= new View('hello_content'); // Создать у представления свойство content и записать в него значение $hello->content = 'Hello, world!'; // Построить представление и отобразить. $hello->render(TRUE); } } |
Понятно, что такой пустой view совершенно бесполезен. Чтобы он был полезным в него нужно поместить html-код оформления страницы.
Итак, пример работает! Но это не совсем правильный путь.
Kohana2. Системный класс Template_Controller.
==============================
Более экономный код получается если создаваемый контроллер наследует не базовый класс Controller а специальный Template_Controller (или Controller_Template в Kohana3).
Для примера создадим простенький файл application/views/template.php
1 2 | <h1>Работаем с шаблонами через контроллер шаблонов</h1> <?php echo $content ?> |
Ничего необычного, кроме названия файла. А теперь перепишем наш контроллер application/controllers/hello.php
1 2 3 4 5 6 7 8 9 | <?php defined('SYSPATH') or die('No direct script access.'); class Hello_Controller extends Template_Controller { public function index() { // Создать у представления свойство content и записать в него значение $this->template->content = 'Hello, world!'; } } |
Если сравнивать этот способ с предыдущим, то заметим код стал гораздо компактнее – а это уже очень хорошо для разработчика! Но зато раньше можно было указывать каждому контроллеру и даже функции своё представление, а здесь только один на всех файл template.php.
Как же лучше?
Kohana2. Путь истинный
=================
В Kohana рекомендуется следующая схема работы:
Создать абстрактный контроллер, например Abstract_Controller
1 2 3 4 5 6 7 8 9 | <?php defined('SYSPATH') or die('No direct script access.'); class Abstract_Controller extends Template_Controller { public function __construct() { parent::__construct(); $this->template->head = 'Тест заголовка!'; } } |
Теперь немного перепишем шаблон template.php
1 2 3 4 5 6 7 8 9 10 11 12 13 | <head> <title><?php echo $head ?></title> </head> <body> <h1>Работаем с шаблонами через контроллер шаблонов</h1> <?php echo $content ?> <hr> <?php echo HTML::anchor('hello/index', 'Метод index')." | ". HTML::anchor('hello/page1', 'Метод page1')." | ". HTML::anchor('hello/page2', 'Метод page2'); ?> </body> |
Вызов функций вида HTML::anchor('hello/page2', 'Метод page2'); создаёт ссылку на контроллер hello метод page2. Таким образом у нас внизу страницы получится меню.
Итак у нас есть некий обрамляющий шаблон на все случаи жизни. В нем мы можем задать общие для всех страниц элементы оформления, стили, меню, сайдбары и прочее.
Теперь для конкретных контроллеров, которые будут вызываться напрямую через URL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php defined('SYSPATH') or die('No direct script access.'); class Hello_Controller extends Abstract_Controller { public function index() { //Вся магия здесь! $this->template->content = new View('view0'); } public function page1() { //Вся магия здесь! $this->template->content = new View('view1'); } public function page2() { //Вся магия здесь! $this->template->content = new View('view2'); } } |
Вся магия в том, что в переменную content мы подставляем произвольный вид
А также создадим 3 аналогичных шаблона view0, view1 и view2 и дать им наполнение, например такое:
1 2 | <h3>Это view0</h3> <p>Бла-бла-бла некий текст</p> |
Примерно в таком духе нужно организовывать огранизацию работу с шаблонами в Kohana.
Kohana3.
=====================
В Kohana3 общая методика остаётся той же, меняются нюансы. Шаблоны остаются те же в той же папке application/views (по-умолчанию такой папки нет, её нужно создать самостоятельно), но вот контроллеры придётся перенести в папку application/classes/controller и немного переписать.
abstract.php
1 2 3 4 5 6 7 8 | <?php defined('SYSPATH') or die('No direct script access.'); class Controller_Abstract extends Controller_Template { public function before() { parent::before(); $this->template->head = 'Тест заголовка!'; } } |
hello.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?php defined('SYSPATH') or die('No direct script access.'); class Controller_Hello extends Controller_Abstract { public function action_index() { //Вся магия здесь! $this->template->content = new View('view0'); } public function action_page1() { //Вся магия здесь! $this->template->content = new View('view1'); } public function action_page2() { //Вся магия здесь! $this->template->content = new View('view2'); } } |
Вот пока и всё. =)
Здесь можно скачать
- пример для kohana2 (всего скачали 181 раз)
- пример для kohana3 (всего скачали 267 раз)
Посты по теме:
RSS-подписка
Было бы значительно интереснее и впринципе понятнее делать подобные статьи с примерами более близкими к реальным.
Например серия статей “делаем простой блоговый движок на Kohana” или что-то в таком роде.
Ну, + нужно было как-то внятно расписать к примеру, что такое Template_Controller и в чем его отличие от обычного контроллера, вы в своей статье подразумеваете, что его назначение понятно по примеру кода, но для читателей, слабо представляющим себе архитекруру веб-приложений это может быть все-таки непонятным.
Жду следующих статей
@ Nayjest, web-superman:
Чтобы писать примеры типа блогового движка, мне придётся непропорционально загромождать пост кодом. Кроме того таких материалов уже много.
А ещё, я пишу в первую очередь для себя (поскольку я являюсь чайником в Kohana) и для программистов примерно моего уровня. Это как правило уже программировавший человек (возможно CI), но незнакомый именно с Kohana. А такой человек, я думаю сам неплохо напишет блоговый движок, главное показать главные рычаги и кнопки.
Про Template_Controller пожалуй и правда нужно вставить пару слов, а то оторванный текст получился…
Очень интересные уроки, самое крутое, что пишете для себя как для “чайников”)).
Очень хотелось бы продолжения!!
А че за фреймворк такой – Konaha?? хД
@ Накукрыскин:
Оппа… Это я не слабо опечатался.. Спасибки
Хм. А вообще – что за контроллер такой “абстрактный”? Почему файл должен называться именно template.php и почему я не могу назвать его templatosa.php?
@ Накукрыскин:
template.php – это дефолтное название. Его можно переопределить. Например так:
public $template = ‘templatosa’;
Спасибо за примеры. Я только начал разбираться с framework-ами и в частности с Kohana. Статус “полный чайник”. Прошу Вас указывать и url к приведенный примерам (localhost/kohana/…).
Вообще благодаря Ваши примерам я и начал изучать Kohana. Спасибо.
Помогите. А почему же происходит так, что Controller_Abstract загружается, несмотря на то, что его названия нет в URL?
@ Исраэль Райдер:
Мы вызываем контроллер, который является наследником абстрактного контроллера.
Тут вам нужно читать про наследование в объектно-ориентированном программировании.
Понял, спасибо.
Единственное – не совсем правильно называть его “абстрактным контроллером”, возникает ассоциативная путанница.
Абстрактный класс – это класс, перед названием которого стоит ключевое слово “abstract”, или в котором присутствует хоть один абстрактный метод.
KO3 на запрос http:/site/kohana/hello выдает:
ErrorException [ 2 ]: file_put_contents(/home/host/www/kohana/application/logs/2010/05/25.php): failed to open stream: Отказано в доступе ~ SYSPATH/classes/kohana/log/file.php [ 71 ]
Все коды в точности скопированы из статьи.
ubuntu/apache2/php5.3.2
Во-первых SYSPATH/classes/kohana/log/file.php – не существует такого пути, покрайней мере в файловой системе фреймворка я не нашел.
Во-вторых файл лога по адрессу kohana/application/logs/2010/05/25.php тоже отсутствует, соответственно понять на что оно ругается не понятно.
Подскажите, пожалуйста, каким методом идентифицировать ошибку и/или как и кому дать права на запись дабы появлялись логи. На папке logs выставил chmod 0777, но это не помогло.
@ Offi:
1. Файл kohana/application/logs/2010/05/25.php должен был создаться, но для этого ему возможно и не хватило доступа.
Потому и нету.
2. SYSPATH/classes/kohana/log/file.php – должен быть. Более того – он у вас есть, раз уж в нём возникла ошибка в 71 строчке.
Точный путь в Вашем случае, вероятно, такой:
/home/host/www/kohana/system/classes/kohana/log/file.php
3. Именно эту папку вы открыли доступ?
/home/host/www/kohana/application/logs/
Или какую другую?
И ещё – доступ 777 только на эту папку, или также на все вложенные?
@ Исраэль Райдер:
Давно-давно, когда я учил ООП, абстрактными называли классы, которые не использовались явно, а нужны были, например, только для создания тучи потомков с одинаковым набором неких свойств.
Возможно с тех пор что-то поменялось …
@ altesack:
Ура, заработало!))) Действительно проблема была в том что доступ на запись был только у папки /application/logs/, а вложенные папки года и месяца такой привилегии не имели.
Кстати, это что получается Кo3 вложенные папки логов создает без права на запись?
p.s. сама ошибка была из-за моей невнимательности, создал каталог views не в /application/, а рядом с папкой контроллеров /application/classes/controller
Спасибо за подсказку, а то бы я еще долго пытался придумать как без логов ошибку отследить)