Forráskód Böngészése

Enhance README with additional features and usage

Expanded README with detailed features and usage examples.
F. Michel 1 hónapja
szülő
commit
a28c17ff2c
1 módosított fájl, 189 hozzáadás és 42 törlés
  1. 189 42
      README.md

+ 189 - 42
README.md

@@ -1,83 +1,230 @@
 # PurePlate
 
-Pure is a high-performance, lexer-based template engine for PHP 7.4+. It compiles a clean, intuitive syntax into native cached PHP code with zero runtime overhead.
+**A lightweight template engine for PHP. The syntax of Twig. The power of native PHP. None of the weight.**
 
-## Installation
+PurePlate parses templates with PHP's native `token_get_all()` lexer and compiles them to plain, cached PHP. No runtime overhead. No bloat. No magic.
+
+```twig
+{% extends "layout.tpl" %}
+
+{% block content %}
+    <h1>Hello, {{ user.name|upper }}!</h1>
+
+    {% if items is not empty %}
+        <ul>
+        {% foreach items as item %}
+            <li>{{ item.title }} — {{ item.price|number_format(2, ',', ' ') }} €</li>
+        {% endforeach %}
+        </ul>
+    {% endif %}
+{% endblock %}
+```
+
+---
+
+## Why PurePlate
+
+### 1. Any PHP function works as a filter — out of the box
+
+In Twig, every filter must be registered:
+
+```php
+// Twig: you have to declare each function as a filter
+$twig->addFilter(new TwigFilter('upper', 'strtoupper'));
+$twig->addFilter(new TwigFilter('format', 'number_format'));
+```
+
+In PurePlate, every PHP function is already a filter:
+
+```twig
+{{ name|strtoupper }}
+{{ price|number_format(2, ',', ' ') }}
+{{ text|substr(0, 100) }}
+{{ items|count }}
+{{ date|date("Y-m-d") }}
+```
+
+No registration. No wrappers. The entire PHP standard library is available immediately.
+
+### 2. Lexer-based, not regex-based
+
+Templates are tokenized with PHP's own `token_get_all()` — the same lexer PHP uses to parse its own source code. This means:
+
+- Correct handling of strings, escapes, nested quotes
+- No regex edge-cases that break on unusual input
+- Predictable, deterministic parsing
+
+### 3. Compile-time validation
+
+Generated PHP is validated with `TOKEN_PARSE` **before** being cached. If the compilation produces invalid PHP, you know immediately — not at runtime, not in production.
+
+### 4. Source-mapped errors
+
+Every compiled line carries a comment pointing back to the original template:
+
+```php
+<?php /*L:14;F:templates/page.tpl*/ echo htmlspecialchars(...); ?>
+```
+
+When an error happens, PurePlate rewrites the exception to point at the **template file and line**, not the cached PHP file.
+
+```
+PurePlate Error: Undefined variable $username [At: templates/page.tpl:14]
+```
+
+### 5. Auto-escaping by default
+
+`{{ var }}` is always passed through `htmlspecialchars(..., ENT_QUOTES)`. Output is safe by default.
+
+---
 
-You can install the library using Composer. Just run the following command:
+## Comparison
+
+|                              | Twig 3      | PurePlate   |
+|------------------------------|-------------|-------------|
+| Syntax                       | Twig        | Twig-like   |
+| PHP function as filter       | ❌ Must register | ✅ Native |
+| Compile-time syntax check    | ❌          | ✅          |
+| Source-mapped errors         | ⚠️ Complex   | ✅ Inline   |
+| PHP 7.4 support              | ⚠️ Twig 3.x only | ✅      |
+| Dependencies                 | Several     | Zero        |
+| Auto-escape                  | ✅          | ✅          |
+
+---
+
+## Installation
 
 ```bash
 composer require michel/pure-plate
 ```
 
-## Basic Usage
+PHP 7.4 or higher. No other runtime dependencies.
 
-To use the renderer in your project, first create an instance of the `PhpRenderer` class and pass the directory where your templates are located.
+---
+
+## Quick Start
 
 ```php
-use Michel\Renderer\PhpRenderer;
+use Michel\PurePlate\Engine;
+
+$plate = new Engine(__DIR__ . '/templates');
+
+echo $plate->render('page.tpl', [
+    'user'  => ['name' => 'fady'],
+    'items' => [
+        ['title' => 'Item A', 'price' => 19.90],
+        ['title' => 'Item B', 'price' => 42.00],
+    ],
+]);
+```
 
