Modern PHP template engine that provides an intuitive and expressive way to build web application views. It offers a clean syntax using custom HTML attributes and supports advanced templating features like view composition, slots, conditional rendering, loops, and built-in security measures.
Pesto can be easily integrated with your favorite framework.
Pesto provides a clean syntax using custom HTML attributes.
It understands the context of {{ variables }} and escapes them to prevent XSS.
Use attributes like php-foreach and php-if
directly in your HTML.
<ul>
<li php-foreach="range(1, 10) as $number"
php-if="$number > 7">
Item {{ $number }}
</li>
</ul>
For greater clarity, use the <template> tag, which
will not be included in the final render.
<ul>
<template php-foreach="range(1, 10) as $number">
<li php-if="$number > 7">Item {{ $number }}</li>
</template>
</ul>
PHP ^8.4 is required. Pesto is available via Composer and has no third-party dependencies.
composer require millancore/pesto
use MillanCore\Pesto\PestoFactory;
$pesto = PestoFactory::create([
templatesPath: __DIR__ . '/views',
cachePath: __DIR__ . '/cache',
// [ New CustomFilters(), ... ]
]);
$pesto->make('view.php', ['user' => $user]);
Pesto makes it easy to reuse parts of your views.
The <template> tag allows you to define
php-* attributes that will be evaluated, but the tag itself will not be included in the
final render.
Input
<p php-if="$user->isAdmin()">Admin</p>
Output
<p>Admin</p>
Input
<template php-if="$user->isAdmin()">Admin</template>
Output
Admin
When working with views composed of other views, you can use partials and slots to avoid repetition.
Layout: layouts/app.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{ $title }}</title>
</head>
<body>
<header>{{ $header | slot }}</header>
<main>{{ $main | slot }}</main>
</body>
</html>
View: views/home.html
<template php-partial="layouts/app.html" php-with="['title' => 'Home']">
<!-- Named slot -->
<nav php-slot="header">
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
<!--Main Slot -->
<section>
<h1>Home</h1>
<p>Lorem ipsum...</p>
<section>
</template>
Pesto allows you to nest views, reusing the same layout multiple times in the same view.
<template php-partial="list.html">
<li>Item</li>
<li>
<ul php-partial="list.html">
<li>nested item</li>
....
</ul>
</li>
</template>
Pesto provides foreach and if directives, sufficient for building any view.
Conditionally render blocks. php-elseif and php-else
must be siblings of php-if.
<p php-if="$user->isAdmin()">Admin</p>
<p php-elseif="$user->isModerator()">Moderator</p>
<p php-else>Guest</p>
We can use to render a list of items based on an array or iterable objects.
<li php-foreach="$list as $item">
{{ $item }}
</li>
Combine directives in one single tag.
<ul>
<li php-foreach="$users as $user" php-if="$user->isAdmin()">
{{ $user->name | title }};
</li>
</ul>
Apply transformations to variables using the pipe
| operator. You can also create your own.
<p>{{ $text | upper }}</p>
<p>{{ $text | capitalize | truncate:50,... }}</p>
<p>{{ $createAt | date:'m-d-Y' }}</p>
Create a class with public methods and register it.
1. Create a filter class
// CustomFilter.php
#[AsFilter(name: 'truncate')]
public function truncate(
string $value,
int $length,
string $end = '...'
) : string
{
//...
}
2. Register it in the factory
$pesto = PestoFactory::create([
templatesPath: => __DIR__ . '/views',
cachePath: => __DIR__ . '/cache', [
new CustomFilter(),
]
]);