Template Engine
Syntax, directives, and caching behavior of `.velvet.php` files.
VelvetCMS ships a compact Blade-inspired engine (VelvetCMS\Services\TemplateEngine) with automatic escaping and compiled template caching.
Rendering life cycle #
ThemeServiceasks the engine to renderlayouts/<name>orpartials/<name>.- The engine compiles the
.velvet.phpfile to raw PHP understorage/cache/templates/(hashed per file path). - On subsequent requests the cached PHP is reused until the source file’s
mtimechanges.
Clear caches on deploy with ThemeService::clearCache() or blow away storage/cache/templates.
Output directives #
| Syntax | Behavior |
|---|---|
{{ $var }} |
Escaped via the global e() helper (prevents XSS). |
{!! $var !!} |
Raw output—only use with trusted HTML. |
@raw ... @endraw |
Emits content exactly as written (useful for inline scripts). |
Control structures #
| Directive | Equivalent PHP |
|---|---|
@if, @elseif, @else, @endif |
if/elseif/else blocks. |
@foreach ($items as $item) / @endforeach |
Loops over arrays/collections. |
@for, @endfor and @while, @endwhile |
Native loops. |
@php ... @endphp |
Inline PHP block. |
Layouts & sections #
@extends('layouts/base')
@section('hero')
<h1>{{ $page->title }}</h1>
@endsection
@section('content')
{!! $content !!}
@endsection
@extends('layouts/base')must appear near the top of the child template.@section('name')+@endsectioncapture output;@yield('name', 'fallback')renders it inside the parent.- Nested sections are tracked via an internal stack—
@endsectionmust match every@section.
Includes & partials #
@include('partials/nav', ['active' => 'docs'])renders another.velvet.phpfile with merged variables.- From PHP you can call
$theme->partial('nav', [...])or$theme->block('cta').
Forms & security helpers #
| Directive | Rendered HTML |
|---|---|
@csrf |
<input type="hidden" name="_token" value="..."> |
@method('PUT') |
<input type="hidden" name="_method" value="PUT"> |
Pair them with VerifyCsrfToken middleware to protect POST/PUT/PATCH/DELETE requests.
Custom variables & helpers #
The engine exposes everything you pass via $theme->render() plus the helper closures described in the Theme Basics guide. You can attach global helpers using $theme->set() or register functions inside modules (e.g., view() helper wraps ThemeService::view()).
Debug tips #
- Use
dump($vars)ordd($vars)directly inside templates—they’re just PHP under the hood. - Template compilation errors show the generated cache path; delete the offending
.phpfile understorage/cache/templatesto force recompilation. - Keep logic minimal: compute data in controllers or modules, pass it into the view, and reserve templates for presentation.
Knowing these directives and cache mechanics will make writing Velvet themes feel familiar to anyone who has used Blade/Twig, without pulling in a heavyweight dependency.