Контроллер Шаблонов

Комментарии: 32  Просмотры: 46 743

Фреймворк Кохана идет сразу с со специальным контроллером шаблонов (Template Controller), который позволяет намного проще работать с файлами шаблонов и делает код в Контроллере, где идет работа с шаблонами, гораздо компактнее. Предлагаю разобрать все это на примерах. Откройте наш старый знакомый Контроллер Welcome и измените код на следующий:

class Controller_Welcome extends Controller_Template {
 
    public function action_index()
    {
        $content = View::factory('welcome')
              ->bind('age', $age);
        $age = 'больше 18';
        $content->name = 'Васька';
        $this->template->content = $content;
    }
 
} // End Welcome

В папке с Видами создайте еще один файл с названием template.php и напишите в нем следующее:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Работаем с Контроллером Шаблонов</title>
</head>
 
<body>
    <?php echo $content; ?>
</body>
</html>

Теперь можно обновить нашу страницу. Визуально ничего не поменялось (разве что у страницы появился title — Работаем с Контроллером Шаблонов). Но если посмотреть html-код страницы, видно, что внутри template.php, между тегами body, вывелся шаблон welcome.php.

Что мы поменяли? Прежде всего изменилось наследование в классе Controller_Welcome. Теперь наследуется не Controller, а Controller_Template. Если заглянуть в файл /system/classes/kohana/controller/template.php с классом Controller_Template, видно, что он в свою очередь наследует уже знакомый нам класс Controller. Также видно, что шаблоном по умолчанию там назначен template (поэтому мы и назвали наш файл template.php):

/**
 * @var  View  page template
 */
public $template = 'template';

Если мы хотим назвать базовый шаблон по другому, например main.php, то в Контроллере Welcome в самом верху нужно прописать его как базовый шаблон, т.е. просто

public $template = 'main';

и теперь можно смело переименовывать файл.

Что все это нам дает ? Возможность очень удобно передавать данные как в базовый шаблон, так и в другие шаблоны. Например так:

class Controller_Welcome extends Controller_Template {
 
    // Определяем шаблон по умолчанию
    public $template = 'main';
 
    public function action_index()
    {
        $content = View::factory('welcome');
 
        // Передаем данные в шаблон welcome.php
        $content->age = 'больше 18';
        $content->name = 'Васька';
 
        // Передаем данные в шаблон по умолчанию - main.php
        $this->template->title = 'Работаем с Контроллером Шаблонов';
        $this->template->description = 'Учимся передавать данные в шаблоны';
        $this->template->content = $content;
    }
 
} // End Welcome

и в файле шаблона main.php тоже немножко поменяем:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><?php echo $title; ?></title>
<meta name="description" content="<?php echo $description; ?>" />
</head>
 
<body>
    <?php echo $content; ?>
</body>
</html>

Удобно ? По-моему вполне. А если вдруг нужно, чтобы какие-то переменные было видно во всех файлах Вида, можно использовать Глобальные переменные Вида. Их мы и рассмотрим в следующем уроке.

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


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

«Но если посмотреть html-код страницы, видно, что внутри welcome.php между тегами body вывелся шаблон template.php.»

Наверное, наоборот. Внутри template.php вывелся welcome.php.

Совершенно верно. Поправил, спасибо.

Это и есть некий layout для сайта! Ае! В codeigniter, на сколько помню, не было такого понятия… Хотя я поверхностно его изучал.

В КИ примерно тоже самое в этом плане. Хотя я его тоже изучил поверхностно (правда один сайт довольно сложный на нем написал, но это было давно и уже подзабыл).

Я помню умельцы писали свои классы для получения нужного эффекта — один шаблон в одном месте кода для всего сайта. По умолчанию вроде там не было понятия layout.

