Revision: Wed, 06 Dec 2023 18:31:49 GMT
v3.4 – outdated
This version of the documentation is outdated. Consider upgrading your project to Spiral Framework 3.10
Edit this page


Keeper comes with several stempler directives, views and templates


Auth directive

Provides a permission check with context, uses GuardInterface call under the hood.

@auth('permision', ['some' => 'context'])

Logout directive

Wraps the given logout url params and adds the current auth token:

<a href="@logout(admin['auth:logout'])">[[Log out]]</a>

For now this directive accepts the full route name.

Route directive

There's a convenient directive for generating uri in the given namespace:

<a href="@keeper('admin', 'createUser')">[[+ User]]</a>

Views and Templates

The next views and templates are worth mentioning:

  • keeper:login view contains sign-up form, can be extended for some customization or built from scratch (don't forget to register the view in the keeper config):
// app/config/path/to/keeper/config.php

return [
    'loginView' => 'default:path/to/login/view'
  • keeper:layout/page and keeper:layout:tabs are 2 main layouts, example below:

< title="[[Title]]"/>
<use:bundle path="keeper:bundle"/>

    [[Some page content.]]

<extends:keeper:layout.tabs title="[[Title]]"/>
<use:bundle path="keeper:bundle"/>

<ui:tab id="information" icon="info" title="[[Information]]" active="true">
    [[Information tab content.]]
<ui:tab id="data" icon="cog" title="[[Data]]">
    [[Data tab content.]]
  • grid templates are powerful html elements for tables with filters:
    <ui:grid url="@action('users.list')">
        <grid:filter search="true" immediate="300" buttons="true">
            <form:select name="status" label="[[Status]]" placeholder="[[Select Status]]"
                         values="{{ ['active' => '[[Active]]', 'disabled' => '[[Disabled]]'] }}"/>

        <grid:cell.text name="first_name" label="[[First Name]]" sort="true" body="{firstName}" sort-dir="asc"
        <grid:cell.text name="last_name" label="[[Last Name]]" sort="true" body="{lastName}"/>
        < name="email" label="[[Email]]" href="mailto:{email}" body="{email}" sort="true"
        <grid:cell.render name="status" label="[[Status]]" renderer="status"/>

        < label="[[Edit]]" icon="edit" url="@action('users.edit', ['user' => '{id}'])"
<stack:push name="scripts" unique-id="datagrid-account-renderer">
    <script type="text/javascript">'status', function () {
            return function (status, item) {
                let map = {
                    "active": 'badge-primary',
                    "disabled": 'badge-warning',
                let badge = (status.toLowerCase() in map) ? map[status.toLowerCase()] : 'badge-secondary';
                return '<span class="badge ' + badge + ' mr-1">' + status.toUpperCase() + '</span>';

Some explanations:

sort="true" allows sorting the grid by that column. Additional sort-dir="asc|desc" and sort-default="true" enable the default sorting with order. name="first_name" is used as a name of the sort key in the query ([first_name]=asc).

condition="" allows showing/hiding the row if needed. body="{firstName}" is the name of the row column.

<grid:cell.render /> with renderer attribute allows using a custom render template. The current item (grid row) and cell value are available inside.

Grid example below:

  "status": 200,
  "data": [
      "firstName": "John",
      "lastName": "Smith",
      "email": "",
      "showEmail": true,
      "status": "active"