DANFA

Универсальный шаблонизатор для больших и маленьких сайтов

Доброго времени суток.
Задался вопросом написания собственной системы создания шаблонов. Мне не интересны существующие библиотеки, хочу сделать свой, сначала, в качестве практики, затем применить на рабочем сайте.

Давайте по косточкам разберем, что должен уметь современный шаблонизатор? Как задавать данные, что будет в шаблонах?

У меня будут еще вопросы.
Спасибо.

Навигация по теме:


Возможно, будет интересно:
Шаблонизатор должен генерировать и сохранять HTML файлы/части страниц, в кэше движка. Задача шаблонизатора отделить PHP от HTML и упростить работу с кодом, разработчику.

Данные в шаблонизатор передаются в виде переменных, массивов. Для того можно написать специальную функцию, что будет принимать и отдавать все переменные.

Тут, на сайте есть несколько записей, по данной теме. Поищите. Там примеры есть.
Я думаю, что для больших и популярных сайтов, так их, как новости или социальные сети, есть смысл делать шаблонизатор, чтобы уменьши количество запросов в базу и время генерации страницы, тк на популярных порталах и так нагрузка большая, от посещаемости. Для маленьких сайтов, с маленькой посещаемостью смысла нет ни какого, лепить систему шаблонов. Она там ни к чему. Вы можете просто писать PHP код, прямо в HTML:
<div class="name">
	<?php echo $name; ?>
</div>

Это удобно, не запутаетесь в костылях шаблонизатора и работает 100%, без отказано. И ни какого шаблонизатора городить не надо.
Спокойный, это понятно, но если делать так, то теряется весь смысл самого шаблонизатора. Смотрим готовые шаблонизаторы, там такие конструкции:
{var.value}

И это проще в написании, чем:
<?php echo $var['value']; ?>
Если вы хотите писать так {var}, например:
<p>{name}</p>

Необходимо будет написать массив с фразами:
$lang = [
	'name' => 'Название'
];

И дальше так:
$tmp = preg_replace_callback(
	'/\{(\w+)\}/',
	function($match) use($lang)
	{
		return $lang[$match[1]];
	},
$tmp);

Можно сделать по аналогии: Тема: Установка заголовка страницы (Шаблонизатор на PHP), только отправлять не одну строку, а массив фраз или данных, для вывода на экран. И совместить его со всем кодом данного поста в своём шаблонизаторе.

Возможно, будет интересно: Тема: Функция "preg_replace_callback" не работает (PHP).
Так понятнее, как добиться универсального шаблонизатора!
Спасибо!
Спокойный сказал:
Для маленьких сайтов, с маленькой посещаемостью смысла нет ни какого, лепить систему шаблонов.

Все сайты, когда-то были маленькими и посещало их 4 человека, за 24 часа.
Slash, как при помощи Вашего кода:
$tmp = preg_replace_callback(
	'/\{(\w+)\}/',
	function($match) use($lang)
	{
		return $lang[$match[1]];
	},
$tmp);

сделать обработку таких переменных:
  • {lang.var} - языковая переменная (массив $lang).
  • {tmp.var} - переменная, что пришла с PHP скрипта (массив $tmp).

Спасибо.
Если $tmp: это массив переменных, то имя переменной следует сменить в обработчике переменных шаблона, например, на: $content. Написал так:
$content = preg_replace_callback(
	'/\{([\w\.]+)\}/',
	function($match) use($lang, $tmp)
	{
		[$item, $var] = explode('.', $match[1]);

		return $$item[$var];
	},
$content);

Пробую:
$lang = [
	'title' => 'Документ',
	'info'  => 'Информация'
];

$tmp = [
	'test' => 'Тест шаблонизатора PHP'
];

$content  = '<strong>{lang.title}</strong> {lang.info}';
$content .= ' {tmp.test}';

Результат:
<strong>Документ</strong> Информация Тест шаблонизатора PHP

Если версия PHP ниже 8, то замените строку:
		[$item, $var] = explode('.', $match[1]);

На:
		list ($item, $var) = explode('.', $match[1]);

Иначе работать не будет.
Как компактно! А я целый километр кода городил и все ровно не заработало.
Спасибо, Slash!
Я себе тоже делаю шаблонизатор, только я пишу не так { code }, а так <!-- code -->, так выглядит код красивее. Ну это дело вкуса, кому как.

У меня вопрос по подключаемым шаблонам внутри шаблона. Вот обработал шаблонизатор один шаблон и выдал его на экран, а как быть с:
<!-- include name_file -->

Как вставить код шаблона из инклуда в шаблон?
Как то так:
if (preg_match('/<\!-- include (.*?) -->/', $cache_tpl))
{
	function incl($cache_tpl, $dir_tpl)
	{
		preg_match_all('/<\!-- include (.*?) -->/', $cache_tpl, $includeArray);
		foreach ($includeArray[1] as $key => $incl)
		{
			if (file_exists($dir_tpl . $incl . '.html'))
			{
				$incl_tpl     = '/<\!-- include ' . $incl . ' -->/';
				$incl_replace = file_get_contents($dir_tpl . $incl . '.html');
				$cache_tpl    = preg_replace($incl_tpl, $incl_replace, $cache_tpl);
			}
			else
			{
				exit('No Template: <strong>' . $incl . '</strong>');
			}
		}

		if (preg_match('/\<\!-- include (.*?) -->/', $cache_tpl))
		{
			$cache_tpl = incl($cache_tpl, $dir_tpl);
		}

		return $cache_tpl;
	}

	$cache_tpl = incl($cache_tpl, $dir_tpl);
}

Проверить не могу.

По моей идеи: Все include, что будут находится в шаблоне, будут заменены на код, которых находится в файле, что указан в include.

Думаю, этот код должен встречать шаблон раньше, чем обработка переменных. Потому что в подключённых шаблонах, так же могут быть прописаны переменные. И если работать с include, после обработки переменных, то переменные в подключаемых файлах, останутся не обработанными.
Спасибо, Slash!

Думаю разберусь, что к чему. Если, что я попрошу помощи.