Besides classic echo constructions, the Stempler supports many Blade-like directives to control the business logic of your templates.
Unlike Blade or Twig, the Stempler directives only responsible for business logic management.
See Components and Props and Inheritance to check how to extend your templates and implement virtual components.
Just double 'at' letter like
@@ // -> will be rendered as '@'
To loop over a list of template variables, use the following directives.
Note
Directive declaration is similar to native PHP syntax.
To embed PHP logic in your template use classic <?php and ?> tags or alternative @php and @endphp:
@php
echo "hello world";
@endphp
Use directive @for and @endfor to render the loop:
@for($i=0; $i<100; $i++)
hello
@endfor
Use directive @while and @endwhile to render while loop:
@php $i = 0; @endphp
@while($i < 10)
hello world
@php $i++; @endphp
@endwhile
Use @break and @continue directives to interrupt your loops:
@php $i = 0; @endphp
@while(true)
hello world
@if($i++>10)
@break
@endif
@endwhile
Note
@break(2)is equivalent tobreak 2. Read more aboutifdirectives below.
Stempler provides some conditional directives which transcribed into native PHP code.
The examples are given with the following variables:
return $this->views->render('welcome', [
'value' => 123
]);
To create conditional statement use @if and @endif directives:
@if($value === 123)
{{ "hello world" }}
@endif
To create else condition use @else directive:
@if($value !== 123)
{{ "value is not 123" }}
@else
{{ "value is 123" }}
@endif
To create conditional else use elseif:
@if($value === 124)
{{ "value is 124" }}
@elseif($value === 123)
{{ "value is 123" }}
@else
{{ "another value" }}
@endif
Use @unless directive to declare negative condition:
@unless($value === 124)
{{ "value is not 124" }}
@endunless
Note
You can use@elseand@elseifwith a@unlessdirective.
Use @empty and @isset conditions and @endempty, @endisset accordingly:
@empty($value)
value is empty
@endempty
@isset($value)
value is set
@endisset
Note
You can combine this condition with@else,@elseif.
To create more complex conditions use @swich, @case, @break and @endswitch statements.
@switch($value)
@case(123) 123 @break
@case(124) 124 @break
@case(125) 125 @break
@endswitch
To render JSON on a page use @json directive:
@json($value)
You can embed json inside JavaScript statements:
return $this->views->render('welcome', [
'value' => ['key' => 'value']
]);
In your template:
<script type="text/javascript">
var value = @json($value);
console.log(value.key);
</script>
Alternatively you can use contextual echo via {{ }} statement:
<script type="text/javascript">
var value = {{ $value }};
console.log(value.key);
</script>
In both cases the generated view will look like:
<script type="text/javascript">
var value = {"key":"value"};
console.log(value.key);
</script>
Spiral provides a number of framework-specific directives.
To invoke container dependency into template use @inject($variable, "class") directive:
@inject($app, App\App::class)
{{ get_class($app) }}
To create route use directive @route:
<a href="@route('home:index')">click me</a>
You can use controller:action pattern for targets handled by default route or route name:
$router->addRoute(
'html',
new Route('/<action>.html', new Controller(HomeController::class))
);
Pass arguments using second parameter:
<a href="@route('html', ['action' => 'index'])">click me</a>
Parameters will be automatically slugified into route url. Parameters not found in route pattern will be passed as query parameters:
<a href="@route('html', ['action' => 'index', 'id' => 10])">click me</a>
The result /index.html?id=10.
Read more about routing and named routes here.
You can declare and register custom directives. To create custom directive create a class which extends
Spiral\Stempler\Directive\AbstractDirective. Directive methods must be prefixed with render and accept
Spiral\Stempler\Node\Dynamic\Directive as parameter:
namespace App\Directive;
use Spiral\Stempler\Directive\AbstractDirective;
use Spiral\Stempler\Node\Dynamic\Directive;
class CustomDirective extends AbstractDirective
{
public function renderCustom(Directive $directive): string
{
return '<?php echo "custom" ?>';
}
}
Note
You can also implementSpiral\Stempler\Directive\DirectiveRendererInterfaceto gain lower-level access to functionality.
Register your directive in one of your bootloaders via StemplerBootloader->addDirective method:
namespace App\Bootloader;
use App\Directive\CustomDirective;
use Spiral\Boot\Bootloader\Bootloader;
use Spiral\Stempler\Bootloader\StemplerBootloader;
class CustomDirectiveBootloader extends Bootloader
{
protected const DEPENDENCIES = [
StemplerBootloader::class
];
public function boot(StemplerBootloader $stempler): void
{
$stempler->addDirective(CustomDirective::class);
}
}
Invoke the directive in your template:
@custom
To access values passed to directive use body and values properties of Directive retrospectively:
class CustomDirective extends AbstractDirective
{
public function renderCustom(Directive $directive): string
{
return $directive->body;
}
}
Example:
@custom(1, "hello world")
Output:
"hello world"
Note
Make sure to check ifbodynot NULL.
To access specific directive values separated by ,:
class CustomDirective extends AbstractDirective
{
public function renderCustom(Directive $directive): string
{
return \sprintf(
'<?php echo (%s > %s) ? "first value larger or equals": "second value larger" ?>',
$directive->values[0],
$directive->values[1]
);
}
}
Example:
@custom(1, 2)
Directive values will be supplied in their original PHP form, you must escape values manually. The following PHP will be generated for the Directive above:
<?php echo (3 > 2) ? "first value larger or equals": "second value larger" ?>
Note
You can pass$variablesinto directives as well.
To capture where directive is invoked from use $directive->getContext()->getPath():
public function renderCustom(Directive $directive): string
{
return '<?php echo "invoked from ' . var_export($directive->getContext()->getPath(), true) . '" ?>';
}
Note
The output:invoked from 'welcome'.