Подключение шаблонов к своему PHP скрипту. Шаблонизатор
Пятница, 04 Июн 2010 11:01
Шаблонизатор является основным модулем системы любой CMS системы. Думаю почему я так считаю объяснять не надо. Любая CMS должна быть гибкой и представлять определённый минимальный набор функционала и сочетать универсальность подстройки дизайна. Именно универсальность интеграции дизайна и позволяет реализовать шаблонизатор. Шаблонизаторы бывают разных типов, от основанных на php шаблонах (самые простые) и до блочно модульных. Первый тип шаблонизаторов достаточно прост в реализации, но в свою очередь и более громоздкий, так как для интеграции требует как минимум базового знания языка программирования. По этому я хочу рассказать о втором типе.
Итак, как де все-таки должен работать такой шаблонизатор?
Представьте себе, что у нас есть базовая вёрстка такого типа
1 | <html><body><div>блок1</div><div>блок2</div><div>блок3</div></body></html> |
Я максимально упростил для наглядности. Каждый блок в зависимости от параметра URLa например или $_POST и $_GET запроса может иметь разное содержимое, более того, в зависимости от того же урла может меняться количество блоков или их расположение.
Ниже приведен код реализующий весь этот функционал и я расскажу как им пользоваться. Комментарии в коде
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | <?php class Template { public $dir = '.'; public $template = null; public $copy_template = null; public $data = array(); public $block_data = array(); public $result = array('info' => '', 'content' => ''); public $template_parse_time = 0; //задаём параметры основных переменных подгрузки шаблона public function set($name , $var) { if (is_array($var) && count($var)) { foreach ($var as $key => $key_var) { $this->set($key , $key_var); } } else $this->data[$name] = $var; } //обозначаем блоки public function set_block($name , $var) { if (is_array($var) && count($var)) { foreach ($var as $key => $key_var) { $this->set_block($key , $key_var); } } else $this->block_data[$name] = $var; } //производим загрузку каркасного шаблона public function load_template($tpl_name) { $time_before = $this->get_real_time(); if ($tpl_name == '' || !file_exists($this->dir . DIRECTORY_SEPARATOR . $tpl_name)) { die ("Невозможно загрузить шаблон: ". $tpl_name); return false;} $this->template = file_get_contents($this->dir . DIRECTORY_SEPARATOR . $tpl_name); if ( stristr( $this->template, "{include file=" ) ) { $this->template = preg_replace( "#\\{include file=['\"](.+?)['\"]\\}#ies","\$this->sub_load_template('\\1')", $this->template); } $this->copy_template = $this->template; $this->template_parse_time += $this->get_real_time() - $time_before; return true; } // этой функцией загружаем "подшаблоны" public function sub_load_template($tpl_name) { if ($tpl_name == '' || !file_exists($this->dir . DIRECTORY_SEPARATOR . $tpl_name)) { die ("Невозможно загрузить шаблон: ". $tpl_name); return false;} $template = file_get_contents($this->dir . DIRECTORY_SEPARATOR . $tpl_name); return $template; } // очистка переменных шаблона public function _clear() { $this->data = array(); $this->block_data = array(); $this->copy_template = $this->template; } public function clear() { $this->data = array(); $this->block_data = array(); $this->copy_template = null; $this->template = null; } //полная очистка включая результаты сборки шаблона public function global_clear() { $this->data = array(); $this->block_data = array(); $this->result = array(); $this->copy_template = null; $this->template = null; } //сборка шаблона в единое целое public function compile($tpl) { $time_before = $this->get_real_time(); foreach ($this->data as $key_find => $key_replace) { $find[] = $key_find; $replace[] = $key_replace; } $result = str_replace($find, $replace, $this->copy_template); if (count($this->block_data)) { foreach ($this->block_data as $key_find => $key_replace) { $find_preg[] = $key_find; $replace_preg[] = $key_replace; } $result = preg_replace($find_preg, $replace_preg, $result); } if (isset($this->result[$tpl])) $this->result[$tpl] .= $result; else $this->result[$tpl] = $result; $this->_clear(); $this->template_parse_time += $this->get_real_time() - $time_before; } //счётчик времени выполнения запросов сборки public function get_real_time() { list($seconds, $microSeconds) = explode(' ', microtime()); return ((float)$seconds + (float)$microSeconds); } } |
А теперь немного о работе данного класса. шаблонизатор этот имеет 2 типа шаблонов, это каркасный шаблон (основной) и шаблоны блоков. То есть на каждый блок расположенный в каркасе мы можем нарисовать свой, отдельный шаблон.
приведу пример как работает данный шаблонизатор. Создадим несколько файлов
main.tpl – каркасный шаблон
1 | <html><body><div>блок1</div>{sub_templ}</body></html> |
sub.tpl – шаблон блока
1 | <div>{var1}</div><div>{var2}</div> |
Итак, мы получили набор из 2-х шаблонов, но пока где у нас есть каркас с блоком {sub_templ} и блок с вёрсткой, в которую должны будут подключиться переменные {var1} и {var2}
Ключевые элементы как вы заметили мы взяли в фигурные скобки.
Теперь нам необходимо инициировать шаблонизатор и заменить нежные функциональные части. Делается это так:
1 2 3 4 5 6 7 8 9 10 11 12 | $tpl = new Template; //инициируем класс $tpl->dir = 'View/tpl'; //задаём местоположение папки с шаблонами $tpl->load_template('main.tpl'); //загружаем каркас $tpl->set('{sub_templ}', $tpl->sub_load_template('sub.tpl')); //подключаем код блока //подставляем значения переменных $tpl->set('{var1}', 'блок2'); $tpl->set('{var2}', 'блок3'); $tpl->compile('main'); //собираем шаблон echo $tpl->result['main']; //выводим результат работы $tpl->global_clear(); //очищаем все переменные для возможно следующего шаблона |
Обратите внимание, что в $tpl->set(‘{var1}’, ‘блок2′); вместо фразы «блок2″ может так же находиться любая переменная.
Вышеописанный код выведет нам такой результат:
1 | <html><body><div>блок1</div><div>блок2</div><div>блок3</div></body></html> |
voskan пишет:
28 Ноя 2011 в 12:44
а как вместо блок 2(то есть значения атребута ) задать php скрипт ? буду благодарен если на мыло напишешь.
hex пишет:
10 Янв 2012 в 14:07
А не проще так ?
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var $vars = array();
var $template;
function get_tpl($tpl_name){
if(empty($tpl_name) || !file_exists($tpl_name)){
return false;
}else{
$this->template = file_get_contents($tpl_name);
}
}
function set_tpl($key,$var){
$this->vars[$key] = $var;
}
function tpl_parse(){
foreach($this->vars as $find => $replace){
$this->template = str_replace($find, $replace, $this->template);
}
}
}
$parse = new parse_class;