Kohana для чайников. Работа с шаблонами.



kohanaВ позапрошлый раз мы составляли скрипт 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');
 
	}
}

Вот пока и всё. =)

Здесь можно скачать

Посты по теме:

  1. Kohana для чайников. Простейший ORM
  2. Kohana для чайников. Hello world.
  3. Kohana для чайников. Простейший роутинг
  4. Kohana для чайников. Настраиваем базу данных
  5. Kohana для чайников. Пользовательские конфиги

Категории Kohana |
автор: altesack / Четверг, Декабрь 10, 2009 / 20 комментов »

20 комментов

    Было бы значительно интереснее и впринципе понятнее делать подобные статьи с примерами более близкими к реальным.
    Например серия статей “делаем простой блоговый движок на 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 :)
    Спасибо за подсказку, а то бы я еще долго пытался придумать как без логов ошибку отследить)

    “Давно-давно, когда я учил ООП, абстрактными называли классы, которые не использовались явно, а нужны были, например, только для создания тучи потомков с одинаковым набором неких свойств.”

    В данном случае действительно не совсем понятно, что это значит. Как на счет Controller_Overall?

    Начал таки разбираться с Коханой.

    В общем – абстрактный контроллер создавать не обязательно. Можно обойтись одним контроллером. В этом случае, просто необходимо наследовать контроллер Template и там описывать все данные, которые мы обрабатываем.

    Как, при использовании шаблона, передать значение из контроллера в представление?

    @ kolyuchii:

    Вариант простой. Если нужно просто передать строку или переменную

    $this->template->content = “Моё значение”;

    Вариант сложнее, если нужно отобразить другое представление, которому нужно передать параметры.

    $data['id']=$something->id;
    …….
    $data['text']=$something->value;
    $this->template->content = new View(’somethingview’, $data);

    Спасибо за статью !

    Понравился метод шаблонизации в КО3(описаный вами ) но я так понял там только 1 шаблон для всего контролера ? Или есть возможность сделать несколько шаблонов для каждого action ? Если есть то как ?
    Спасибо!

    @ Jarek:
    Не совсем так. Основной шаблон один. Но в отдельные элементы можно встраивать шаблоны по-меньше. Как собственно показано в примере.

    Вы хотите чтобы шаблон вообще отличался от принятого, то наследуйте от Controller, а не от Controller_Template. А вызвать шаблон можно так:

    $view=new View(’ваш_шаблон’);
    $view->ваш_контент=$blablabla;
    echo $view;

Ответить