Installation:
composer require codewithkyrian/jinja-php
No additional dependencies required.
First Use Case: Render a simple ML chat template:
use CodeWithKyrian\Jinja\Template;
$template = new Template("{{ bos_token }}{{ message.content }}");
$rendered = $template->render([
'bos_token' => '<s>',
'message' => ['content' => 'Hello, world!']
]);
Where to Look First:
// In a Laravel controller
public function renderChatTemplate(Request $request) {
$template = new Template(file_get_contents('resources/templates/chat.jinja'));
$data = [
'messages' => $request->messages,
'bos_token' => config('app.bos_token'),
];
return response()->json(['output' => $template->render($data)]);
}
// Define macros in a template file
$template = new Template(<<<'JINJA'
{% macro formatMessage(message) %}
<div class="message {{ message.role }}">
{{ message.content }}
</div>
{% endmacro %}
{% for message in messages %}
{{ formatMessage(message) }}
{% endfor %}
JINJA);
// Render with data
$rendered = $template->render(['messages' => [...]]);
// Process text in templates
$template = new Template("{{ text|upper|replace('HELLO', 'Hi') }}");
$rendered = $template->render(['text' => 'hello world']);
// Create a custom view resolver
app()->resolving(View::class, function () {
View::addExtension('jinja', function ($path, array $data) {
$template = new Template(file_get_contents($path));
return $template->render($data);
});
});
// Usage in Blade
@jinja('templates/email.jinja', ['user' => $user])
use CodeWithKyrian\Jinja\Environment;
$env = new Environment();
$env->addFilter('custom_filter', function ($value) {
return strtoupper($value) . '!';
});
$template = new Template("{{ text|custom_filter }}");
$rendered = $template->render(['text' => 'hello'], $env);
Negative Array Indexing:
messages[-1]), which may confuse developers used to PHP's end($array).Boolean Literals:
true/false and True/False (case-insensitive).null is not falsy; use none or None for null literals.String Concatenation:
~ operator ({{ "a" ~ "b" }}), not PHP's ..~ in raw strings by doubling: {{ "a~~b" }}.Loop Variables:
loop.index0 starts at 0 (like Python), not 1 (like PHP's array_key_first).{% for item in items %}
{{ loop.index }} {# 1-based #}
{{ loop.index0 }} {# 0-based #}
{% endfor %}
Template Inheritance:
Custom Functions:
Enable Debug Mode:
$template = new Template($source);
$template->setDebug(true); // Shows parsing errors with line numbers
Inspect Parsed AST:
$ast = $template->parse();
print_r($ast->dump()); // Dump the Abstract Syntax Tree
Common Errors:
Undefined variable: Ensure all variables in templates exist in $args.SyntaxError: Validate templates against Jinja spec.Call to undefined function: Use filters or macros instead of custom functions.Custom Filters:
$env->addFilter('slugify', function ($value) {
return Str::slug($value);
});
Custom Transformers:
$env->addTransformer('generation', function ($value) {
return str_replace(['<s>', '</s>'], ['[START]', '[END]'], $value);
});
Pre/Post-Processing:
$template->setPreProcessor(function ($source) {
return str_replace('{{{', '{{', $source); // Custom tag support
});
Environment Configuration:
$env = new Environment();
$env->setStrictVariables(true); // Throw errors for undefined variables
$env->setAutoescape(false); // Disable HTML escaping
Cache Parsed Templates:
$cacheKey = 'template_' . md5($templateSource);
if (cache()->has($cacheKey)) {
$rendered = cache()->get($cacheKey);
} else {
$rendered = $template->render($data);
cache()->put($cacheKey, $rendered, now()->addHours(1));
}
Avoid Overusing Macros:
Minimize Filters:
{{ text|upper|title }} is less efficient than {{ (text|upper)|title }}).How can I help you explore Laravel packages today?