Are you tired of using bloated, overcomplicated template engines that don’t quite fit your needs? Do you want to build something lightweight, secure, and tailored to your workflow? If so, you’re in the right place! In this tutorial, we’ll walk through the process of creating your very own PHP HTML template engine, which we’ll call the PHP HTML Template Engine. By the end of this guide, you’ll have a fully functional, secure, and extensible template engine that you can use in your PHP projects. How to Dynamically Load Objects with HTMX and PHP
Table of Contents
- What is the PHP HTML Template Engine?
- Step 1: Setting Up the Project
- Step 2: Building the Core Engine
- Step 3: Adding Asset Management
- Step 4: Using the PHP HTML Template Engine
- Example 1: Basic Component Rendering
- Example 2: Nested Components
- Example 3: Using PHP Components
- Example 4: Managing Assets
- Example 5: Escaping Data for Security
- Example 6: Advanced Usage with Custom Logic
- Conclusion
Whether you’re building a small website or a large-scale application, having a custom PHP HTML template engine can make your development process smoother and more efficient. Let’s dive in and create something amazing!
What is the PHP HTML Template Engine?
The PHP HTML Template Engine is a lightweight, secure, and flexible PHP HTML template engine designed to simplify the process of rendering reusable components. It allows you to create modular, maintainable, and secure templates by separating your HTML structure from your PHP logic. With features like nested components, asset management, and automatic data escaping, the PHP HTML Template Engine is perfect for modern web development. Using HTMX with PHP: Examples and Use Cases
Our goal is to build a template engine that:
- Supports both
.html
and.php
components. - Automatically escapes data to prevent XSS attacks.
- Allows nesting of components for reusability.
- Manages CSS and JavaScript assets efficiently.
- Is easy to extend and customize.
Let’s get started!
Step 1: Setting Up the Project
Before we start coding, let’s set up our project structure. Create a new directory for your project and organize it like this:
/hishuanigami-engine
/components
header.php
footer.html
/assets
/css
styles.css
/js
scripts.js
index.php
HishuanigamiEngine.php
- The
components
folder will store reusable HTML and PHP templates. - The
assets
folder will hold your CSS and JavaScript files. index.php
will be the entry point for your application.HishuanigamiEngine.php
will contain the core logic of our template engine.
Step 2: Building the Core Engine
Now, let’s dive into the code. Open HishuanigamiEngine.php
and start building the core of our PHP HTML template engine.
2.1: The Class Structure
We’ll start by defining the HishuanigamiEngine
class. This class will handle loading components, rendering templates, and managing assets.
<?php
namespace Hishuanigami;
class HishuanigamiEngine
{
private $components = [];
private $basePath;
private $assets = [
'css' => [],
'js' => []
];
private $renderDepth = 0;
const MAX_DEPTH = 10;
public function __construct(string $componentsPath = 'components')
{
$this->basePath = realpath($componentsPath);
if (!$this->basePath) {
throw new \InvalidArgumentException("Invalid components path");
}
$this->loadAllComponents();
}
}
2.2: Loading Components
The engine needs to load all available components from the components
folder. We’ll support both .html
and .php
files.
private function loadAllComponents(): void
{
foreach (glob($this->basePath . '/*.{html,php}', GLOB_BRACE) as $file) {
$componentName = pathinfo($file, PATHINFO_FILENAME);
$this->components[$componentName] = [
'path' => $file,
'type' => pathinfo($file, PATHINFO_EXTENSION)
];
}
}
2.3: Rendering Components
The renderComponent
method will handle rendering a component by its name. It also supports passing data to the component.
public function renderComponent(string $componentName, array $data = []): string
{
if (!isset($this->components[$componentName])) {
throw new \Exception("Component '$componentName' not found");
}
$component = $this->components[$componentName];
$content = $this->renderComponentContent($component, $data);
// Process nested components
$content = $this->parseNestedComponents($content, $data);
return $this->wrapWithAssets($content);
}
2.4: Handling Nested Components
One of the coolest features of the PHP HTML Template Engine is its ability to handle nested components. This allows you to create reusable, modular templates.
private function parseNestedComponents(string $content, array $data): string
{
$this->renderDepth++;
if ($this->renderDepth > self::MAX_DEPTH) {
throw new \Exception("Component nesting depth exceeded");
}
$result = preg_replace_callback(
'/{{\s*component\(\s*["\'](.+?)["\'](?:,\s*(.+?))?\s*\)\s*}}/',
function ($matches) use ($data) {
try {
$componentData = isset($matches[2]) ?
json_decode($matches[2], true, 512, JSON_THROW_ON_ERROR) :
[];
} catch (\JsonException $e) {
return '<!-- Invalid component data: ' . $this->escape($matches[2]) . ' -->';
}
if (!isset($this->components[$matches[1]])) {
return '<!-- Component missing: ' . $this->escape($matches[1]) . ' -->';
}
return $this->renderComponent(
$matches[1],
array_merge($componentData, $data)
);
},
$content
);
$this->renderDepth--;
return $result;
}
Step 3: Adding Asset Management
To make our engine even more powerful, we’ll add support for managing CSS and JavaScript assets.
public function addAsset(string $type, string $path): void
{
$validTypes = ['css', 'js'];
if (!in_array($type, $validTypes)) {
throw new \InvalidArgumentException("Invalid asset type");
}
$safePath = $this->validatePath($path);
$this->assets[$type][] = $safePath;
}
private function wrapWithAssets(string $content): string
{
$head = implode("\n", array_map(function ($css) {
return '<link rel="stylesheet" href="' . $this->escapeAttr($css) . '">';
}, $this->assets['css']));
$bottom = implode("\n", array_map(function ($js) {
return '<script src="' . $this->escapeAttr($js) . '"></script>';
}, $this->assets['js']));
return $head . "\n" . $content . "\n" . $bottom;
}
Step 4: Using the PHP HTML Template Engine
Now that our engine is ready, let’s see it in action! Open index.php
and start rendering components.
<?php
require 'HishuanigamiEngine.php';
use Hishuanigami\HishuanigamiEngine;
$engine = new HishuanigamiEngine('components');
$engine->addAsset('css', 'assets/css/styles.css');
$engine->addAsset('js', 'assets/js/scripts.js');
echo $engine->renderComponent('header', ['title' => 'Welcome to PHP HTML Template Engine']);
echo $engine->renderComponent('footer');
Let’s dive deeper into how you can use the PHP HTML Template Engine in real-world scenarios. I’ll walk you through some practical examples to demonstrate its flexibility and power. By the end of this section, you’ll have a clear understanding of how to use the engine to build modular, reusable, and secure templates.
Check out Your Own Random Anime Image Generator using Nekosia API Discord TTS Bot: Create Your Own TTS Bot for Discord Create a Dynamic PHP Routing System from Scratch How to Build Your Own Simple PHP Framework 🎉🎉
Example 1: Basic Component Rendering
Let’s start with a simple example. Suppose you have a header.php
component and a footer.html
component. Here’s how you can render them using the PHP HTML Template Engine.
Step 1: Create the Components
components/header.php
<header>
<h1>{{ title }}</h1>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>
</nav>
</header>
components/footer.html
<footer>
<p>© {{ year }} My Awesome Website</p>
</footer>
Step 2: Render the Components in index.php
<?php
require 'HishuanigamiEngine.php';
use Hishuanigami\HishuanigamiEngine;
$engine = new HishuanigamiEngine('components');
// Render the header with dynamic data
echo $engine->renderComponent('header', [
'title' => 'Welcome to Hishuanigami '
]);
// Render the footer with dynamic data
echo $engine->renderComponent('footer', [
'year' => date('Y')
]);
Output
<header>
<h1>Welcome to Hishuanigami </h1>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>
</nav>
</header>
<footer>
<p>© 2023 My Awesome Website</p>
</footer>
Example 2: Nested Components
One of the most powerful features of the PHP HTML Template Engine is its ability to handle nested components. Let’s create a card
component that uses a button
component internally.
Step 1: Create the Nested Components
components/card.html
<div class="card">
<h2>{{ title }}</h2>
<p>{{ description }}</p>
{{ component('button', { "text": "Learn More", "url": "{{ url }}" }) }}
</div>
components/button.html
<a href="{{ url }}" class="btn">{{ text }}</a>
Step 2: Render the Nested Components in index.php
<?php
require 'HishuanigamiEngine.php';
use Hishuanigami\HishuanigamiEngine;
$engine = new HishuanigamiEngine('components');
// Render the card with nested button
echo $engine->renderComponent('card', [
'title' => 'Hishuanigami ',
'description' => 'A lightweight and secure PHP HTML template engine.',
'url' => '/learn-more'
]);
Output
<div class="card">
<h2>Hishuanigami </h2>
<p>A lightweight and secure PHP HTML template engine.</p>
<a href="/learn-more" class="btn">Learn More</a>
</div>
Example 3: Using PHP Components
The Engine supports both .html
and .php
components. Let’s create a user-profile.php
component that uses PHP logic.
Step 1: Create the PHP Component
components/user-profile.php
<?php
// Example PHP logic
$user = [
'name' => $data['name'],
'email' => $data['email'],
'bio' => $data['bio']
];
?>
<div class="user-profile">
<h2>{{ name }}</h2>
<p><strong>Email:</strong> {{ email }}</p>
<p><strong>Bio:</strong> {{ bio }}</p>
</div>
Step 2: Render the PHP Component in index.php
<?php
require 'HishuanigamiEngine.php';
use Hishuanigami\HishuanigamiEngine;
$engine = new HishuanigamiEngine('components');
// Render the user profile with dynamic data
echo $engine->renderComponent('user-profile', [
'name' => 'John Doe',
'email' => '[email protected]',
'bio' => 'A passionate developer building awesome things with PHP!'
]);
Output
<div class="user-profile">
<h2>hishuanigami</h2>
<p><strong>Email:</strong> [email protected]</p>
<p><strong>Bio:</strong> A budget developer building awesome things with PHP!</p>
</div>
Example 4: Managing Assets
The Engine makes it easy to manage CSS and JavaScript assets. Let’s add some assets to our project.
Step 1: Add Assets to the Engine
<?php
require 'HishuanigamiEngine.php';
use Hishuanigami\HishuanigamiEngine;
$engine = new HishuanigamiEngine('components');
// Add CSS and JS assets
$engine->addAsset('css', 'assets/css/styles.css');
$engine->addAsset('js', 'assets/js/scripts.js');
// Render components
echo $engine->renderComponent('header', [
'title' => 'Welcome to Hishuanigami'
]);
echo $engine->renderComponent('footer', [
'year' => date('Y')
]);
Step 2: Check the Output
The engine will automatically include the assets in the rendered output:
<link rel="stylesheet" href="assets/css/styles.css">
<header>
<h1>Welcome to Hishuanigami</h1>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>
</nav>
</header>
<footer>
<p>© 2023 My Awesome Website</p>
</footer>
<script src="assets/js/scripts.js"></script>
Example 5: Escaping Data for Security
The Engine automatically escapes data to prevent XSS attacks. Let’s see how it works.
Step 1: Render a Component with Unsafe Data
<?php
require 'HishuanigamiEngine.php';
use Hishuanigami\HishuanigamiEngine;
$engine = new HishuanigamiEngine('components');
// Render a component with potentially unsafe data
echo $engine->renderComponent('header', [
'title' => '<script>alert("XSS Attack!");</script>'
]);
Step 2: Check the Output
The engine will escape the unsafe data:
<header>
<h1><script>alert("XSS Attack!");</script></h1>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>
</nav>
</header>
If you want to render raw HTML, you can use the |raw
filter in your templates:
<h1>{{ title | raw }}</h1>
Example 6: Advanced Usage with Custom Logic
You can extend the PHP HTML Template Engine to include custom logic. For example, let’s add a method to render a list of items.
Step 1: Add a Custom Method to the Engine
public function renderList(array $items): string
{
$html = '<ul>';
foreach ($items as $item) {
$html .= '<li>' . $this->escape($item) . '</li>';
}
$html .= '</ul>';
return $html;
}
Step 2: Use the Custom Method
<?php
require 'HishuanigamiEngine.php';
use Hishuanigami\HishuanigamiEngine;
$engine = new HishuanigamiEngine('components');
// Render a list using the custom method
echo $engine->renderList(['Apple', 'Banana', 'Cherry']);
Output
<ul>
<li>Apple</li>
<li>Banana</li>
<li>Cherry</li>
</ul>
Conclusion
The Hishuanigami PHP HTML Template Engine is a powerful, flexible, and secure PHP HTML template engine that you can use to build modular and maintainable templates. From basic component rendering to advanced features like nested components and asset management, this engine has everything you need to streamline your development workflow.
By following these examples, you’ve learned how to:
- Render basic and nested components.
- Use PHP logic within components.
- Manage CSS and JavaScript assets.
- Automatically escape data for security.
- Extend the engine with custom logic.
Now it’s your turn! Start using the PHP HTML Template Engine in your projects and unleash its full potential. Happy coding! 🚀