A simple yet powerful PHP template engine that doesn't create a new 'language' for you to learn and get used to. Uses vanilla PHP for everything, doesn't require any regex or evals, and simple caching capabilities. Could be extended to whatever you might need it to. Good for those small projects where using a framework is just too much.
class ViewEngine
{
// Enabling auto-deletion of expired cache files ()
protected $autoDeleteCache = true;
// Length of life of cache files (In minutes)
protected $cacheExpiration = 1; // 1440 24 hours
// Toggle caching on/off
protected $enableCache = false;
// In case we don't want cache to ever expire
protected $permanentCache = false;
// Various variables in-use with the template engine. Not settings
protected $includedViews = [];
protected $sections = [];
protected $layout;
protected $templateDir;
protected $cacheDir;
protected $layoutData;
public function __construct()
{
// Location of view/template files
$this->templateDir = baseDir('resources/views');
// Location of view/template cache
$this->cacheDir = baseDir('storage/cache/views');
}
public function enableCache($enable = true)
{
$this->enableCache = $enable;
}
public function extend($layout, $data = [])
{
$this->layout = $layout;
$this->layoutData = $data;
$this->render($layout, $data);
}
public function section($name, $default = '')
{
return $this->sections[$name] ?? $default;
}
public function startSection()
{
ob_start();
}
public function endSection($name)
{
$this->sections[$name] = ob_get_clean();
}
public function include($view, $data = [])
{
$includedViewPath = $this->templateDir . '/' . $view . '.php';
$this->includedViews[$view] = $includedViewPath;
ob_start();
extract($data);
include $includedViewPath;
return ob_get_clean();
}
public function render($view, $data = [])
{
if ($this->enableCache) {
$cacheFile = $this->getCacheFileName($view);
if (!$this->isCacheExpired($cacheFile)) {
// Cache is still valid, include cached file
return include $cacheFile;;
}
}
extract($data);
ob_start();
$templatePath = $this->templateDir . '/' . $view . '.php';
include $templatePath;
if ($this->layout) {
// Extract layout data and merge with view data
$layoutData = array_merge($this->layoutData, $data);
extract($layoutData);
include "{$this->templateDir}/{$this->layout}.php";
}
$content = ob_get_clean();
if ($this->enableCache) {
// Save content to cache file
file_put_contents($cacheFile, $content);
}
return $content;
}
public function setCacheExpiration($minutes)
{
$this->cacheExpiration = $minutes;
}
protected function isCacheExpired($cacheFile)
{
if ($this->enableCache && file_exists($cacheFile)) {
if ($this->permanentCache === true) {
return false;
}
$fileTime = filemtime($cacheFile);
$expirationTime = $fileTime + ($this->cacheExpiration * 60);
return time() > $expirationTime;
}
$this->deleteExpiredCache($cacheFile);
return true;
}
protected function getCacheFileName($view)
{
return $this->cacheDir . '/' . md5($view) . '.php';
}
public function enableAutoDeleteCache($enable = true)
{
$this->autoDeleteCache = $enable;
}
public function enablePermanentCache($enable = true)
{
$this->permanentCache = $enable;
}
protected function deleteExpiredCache($cacheFile)
{
if ($this->enableCache && $this->autoDeleteCache) {
if (file_exists($cacheFile) && $this->isCacheExpired($cacheFile)) {
unlink($cacheFile);
}
}
}
}
This code snippet was published on It was last edited on
<?= $this->include('path/to/file', ['feature' => 'As Requested']) ?>
The file you include could also be in a different directory. Starting from the base template directory. — Bogey