CommentTemplate

CommentTemplate is a powerful PHP template engine with asset compilation, template inheritance, and variable processing. It provides a simple yet flexible way to manage templates with built-in CSS/JS minification and caching.

Features

  • Template Inheritance: Use layouts and include other templates
  • Asset Compilation: Automatic CSS/JS minification and caching
  • Variable Processing: Template variables with filters and commands
  • Base64 Encoding: Inline assets as data URIs
  • Flight Framework Integration: Optional integration with Flight PHP framework

Installation

Install with composer.

composer require knifelemon/comment-template

Basic Configuration

There are some basic configuration options to get started. You can read more about them in the CommentTemplate Repo.

Method 1: Using Callback Function

<?php
require_once 'vendor/autoload.php';

use KnifeLemon\CommentTemplate\Engine;

$app = Flight::app();

$app->register('view', Engine::class, [], function (Engine $engine) use ($app) {
    // Where your template files are stored
    $engine->setTemplatesPath(__DIR__ . '/views');

    // Where your public assets will be served from
    $engine->setPublicPath(__DIR__ . '/public');

    // Where compiled assets will be stored
    $engine->setAssetPath('assets');

    // Template file extension
    $engine->setFileExtension('.php');
});

$app->map('render', function(string $template, array $data) use ($app): void {
    echo $app->view()->render($template, $data);
});

Method 2: Using Constructor Parameters

<?php
require_once 'vendor/autoload.php';

use KnifeLemon\CommentTemplate\Engine;

$app = Flight::app();

// __construct(string $publicPath = "", string $skinPath = "", string $assetPath = "", string $fileExtension = "")
$app->register('view', Engine::class, [
    __DIR__ . '/public',    // publicPath - where assets will be served from
    __DIR__ . '/views',     // skinPath - where template files are stored  
    'assets',               // assetPath - where compiled assets will be stored
    '.php'                  // fileExtension - template file extension
]);

$app->map('render', function(string $template, array $data) use ($app): void {
    echo $app->view()->render($template, $data);
});

Template Directives

Layout Inheritance

Use layouts to create a common structure:

layout/global_layout.php:

<!DOCTYPE html>
<html>
<head>
    <title>{$title}</title>
</head>
<body>
    <!--@contents-->
</body>
</html>

view/page.php:

<!--@layout(layout/global_layout)-->
<h1>{$title}</h1>
<p>{$content}</p>

Asset Management

CSS Files

<!--@css(/css/styles.css)-->          <!-- Minified and cached -->
<!--@cssSingle(/css/critical.css)-->  <!-- Single file, not minified -->

JavaScript Files

CommentTemplate supports different JavaScript loading strategies:

<!--@js(/js/script.js)-->             <!-- Minified, loaded at bottom -->
<!--@jsAsync(/js/analytics.js)-->     <!-- Minified, loaded at bottom with async -->
<!--@jsDefer(/js/utils.js)-->         <!-- Minified, loaded at bottom with defer -->
<!--@jsTop(/js/critical.js)-->        <!-- Minified, loaded in head -->
<!--@jsTopAsync(/js/tracking.js)-->   <!-- Minified, loaded in head with async -->
<!--@jsTopDefer(/js/polyfill.js)-->   <!-- Minified, loaded in head with defer -->
<!--@jsSingle(/js/widget.js)-->       <!-- Single file, not minified -->
<!--@jsSingleAsync(/js/ads.js)-->     <!-- Single file, not minified, async -->
<!--@jsSingleDefer(/js/social.js)-->  <!-- Single file, not minified, defer -->

Asset Directives in CSS/JS Files

CommentTemplate also processes asset directives within CSS and JavaScript files during compilation:

CSS Example:

/* In your CSS files */
@font-face {
    font-family: 'CustomFont';
    src: url('<!--@asset(fonts/custom.woff2)-->') format('woff2');
}

.background-image {
    background: url('<!--@asset(images/bg.jpg)-->');
}

.inline-icon {
    background: url('<!--@base64(icons/star.svg)-->');
}

JavaScript Example:

/* In your JS files */
const fontUrl = '<!--@asset(fonts/custom.woff2)-->';
const imageData = '<!--@base64(images/icon.png)-->';

Base64 Encoding

<!--@base64(images/logo.png)-->       <!-- Inline as data URI -->

Example:

<!-- Inline small images as data URIs for faster loading -->
<img src="<!--@base64(images/logo.png)-->" alt="Logo">
<div style="background-image: url('<!--@base64(icons/star.svg)-->');">
    Small icon as background
</div>

Asset Copying

<!--@asset(images/photo.jpg)-->       <!-- Copy single asset to public directory -->
<!--@assetDir(assets)-->              <!-- Copy entire directory to public directory -->

Example:

<!-- Copy and reference static assets -->
<img src="<!--@asset(images/hero-banner.jpg)-->" alt="Hero Banner">
<a href="<!--@asset(documents/brochure.pdf)-->" download>Download Brochure</a>

<!-- Copy entire directory (fonts, icons, etc.) -->
<!--@assetDir(assets/fonts)-->
<!--@assetDir(assets/icons)-->

Template Includes

<!--@import(components/header)-->     <!-- Include other templates -->

Example:

<!-- Include reusable components -->
<!--@import(components/header)-->

<main>
    <h1>Welcome to our website</h1>
    <!--@import(components/sidebar)-->

    <div class="content">
        <p>Main content here...</p>
    </div>
</main>

<!--@import(components/footer)-->

Variable Processing

Basic Variables

<h1>{$title}</h1>
<p>{$description}</p>

Variable Filters

{$title|upper}                       <!-- Convert to uppercase -->
{$content|lower}                     <!-- Convert to lowercase -->
{$html|striptag}                     <!-- Strip HTML tags -->
{$text|escape}                       <!-- Escape HTML -->
{$multiline|nl2br}                   <!-- Convert newlines to <br> -->
{$html|br2nl}                        <!-- Convert <br> tags to newlines -->
{$description|trim}                  <!-- Trim whitespace -->
{$subject|title}                     <!-- Convert to title case -->

Variable Commands

{$title|default=Default Title}       <!-- Set default value -->
{$name|concat= (Admin)}              <!-- Concatenate text -->

Variable Commands

{$content|striptag|trim|escape}      <!-- Chain multiple filters -->

Example Project Structure

project/
├── source/
│   ├── layouts/
│   │   └── default.php
│   ├── components/
│   │   ├── header.php
│   │   └── footer.php
│   ├── css/
│   │   ├── bootstrap.min.css
│   │   └── custom.css
│   ├── js/
│   │   ├── app.js
│   │   └── bootstrap.min.js
│   └── homepage.php
├── public/
│   └── assets/           # Generated assets
│       ├── css/
│       └── js/
└── vendor/