millancore / pesto
PHP View Engine
Requires
- php: ^8.4
- ext-dom: *
- ext-libxml: *
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.86
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^12.3
- symfony/var-dumper: ^7.3
This package is auto-updated.
Last update: 2025-08-18 14:22:13 UTC
README
composer require millancore/pesto
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 understands the context of {{ variables }}
and escapes them according to their scope to avoid
Cross-Site Scripting (XSS) issues.
<ul> <li php-foreach="range(1, 10) as $number" php-if="$number > 7">Item {{ $number }}</li> </ul>
Or, for greater clarity, use <template>
, 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>
Result:
<ul> <li>Item 8</li> <li>Item 9</li> <li>Item 10</li> </ul>
Installation & Usage
- PHP ^8.4
Pesto is available via Composer: composer require millancore/pesto
and is free of third-party dependencies
use MillanCore\Pesto\PestoFactory; $pesto = PestoFactory::create([ templatesPath: __DIR__ . '/views', cachePath: __DIR__ . '/cache', ]); $pesto->render('view.php', ['user' => $user]);
Features
Pesto templates use files with the .php
extension,
allowing you to seamlessly integrate PHP code
View Composition
Pesto makes it easy to reuse parts of your views
Template Tag
The <template>
tag allows you to define php-* attributes
that will be evaluated but not the tag included in the final render.
<p php-if="$user->isAdmin()">Admin</p>
--><p>Admin</p>
<template php-if="$user->isAdmin()">Admin</template>
-->Admin
Partials & Slots
When working with views that are composed of other views, you can use partials and slots to avoid repetition.
Layout
<!--- layouts/app.php --> <!DOCTYPE html> <html lang="en"> <head> <title>{{ $title }}</title> </head> <body> <header>{{ $header }}</header> <main>{{ $slot }}</main> </body> </html>
View:
<!--- views/home.php --> <template php-partial="layouts/app.php" 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 dolor sit amet consectetur adipisicing elit. Quisquam, quae.</p> <section> </template
Nested Views
Pesto allows you to nest views, allowing you to reuse the same layout for multiple times in the same view.
<template php-partial="list.php"> <li>Item</li> <li> <ul php-partial="list.php"> <li>nested item</li> .... </ul> </li> </template>
Control Flow
Pesto provides two control flow directives: foreach
and if
, enough to build any kind of view.
If Attribute
The only rule importance for use php-elseif
and php-else
is the tag must be a sibling of the php-if
tag.
php-if
php-elseif
php-else
php-if
allows you to conditionally render a block of code.
<p php-if="$user->isAdmin()">Admin</p> <p php-elseif="$user->isModerator()">Moderator</p> <p php-else>Guest</p>
Loops
Pesto provides a simple way to loop over arrays or objects.
<ul php-foreach="$list as $item"> <li>{{ $item }}</li> </ul>
Inline
Pesto also allows you to use inline control flow directives.
<ul php-foreach="$users as $user" php-if="$user->isAdmin()">> <li>{{ $user->name | ucfirst }}</li> <li>{{ $user->email }}</li> </ul>
Filters
Pesto provides a simple way to apply filters to variables using the pipe operator, you can define your own filters or use the php built-in functions.
<p>{{ $text | strtoupper }}</p>
Chain Filters
You can chain multiple filters together.
<p>{{ $text | ucfirst | truncate:50,... }}</p>
Filters with Arguments
To pass arguments to a filter, you can use the :
operator.
<p>{{ $createAt | date:m-d-Y }}</p>