- Build Your Own Template Engine in PHP — Rendering & Echo
- Создание движка шаблонов на PHP — Рендеринг и Эхо
- 13+ Best PHP Template Engines to Design your PHP Web Project!
- Twig – Best PHP Template Engine
- Latter – Amazing PHP Template Engine
- Dwoo – PHP5 Template Engine
- Smarty – Free PHP Template Engine Download
- FOIL – Template Engine for Native PHP Templates
- PH7 – PHP Template Engine
Build Your Own Template Engine in PHP — Rendering & Echo
This post will focus on rendering the template and echoing out data that can be escaped with htmlspecialchars() .
Before we start writing code we need to take care of the most important part of any programming project — giving the project a name. I’m going to call it Stencil.
The templates themselves will all be plain PHP. We won’t be creating any special syntax like Twig or Blade, we’ll focus solely on templating functionality.
We’ll begin by creating the main class.
class Stencil public function __construct( protected string $path, ) <> >
The Stencil class will need to know where the templates are located — so that gets passed in through the constructor.
To actually render our templates, we’ll need a render() method.
class Stencil // . public function render(string $template, array $data = []): string // ? > >
The render() method accepts the name of the template and an array of data variables that will be accessible inside of said template.
We now need to do three things:
- Form a path to the requested template.
- Make sure the template exists.
- Render the template with the provided data.
class Stencil // . public function render(string $template, array $data = []): string $path = $this->path . DIRECTORY_SEPARATOR . $template . '.php'; if (! file_exists($path)) throw TemplateNotFoundException::make($template); > // ? > >
The first two on the list are easy to do. Stencil will only look for .php files so forming a path is just a case of concatenating some strings. If the requested template contains any directory separators, that will handle the nesting of templates inside of directories.
If the file doesn’t exist, throw a custom TemplateNotFoundException .
To cover the third point in the list, actually rendering the template, we’ll want to make a new class called Template . This will house all of the methods available to the template and handle the real rendering side of things.
class Template public function __construct( protected string $path, protected array $data = [], ) <> public function render(): string // ? > >
class Stencil // . public function render(string $template, array $data = []): string $path = $this->path . DIRECTORY_SEPARATOR . $template . '.php'; if (! file_exists($path)) throw TemplateNotFoundException::make($template); > return (new Template($path, $data))->render(); > >
To obtain the rendered template as a string, we’ll take advantage of PHP’s output buffers. When you call ob_start() PHP will start to capture anything that the application attempts to output ( echo , raw HTML, etc).
You can retrieve that as a string and then stop capturing the output using ob_get_clean() . A combination of these two functions and an include will let us evaluate a template file.
class Template // . public function render(): string ob_start(); include $this->path; return ob_get_clean(); > >
This will handle rendering the template, but it doesn’t do anything to let the template access those data variables stored inside of $data . PHP being the wonderful language it is provides another function called extract() that accepts an array of key value pairs.
The key for each item in the array will be used to create a new variable in the current scope using the associated value. Since include and its relatives always execute the PHP file in the current scope, the template will be able to access the extracted variables.
class Template // . public function render(): string ob_start(); extract($this->data); include $this->path; return ob_get_clean(); > >
Perfect! Now we can render a template and give it access to the data variables provided. There is one thing that we haven’t considered. if we wanted to create some variables inside of the render() method, our template would also be able to access those. That’s not what we want!
To solve that problem, we need to wrap the extract() and include calls in an immediately-invoke closure — that way, the template will only have access to the variables inside of the closure.
class Template // . public function render(): string ob_start(); (function () extract($this->data); include $this->path; >)(); return ob_get_clean(); > >
The final piece of the puzzle is a method for escaping values when echoing them. Closures inherit $this which means our template will be able to call any method we define on the Template class. Let’s create an e() method that accepts a value and escapes it using htmlspecialchars() .
class Template // . public function e(?string $value): string return htmlspecialchar($value ?? '', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); > >
And like that we have a little template engine for our PHP projects.
The template above can be rendered using our engine:
$stencil->render('hello', [ 'name' => 'Ryan' ]);
And will output the following HTML:
In a future blog post we’ll implement support for partials, allowing us to separate out common templates and use them in multiple places.
Stencil is open-source on GitHub too if you want to look at the source code.
Создание движка шаблонов на PHP — Рендеринг и Эхо
Давайте создадим крошечный движок шаблонов для PHP! Эта статья будет посвящена рендерингу шаблона и отображению данных, которые можно экранировать с помощью htmlspecialchars() .
Прежде чем начнём писать код, необходимо позаботиться о самой важной части любого проекта по программированию — дать имя проекту. Я назову его Stencil
Сами шаблоны будут на простом PHP. Мы не будем создавать какой-либо специальный синтаксис, такой как Twig или Blade , мы сосредоточимся исключительно на функциональности шаблонов.
Начнём с создания основного класса.
class Stencil
public function __construct(
protected string $path,
) >
>
Классу Stencil необходимо знать, где находятся шаблоны, чтобы они передавались через конструктор.
Чтобы на самом деле отображать шаблоны, понадобиться метод render() .
class Stencil
// .
public function render(string $template, array $data = []): string
// ?
>
>
Метод render() принимает имя шаблона и массив данных переменных, которые будут доступны внутри указанного шаблона.
Теперь нужно сделать три вещи:
- Сформировать путь к запрашиваемому шаблону.
- Убедится, что шаблон существует.
- Отобразить шаблон с предоставленными данными.
class Stencil
// .
public function render(string $template, array $data = []): string
$path = $this->path . DIRECTORY_SEPARATOR . $template . '.php';
if (! file_exists($path))
throw TemplateNotFoundException::make($template);
>
// ?
>
>
Первые два пункта списка легко сделать. Stencil будет искать только .php файлы, поэтому формирование пути — этого всего лишь случай объединения строк. Если запрошенный шаблон содержит какие-либо разделители каталогов, будут обрабатываться вложение шаблонов в каталоги.
Если файл шаблона не существует, выбрасываем исключение TemplateNotFoundException .
Чтобы охватить третий пункт в списке, фактически отображающий шаблон, нужно создать новый класс Template . В нём будут размещены все методы, доступные для шаблона, и будет обрабатываться реальная сторона рендеринга.
class Template
public function __construct(
protected string $path,
protected array $data = [],
) >
public function render(): string
// ?
>
>
class Stencil
// .
public function render(string $template, array $data = []): string
$path = $this->path . DIRECTORY_SEPARATOR . $template . '.php';
if (! file_exists($path))
throw TemplateNotFoundException::make($template);
>
return (new Template($path, $data))->render();
>
>
Чтобы получить отображаемый шаблон в виде строки, мы воспользуемся буфером вывода PHP. Когда вызывается ob_start() , PHP начинает захватывать всё, что приложение пытается вывести (эхо, HTMl и т.д.).
Мы можем получить это как строку, а затем прекратить захват вывода с помощью ob_get_clean() . Комбинация этих двух функций и include позволит оценить файл шаблона.
class Template
// .
public function render(): string
ob_start();
include $this->path;
return ob_get_clean();
>
>
Это обработает рендеринг, но не даст шаблону доступ к данным переменных, хранящихся внутри $data . PHP, будучи замечательным языком, предоставляет ещё одну функцию, extract() , которая принимает массив пар ключ-значение.
Ключ для каждого элемента в массиве будет использоваться для создания новой переменной в текущей области видимости с использованием ассоциированного значения. Поскольку include и его родственники всегда выполняют PHP-файл в текущей области видимости, шаблон сможет получить доступ к извлечённым переменным.
class Template
// .
public function render(): string
ob_start();
extract($this->data);
include $this->path;
return ob_get_clean();
>
>
Идеально! Теперь мы можем рендерить шаблон и предоставить ему доступ к предоставленным переменным. Есть одна вещь, которую мы не учли… если бы мы захотели создать несколько переменных внутри метода render() , наш шаблон также смог бы получить к ним доступ. Это не то, что мы хотим!
Для решения этой проблемы необходимо обернуть extract() и include /включить вызовы в немедленно вызываемое замыкание — таким образом, шаблон будет иметь доступ только к переменным внутри замыкания.
class Template
// .
public function render(): string
ob_start();
(function ()
extract($this->data);
include $this->path;
>)();
return ob_get_clean();
>
>
Последняя часть головоломки — метод экранирования значений при их отображении. Замыкания наследуют $this , это означает, что наш шаблон сможет вызывать любой метод определённый в классе Template . Создадим метод e() , принимающий значение и экранирующий его с помощью htmlspecialchars() .
class Template
// .
public function e(?string $value): string
return htmlspecialchar($value ?? '', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
>
>
Таким образом, у нас есть небольшой движок шаблонов для наших PHP проектов.
Приведённый выше шаблон можно рендерить с помощью нашего движка:
$stencil->render('hello', [
'name' => 'Ryan'
]);
В следующей стать мы реализуем поддержку партиалов, что позволит отделить общие части шаблонов и использовать их в нескольких местах.
13+ Best PHP Template Engines to Design your PHP Web Project!
Web designers and coders can now design professional looking and functionally astounding PHP web pages easily using PHP template engines. Template engines like Mustache, Smarty, Twig etc allow you to design your PHP web project and fine tune the layout, looks, content and other visual elements without making it difficult for the back end developers to understand the altered coding later on. Moreover, you do not need to change the source code every time you have to make a change but you can simply change the design in the visual editor and the underlying code is automatically changed, generating your desired template!
- Free PHP Website Templates
- PHP Directory Templates
Twig – Best PHP Template Engine
Using the Twig template engine you can compile templates down to plain and easily understandable PHP code, modify template layout and design with minimum coding and create your own DSL with custom leyer and parsers. Trust Twig to simplify your website making process and also to present awesome template designing opportunities.
Latter – Amazing PHP Template Engine
Latte is a template engine which compiles templates to plain optimized PHP code very fast, using content aware escaping protects the templates against vulnerabilities like XSS and has better syntax which helps you build better websites without much programming knowledge also.
Dwoo – PHP5 Template Engine
Dwoo is a template engine which allows you to use various functions to simplify the coding and presentation of the templates, use various functions for executing processed in the back end and measure speed of execution and timing at various instances. You can even alter the PHP and underlying coding to sync your template easily.
Smarty – Free PHP Template Engine Download
Smarty template engine allows you to design and redesign the templates with just visual tools, separate the presentation from the back end coding for easier understanding and compile to other languages other than PHP also, indicating great portability. You are even insulated from PHP thereby granting complete freedom for development.
FOIL – Template Engine for Native PHP Templates
Foil PHP template engine allows you to choose from plenty of clean, concise and dry templates, make multiple template folders with option of auto discover and custom picking and auto or manual data escape for enhanced security. You can also use the centralized API for easy integration and maintenance.
PH7 – PHP Template Engine
The symisc PH7 template engine helps you to implement a bytecode compiler and a virtual machine while designing your website, compile and execute scripts in the process itself and provides full support for enhancing your templates and application. It is also easy to redesign the website and embed the code aligning it with the content.