здравствуйте!! Большое вам спасибо за сайт!!Здесь действительно нужная информация!!!
Но у меня проблема((Все делаю как сдесь написано в браузере перехожу http://kohana/page/about выдает ошибку
HTTP_Exception_404[404]: The requested URL page/about was not found on this server. в чем может быть проблема??(((((

Почему /page/about , у нас же вроде просто /about
Мне трудно сказать, что может быть, так как я не знаю, что у вас в роутах написано. Но если page — это контроллер, а about — это action, то проверьте моменты: файл контроллера должен называться page.php, класс должен называться Controller_Page и метод должен называться action_about.
И задавайте такие вопросы пожалуйста в форуме. Даже тема специально создана по урокам:
http://forum.kohanaframework.su/viewtopic.php?f=2&t=15&sid=3d31b0d68677e807fc603361499e12e6
Особенно если не помогут советы. Тогда пишите там, показывайте код.

Вот такая вот ошибка. В чем проблема?
ошибка на 11 строке
ErrorException [ Strict ]: Creating default object from empty value
APPPATH/classes/controller/welcome.php [ 11 ]
6 {
7 $content = View::factory(‘welcome’)
8 ->bind(‘age’, $age);
9 $age = ‘больше 18′;
10 $content->name = ‘Васька’;
11 $this->template->content = $content;
12 }
13
14 public function action_test()
15 {
16 $this->response->body(‘bla-bla kz!’);
APPPATH/classes/controller/welcome.php [ 11 ] » Kohana_Core::error_handler()
{PHP internal call} » Controller_Welcome->action_index()
SYSPATH/classes/kohana/request/client/internal.php [ 118 ] » ReflectionMethod->invoke(arguments)
SYSPATH/classes/kohana/request/client.php [ 64 ] » Kohana_Request_Client_Internal->execute_request(arguments)
SYSPATH/classes/kohana/request.php [ 1138 ] » Kohana_Request_Client->execute(arguments)
DOCROOT/index.php [ 109 ] » Kohana_Request->execute()

Простите не заметил что родитель поменялся. Виноват)))

Тоже не заметил, что родитель поменялся. Спасибо, за помощь.

$this->template->title = ‘Работаем с Контроллером Шаблонов’; Обьясните пожалуйста, что находиться в свойстве teemplate, как я понимаю, в нем должен быть обьект и от этого обьекта обращаются к свойству title

Да, это объект. Вы можете посмотреть код контроллера шаблонов. Он очень короткий и простой. Фактически основная строка там
$this->template = View::factory($this->template);

а каким образом $this->template->titlr = ‘Главная’; подставляется в шаблоне в переменную title ?

Вы решили досконально изучить структуру фреймворка ? :) Тогда лучше всего не здесь эти вопросы задавать, а смотреть код — это будет гораздо полезнее. Изучите класс Kohana_Controller_Template, посмотрите как там создается объект класса View. Откройте класс Kohana_View, посмотрите как там собираются и отдаются параметры (методы set и get). То, что вы спрашивали, как бы вот

public function & __get($key)
{
    if (array_key_exists($key, $this-&gt;_data))
    {
        return $this->_data[$key];
    }
    elseif (array_key_exists($key, View::$_global_data))
    {
        return View::$_global_data[$key];
    }
    else
    {
        throw new Kohana_Exception('View variable is not set: :var',
            array(':var' => $key));
    }
}

[quote]Если заглянуть в файл /system/classes/kohana/controller/template.php с классом Controller_Template, видно, что он в свою очередь наследует уже знакомый нам класс Controller[/quote]

На самом деле Controller_Template наследует сначала класс Kohana_Controller_Template в файле /system/classes/controller/template.php, который, в свою очередь, наследует уже класс Controller в файле /system/classes/kohana/controller/template.php.

Но я хотел отметить, что, на первый взгяд, не совсем понятная цепочка наследований, в результате которой к начальнему классу Controller добавляется всего-навсего автоматический вывод (хотя пока что я вскользь его просмотрел)…

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

Контроллер вида из обычного контроллера легко похоже делается.
class Controller_Welcome extends Controller
{
public $template = ‘main’;

public function action_index()
{
$tmp = View::factory($template);
$tmp->title = »;

$view = View::factory(‘welcome’);
$tmp->content = $view;

$this->responce->body($tmp);
}
}

так можно сколь угодно раз вкладывать один вид в другой ))

А как мне в шаблоне вывести данные из базы?

Решил вот таким способом

public $template = ‘default’;
public function before()
{
parent::before();
// Для любого action передаем шаблону какие-нибудь данные
$this->template->categories = array(‘PHP’, ‘Kohana’, ‘Framework’);
}

феноменально )))

Возможно ли переопределять $template внутри методов контролера? Чтобы для каждого метода использовался свой файл шаблона. или проще создавать для этих методов отдельные наследующие классы?

Что это за сайт такой, где все шаблоны разные ?
Т.е. на одной странице меню слева, на другой справа, а где-то хидера нет ?
Можно писать в контроллере что-то вроде

$this->template = View::factory('тут другой шаблон, какой-нибудь main1');

Вопрос чисто академический. Всегда писал без использования классов. Это для меня новое.. Это сработало. Смутило что объявление и переназначение переменной имеет различный синтаксис.. Возможно пригодится для урезанной версии отображения сайта.. для моб устройств. или подстраивать кол-во выводимой информации под разрешение клиента (монитора).

Где различный синтаксис ?

public $template = ‘main1′;
и
$this->template = View::factory(‘main2′);

Можно ли передать два вида в один шаблон?

типа такого
$this->template->content = new View(‘salon’,'contacts’);

хочу в один шаблон вставить другой шаблон, и уже в этот другой шаблон вставить сам вид.

возможно ли такое реализовать?

Выше в комментах adr6t7 дал пример.



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

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