PHPackages                             stempler/stempler - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. stempler/stempler

ActiveLibrary[Templating &amp; Views](/categories/templating)

stempler/stempler
=================

Stempler, HTML markup processor and template engine framework

3.49.0(1mo ago)00MITPHPPHP &gt;=8.1

Since Feb 3Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/stempler-php/stempler)[ Packagist](https://packagist.org/packages/stempler/stempler)[ Docs](https://github.com/stempler-php/stempler/)[ GitHub Sponsors](https://github.com/sponsors/spiral)[ RSS](/packages/stempler-stempler/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependencies (4)Versions (97)Used By (0)

Stempler
========

[](#stempler)

Stempler is a standalone PHP template engine and HTML markup processor with support for Blade-like directives, context-aware escaping, inheritance, stacks, component imports, and AST visitors.

This project is a standalone fork of `spiral/stempler` without coupling to the Spiral Framework.

Installation
------------

[](#installation)

```
composer require stempler/stempler
```

Requirements:

- PHP `>=8.1`
- `ext-json`

Quick Start
-----------

[](#quick-start)

### Render a file-based template

[](#render-a-file-based-template)

Create `views/hello.dark.php`:

```
Hello, {{ $name }}!
```

Render it with `DirectoryLoader`:

```
use Stempler\Loader\DirectoryLoader;
use Stempler\Stempler;

$stempler = Stempler::create(
    new DirectoryLoader(__DIR__ . '/views'),
);

echo $stempler->render('hello', [
    'name' => '',
]);
```

Output:

```
Hello, &lt;John&gt;!

```

`DirectoryLoader` resolves `hello` to `views/hello.dark.php` by default.

### Enable filesystem cache

[](#enable-filesystem-cache)

```
use Stempler\Loader\DirectoryLoader;
use Stempler\Stempler;
use Stempler\StemplerCache;

$stempler = Stempler::create(
    new DirectoryLoader(__DIR__ . '/views'),
    cache: new StemplerCache(__DIR__ . '/runtime/stempler'),
);
```

Cache is used only for filesystem-backed templates. Drop a single cached template with:

```
$stempler->reset('hello');
```

### Render an in-memory template

[](#render-an-in-memory-template)

```
use Stempler\Loader\StringLoader;
use Stempler\Stempler;

$loader = new StringLoader();
$loader->set('hello', 'Hello, {{ $name }}!');

echo Stempler::create($loader)->render('hello', [
    'name' => 'Jane',
]);
```

Core API
--------

[](#core-api)

- `Stempler::create(LoaderInterface $loader, iterable $directives = [], array $visitors = [], ?StemplerCache $cache = null): Stempler`
- `render(string $path, array $data = []): string`
- `compile(string $path): Result`
- `load(string $path): Template`
- `makeSourceMap(Result|string $source): ?SourceMap`
- `reset(string $path): void`

Stempler templates also support raw PHP syntax:

```
Hello, !
```

> **Danger**`{{ $name }}` applies automatic escaping and is the safe default. `` does not escape output, so values must be escaped manually when needed.

#### Context-Aware escaping

[](#context-aware-escaping)

The escape strategy changes depending on where you echo your value. You can safely embed values inside `script` tags:

```

    const value = {{ $name }};

```

It will be rendered differently depending on the value type:

:::: tabs

::: tab String

```

    const value = "John";

```

:::

::: tab Number

```

    const value = 123;

```

:::

::: tab Null

```

    const value = null;

```

:::

::: tab List

```

    const value = ["John"];

```

:::

::: tab Array

```

    const value = {"first": "John", "last": "Doe"};

```

:::

::::

#### Disable Escaping

[](#disable-escaping)

To output a value without automatic escaping, use:

```
{!! $value !!}
```

Example:

```
$stempler = Stempler::create(
    new DirectoryLoader(__DIR__ . '/views'),
);

echo $stempler->render('welcome', [
    'html' => 'Hello world',
]);
```

Template:

```
{!! $html !!}
```

Output with disabled escaping:

```
Hello world
```

Output with `{{ $html }}`:

```
&lt;div&gt;Hello world&lt;/div&gt;
```

Directives
----------

[](#directives)

In addition to the classic echo constructions, Stempler supports many Blade-like directives to control the business logic of your templates.

Unlike Blade or Twig, Stempler directives are only responsible for managing business logic.

> **Note**See [Components and Props](#components-and-props) and [Inheritance](#inheritance-and-stacks) to check how to extend your templates and implement virtual components.

### Loop Directives

[](#loop-directives)

Stempler provides several loop directives to help you manage the rendering of repetitive elements in your templates. These directives make it easy to incorporate dynamic content into your templates.

> **Note**The directive declaration is similar to native PHP syntax.

#### Foreach

[](#foreach)

Use the directive `@foreach` and `@endforeach` to render the loop:

```

    @foreach($items as $item)
    {{ $item }}
    @endforeach

```

#### For

[](#for)

Use the directive `@for` and `@endfor` to render the loop:

```

    @for($i = 0; $i < 10; $i++)
    {{ $i }}
    @endfor

```

#### While

[](#while)

Use the directive `@while` and `@endwhile` to render `while` loop:

```

    @while($i < 10)
    {{ $i }}
    @php $i++; @endphp
    @endwhile

```

#### Break and Continue

[](#break-and-continue)

Use the `@break` and `@continue` directives to interrupt your loops:

```

    @while(true)
    {{ $i }}
    @if($i++ > 10)
        @break
    @endif
    @endwhile

```

> **Note**`@break(2)` is equivalent to `break 2`. Read more about `if` directives below.

### Conditional Directives

[](#conditional-directives)

Stempler provides several directives for creating conditional statements in your templates. These directives are transcribed into native PHP code and offer a more readable and efficient way to handle conditions in your templates.

The examples are given with the following variables:

```
return $this->views->render('welcome', [
    'value' => 123
]);
```

#### If and Else

[](#if-and-else)

To create a simple conditional statement, use the `@if` and `@endif` directives.

```
@if($value === 123)
    Hello World
@endif
```

To add an `else` condition, use the `@else` directive.

```
@if($value !== 123)
    Value is not 123
@else

@endif
```

For more complex conditions, use the `@elseif` directive.

```
@if($value === 124)
    Value is not 124
@elseif($value === 123)
    Value is 123
@else
    Another value
@endif
```

#### Unless

[](#unless)

The `@unless` directive allows you to create a negative condition, and can be used with `@else` and `@elseif` like the `@if` directive.

```
@unless($value === 124)
    Value is not 124
@endunless
```

> **Note**You can use `@else` and `@elseif` with the `@unless` directive.

#### Empty and Isset

[](#empty-and-isset)

Use the `@empty` and `@isset` conditions to check if a variable is empty or set, respectively.

:::: tabs

::: tab Empty

```
@empty($value)
    Value is empty
@endempty
```

:::

::: tab Isset

```
@isset($value)
    Value is set
@endisset
```

:::

::::

#### Switch case

[](#switch-case)

For more complex conditions, you can use the `@switch`, `@case` and `@break` statements.

```
@switch($value)
    @case(123) value is 123 @break
    @case(124) value is 124 @break
    @case(125) value is 125 @break
@endswitch
```

### Json Directive

[](#json-directive)

The `@json` directive allows you to render JSON data within a page. To use it, simply pass a variable to the directive, like this:

```
@json($value)
```

> **Note**The `@json` directive is equivalent to `json_encode($value)`.

And setting a variable:

```
return $this->views->render('welcome', [
    'value' => ...
]);
```

And the output will be:

:::: tabs

::: tab String

In case of a string value `['value' => 'Hello world']`:

```
"Hello world"
```

:::

::: tab Number

In case of a number value `['value' => 123]`:

```
123
```

:::

::: tab Null

In case of null value `['value' => null]`:

```
null
```

:::

::: tab List

In case of an array `['value' => ['John']]` value:

```
["John"]
```

:::

::: tab Array In case of an associative array `['value' => ['first' => 'John', 'last' => 'Doe']]` value:

```
{"first":"John","last":"Doe"}
```

::: ::::

#### Embedding JSON data

[](#embedding-json-data)

It can be useful to embed JSON data inside JavaScript statements:

Here is an example of a view template with value `['value' => ['key' => 'value']]`:

```

    var value = @json($value);
    console.log(value.key);

```

The generated view will then look like this:

```

    var value = {"key":"value"};
    console.log(value.key);

```

### Built-in directives

[](#built-in-directives)

The standalone core includes these directive groups by default:

- conditional directives such as `@if`, `@elseif`, `@else`, `@unless`, `@isset`, `@empty`, and `@switch`
- loop directives such as `@foreach`, `@for`, `@while`, `@break`, and `@continue`
- `@json(...)`
- raw PHP via `@php ... @endphp`

Framework-specific helpers such as routing or container access are intentionally out of scope for this package. Add them as custom directives in your application or use a framework integration package.

### Raw PHP

[](#raw-php)

To embed PHP logic in your template, use the classic `` tags or alternative `@php` and `@endphp`:

```
@php
    echo "hello world";
@endphp
```

### Escaping control '@' letter

[](#escaping-control--letter)

Just double 'at' letter like

```
@@ // -> will be rendered as '@'
```

### Custom Directives

[](#custom-directives)

Stempler provides a way to extend its functionality through custom directives. A custom directive is a class that extends the `Stempler\Directive\AbstractDirective` class and implements a render method that accepts a `Stempler\Node\Dynamic\Directive` parameter.

To create a custom directive, follow these steps:

#### Create a directive class

[](#create-a-directive-class)

Create a class that extends `Stempler\Directive\AbstractDirective` and implements the render method with the desired functionality.

```
namespace App\Integration\Stempler;

use Stempler\Directive\AbstractDirective;
use Stempler\Node\Dynamic\Directive;

final class DatetimeDirective extends AbstractDirective
{
    public function renderDateTime(Directive $directive): string
    {
        return '';
    }
}
```

> **Note**It's also possible to implement the `Stempler\Directive\DirectiveRendererInterface` for lower-level access to the rendering process.

#### Register the directive

[](#register-the-directive)

Pass the custom directive to `Stempler::create()`. You can pass either a class name or an instance.

```
use App\Integration\Stempler\DatetimeDirective;
use Stempler\Loader\DirectoryLoader;
use Stempler\Stempler;

$stempler = Stempler::create(
    new DirectoryLoader(__DIR__ . '/views'),
    directives: [DatetimeDirective::class],
);
```

#### Use the directive

[](#use-the-directive)

The custom directive can be used in the template by invoking it with the appropriate syntax.

Here is the template code:

```

    @dateTime

```

And this is the final PHP code generated by the directive:

```

```

By using the custom directive, you can add custom functionality to the template engine and reuse it across different templates.

#### Passing values

[](#passing-values)

You can pass values to a custom directive by using the `body` and `values` properties of the `Directive` object. These properties can be used to access the values passed to the directive. This allows you to pass dynamic values to the directive, making it more flexible and reusable.

Here is an example of using the `body` property:

```
public function renderDateTime(Directive $directive): string
{
    return \sprintf('', $directive->body);
}
```

Example:

:::: tabs

::: tab String

```

    @dateTime('l')

```

This directive will generate the following PHP code:

```
