Pull to refresh

Организация простой смены шаблонов при использовании Kohana 3

Reading time3 min
Views916
Доброго времени суток!

Не так давно я начал свое знакомство с фреймворками впринципе и сразу столкнулся с таким вопросом — как же организовать простую смену шаблонов, чтобы в любой момент можно было добавить, скажем, в папку templates еще одну папку с шаблоном и безболезненно изменять шаблоны в будущем. Но в Kohana 3 (к сожалению, ничего не могу сказать о других фреймворках, так как работал с ними лишь поверхностно) во-первых все View-файлы лежат в папке views (все-таки templates проще и понятнее простому пользователю), а во-вторых, нет механизма выбора нужного View-файла из папки Views (кроме как подключение его напрямую). Что ж — сейчас я хочу рассказать, как это реализовать. Используемая версия фреймворка — 3.0.7, последняя на данный момент.
Давайте начнем.

Возможность использования папки Templates вместо Views


Сначала посмотрим на файл Kohana_View, который наследуется классом-пустышкой View. Класс довольно простой, но нас интересует конкретно функция set_filename() — именно в ней «жестко» указано, где искать View-файл:
public function set_filename($file)
{
if (($path = Kohana::find_file('views', $file)) === FALSE)
{
throw new Kohana_View_Exception('The requested view :file could not be found', array(
':file' => $file,
));
}

// Store the file path locally
$this->_file = $path;
return $this;
}

Теперь давайте создадим свой класс Template, унаследовав Kohana_View и слегка изменив функцию set_filename:
public function set_filename($file)
{
$folder = 'templates/'.self::get_name();
if (($path = Kohana::find_file($folder, $file)) === FALSE)
{
throw new Kohana_View_Exception('The requested layer :file could not be found', array(
':file' => $file,
));
}

// Store the file path locally
$this->_file = $path;

return $this;
}

Здесь мелькнуло обращение к несуществующей в классе-родителе статической функции — self::get_name() — давайте теперь напишем ее. Ее задачей будет получение из конфигов в БД (это лишь мой конкретный пример, тут каждый может изменить ее под себя) имени установленного на сайте шаблона.
public static function get_name()
{
$template = DB::select('value')
->from('config')
->where('key', '=', 'template')
->limit(1)
->execute()
->current();
return $template['value'];
}

Теперь при необходимости мы легко можем узнать имя текущего шаблона, обратившись к Template::get_name(). Была в начале мысль вынести имя в статическую переменную, но практика показала, что такой подход порой неприменим (хотя при должном искусстве извращаться — запросто).

Дальше по списку у нас фабрика — без излишеств:
public static function factory($file = NULL, array $data = NULL)
{
return new Template($file, $data);
}

Вот, собственно, и все — с файлом Template покончено, можно сохранить его как application/classes/template.php

Пишем свой Controller_Template


Теперь давайте напишем свой контроллер Controller_Template, взяв за основу предлагаемый фреймворком Kohana_Controller_Template:
class Controller_Template extends Controller{

/**
* @var string template layer
*/
public $layer = 'index';

/**
* @var boolean auto renders template
*/
public $auto_render = TRUE;

/**
* Loads the template object (Template instance)
*/
public function before()
{
if($this->auto_render === TRUE)
{
$this->template = Template::factory($this->layer);
return parent::before();
}

/**
* Assigns the template as the request response.
*/
public function after()
{
if($this->auto_render === TRUE)
{
$this->request->response = $this->template;
}
return parent::after();
}
}


Теперь, допустим, при написании контроллера авторизации, который будет использовать отдельный layer templates/[template_name]/auth.php достаточно будет унаследовать его от Controller_Template и добавить строку
public $layer = 'auth';

Вот, собственно, и все.

Буду рад, если моя статья кому-то поможет. Также буду рад любой здоровой критике, вопросам, комментариям… В общем, ради них и написал. :)
Благодарю за внимание.
Tags:
Hubs:
+5
Comments5

Articles