-// Specify the template directory
-$templateDir = '/path/to/templates';
+---
 
-// Optional global variables to be passed to all templates
-$globals = [
-    'siteTitle' => 'My Website',
-];
+## Syntax
 
-// Create the renderer instance
-$renderer = new PhpRenderer($templateDir, $globals);
+### Output
+
+```twig
+{{ variable }}                       {# auto-escaped #}
+{{ user.name }}                      {# same as user->name #}
+{{ user.getName() }}                 {# method call #}
+{{ value|filter }}                   {# any PHP function #}
+{{ value|filter(arg1, arg2) }}       {# with arguments #}
 ```
 
-### Creating a Layout
+### Control structures
+
+```twig
+{% if condition %} ... {% elseif other %} ... {% else %} ... {% endif %}
+{% foreach items as item %} ... {% endforeach %}
+{% for i = 0; i < 10; i++ %} ... {% endfor %}
+{% while condition %} ... {% endwhile %}
+```
 
-Create a layout file (e.g., `layout.php`) that represents the common structure of your pages. Use `block()` to define sections that will be replaced by content from child templates.
+### Tests
 
-```php
-<!DOCTYPE html>
+```twig
+{% if list is empty %} ... {% endif %}
+{% if list is not empty %} ... {% endif %}
+{% if not active %} ... {% endif %}
+```
+
+### Variable assignment
+
+```twig
+{% set total = price * quantity %}
+```
+
+### Template inheritance
+
+```twig
+{# layout.tpl #}
 <html>
-<head>
-    <title><?php echo $this->block('title'); ?></title>
-</head>
 <body>
-    <div class="container">
-        <?php echo $this->block('content'); ?>
-    </div>
+    {% block content %}{% endblock %}
 </body>
 </html>
+
+{# page.tpl #}
+{% extends "layout.tpl" %}
+{% block content %}
+    <h1>Hello</h1>
+{% endblock %}
+```
+
+### Includes
+
+```twig
+{% include "partials/header.tpl" %}
 ```
 
-### Creating a Template
+### Comments
 
-Create your template file (e.g., `page.php`). Use `extend()` to specify the layout file and `startBlock()` / `endBlock()` to define the content for the blocks.
+```twig
+{# This will not appear in the output #}
+```
 
-```php
-<?php $this->extend('layout.php'); ?>
+---
 
-<?php $this->startBlock('title'); ?>
-    My Page Title
-<?php $this->endBlock(); ?>
+## Dev mode
 
-<?php $this->startBlock('content'); ?>
-    <h1>Hello, <?php echo $name; ?>!</h1>
-    <p>Welcome to my website.</p>
-<?php $this->endBlock(); ?>
+In dev mode, templates are recompiled on every request:
+
+```php
+$plate = new Engine(__DIR__ . '/templates', devMode: true);
 ```
 
-### Rendering Templates
+In production (default), templates are compiled once and cached. The cache is invalidated automatically when the template source changes.
+
+---
+
+## Cache directory
 
-To render your template, use the `render` method. You can pass an array of variables to be extracted and made available within the template.
+By default, compiled templates are stored in the system temp directory. To customize:
 
 ```php
-echo $renderer->render('page.php', ['name' => 'John']);
+$plate = new Engine(
+    templateDir: __DIR__ . '/templates',
+    devMode: false,
+    cacheDir: __DIR__ . '/var/cache/plate'
+);
 ```
 
-This will render `page.php`, inject its blocks into `layout.php`, and return the final HTML.
+---
 
-## Contributing
+## Globals
+
+Variables passed as globals are available in every template without being re-passed at each render:
+
+```php
+$plate = new Engine(__DIR__ . '/templates', globals: [
+    'siteTitle' => 'My Site',
+    'version'   => '1.0',
+]);
+```
 
-Contributions to the PurePlate library are welcome! If you find any issues or want to suggest enhancements, feel free to open a GitHub issue or submit a pull request.
+---
 
 ## License
 
-PurePlate is open-source software released under the Mozilla Public License 2.0. See the [LICENSE](LICENSE) file for more details.
+Mozilla Public License 2.0