nabeghe / risma
A lightweight, zero-dependency string template engine and interpreter for PHP โ embed logic, conditionals, and function pipelines directly inside strings.
Requires
- php: >=7.4
Requires (Dev)
- pestphp/pest: ^4.7
- pestphp/pest-plugin: ^4.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
โก Risma
A Lightweight String Template Engine & Interpreter for PHP
๐ Read Full Documentation & Interactive Guides โ
๐ฎ What is Risma?
The logic lives inside the string itself.
Risma is a zero-dependency PHP string template engine and interpreter. It embeds processing logic, conditionals, and transformation pipelines directly inside plain text strings.
No eval(). No runtime dependencies. Safe for user-provided templates.
use Nabeghe\Risma\Risma; // The string IS the program: // Combines variables, pipelines, built-in conditionals, and Direct Function Execution (@) $template = 'Hi {user.trim.title}! You have {unread} unread {unread.plural("message", "messages")}. ' . 'Server time: {@date("H:i")} | Status: {@phpversion.truncate(3, "").if_gte("8.0", "Modern ๐ (%s)", "Legacy โ ๏ธ (%s)")}'; echo Risma::quick($template, [ 'user' => ' sarah connor ', 'unread' => 5, ]); // Output: Hi Sarah Connor! You have 5 unread messages. Server time: 14:30 | Status: Modern ๐ (8.4)
๐ก Real-World Use Cases
- ๐ Dynamic Translations: Store translations with built-in pluralization and fallbacks directly in your lang files:
'{count.plural("%s item", "%s items", "No items")}' - ๐ง Notification & Email Templates: Marketers and editors write smart strings without developers touching PHP:
'Hi {name.or("there")}! Order #{id} is {status.upper}. Details: {notes.flatten_lines.if_empty("None")}' - ๐งฉ Safe CMS Sandboxing: Safe execution of user-authored templates with a deterministic lexer (strictly zero
eval()).
โก Syntax at a Glance
- ๐ฏ Direct Execution (
@): Run standalone functions or chain pipelines onto them without a variable:{@date('Y')}or{@rand(1, 100).if_gte('50', 'Pass (%s)', 'Fail (%s)')}or{@line} - ๐ Pipeline Chaining (
.): Pipe data through functions using dot notation:{user.trim.lower.title} - ๐ฏ Argument Routing (
$): Pinpoint where the piped value should land:{slug.str_replace('-', ' ', '$')} - ๐ช Deep Nesting: Recursively resolve placeholders inside arguments from inside out:
{@sprintf("Hello %s", "{user.upper}")} - ๐จ Custom Delimiters & Shared Globals (v2): Configure custom tags (
[: :]) and app-wide shared variables.
๐ Installation & Quick Start
composer require nabeghe/risma
use Nabeghe\Risma\Risma; // 1. Instant static execution with direct functions (@) and pipelines: echo Risma::quick( 'Welcome {user.trim.title}! Server year: {@date("Y")} (PHP {@phpversion.truncate(3, "")})', ['user' => ' hadi '] ); // Output: Welcome Hadi! Server year: 2026 (PHP 8.3) // 2. Instance execution with custom delimiters, shared globals, and direct execution: $risma = (new Risma()) ->share('app', 'CloudPortal') ->setDelimiters('[:', ':]'); echo $risma->render( '[:app:] ยฉ [:@date("Y"):] โ Welcome, [:user.upper:]!', ['user' => 'Ali'] ); // Output: CloudPortal ยฉ 2026 โ Welcome, ALI!
๐ Documentation & Guides
For the complete manual, interactive search, comprehensive API reference, and production recipes:
๐งช Testing
composer test # or: vendor/bin/pest
๐ License
Risma is open-sourced software licensed under the MIT License.