{can}
Renders its content when the user may do something a gate decides, and its else half when not.
Syntax
{can 'ability'} ... {/can}
{can 'ability', $value} ... {else} ... {/can}
{rows}{can 'ability', $rows} ... {/can}{/rows}
Parameters
-
ability -
The name of a gate defined with
padGate ( 'edit-post', fn ( $user, $post ) => ... )in a_lib/file. -
values - Optional, any number: what the gate is given after the user - an expression each, an array of the page whole, and the name of an enclosing loop for the row of its occurrence.
Description
{can 'edit-post', $post} asks a gate whether the user logged in may do something, and renders its content when the answer is yes; the part after its own {else}, or the @else@ half, renders when it is no. The gates are functions the application defines once, in a file of its _lib/:
padGate ( 'edit-post', fn ( array $user, array $post ) => $user ['id'] === $post ['author'] );
The first item is the ability, the others are what the gate is given after the user: an expression each, the name of an array of the page as that array - and the name of an enclosing loop as the row of its current occurrence, so {posts}{can 'edit-post', $posts} asks about one post, not the list.
padGateBefore ( fn ( $user, $ability ) => ... ) hooks are asked first: TRUE or FALSE decides, NULL leaves it to the gate - an admin who may do anything. A guest reaches only a gate (or hook) whose user parameter takes NULL - ?array $user or $user = NULL; any other gate is not even asked and answers no. An ability nobody defined is FALSE and, under the strict check, an error, so a misspelled name is reported instead of silently hiding a button. {cannot} turns the answer round; padCan, padCannot and padAuthorize (403) ask from PHP.
The gates of the examples here are in this application's _lib/canGates.php: read-post takes a guest, edit-post does not.
Examples
A gate that takes a guest
read-post takes ?array $user, so a guest is asked too - inside {posts}, $posts is the row of the occurrence.
<ul>
{posts}
<li>{can 'read-post', $posts}<a href="#">{$title}</a>{else}{$title} - not published yet{/can}</li>
{/posts}
</ul>
<?php
$posts = [
[ 'title' => 'Release notes', 'published' => TRUE, 'author' => 1 ],
[ 'title' => 'Draft: roadmap', 'published' => FALSE, 'author' => 1 ] ];
?>
- Release notes
- Draft: roadmap - not published yet
A gate for users only
edit-post takes array $user: a guest is never let through and the gate is not even asked.
<h3>{$post.title}</h3>
{can 'edit-post', $post}
<a href="#edit">Edit</a>
{else}
<p>Read only.</p>
{/can}
<?php
$post = [ 'title' => 'Release notes', 'published' => TRUE, 'author' => 1 ];
?>
Release notes
Read only.
Defining the gates
The gates live in a file of _lib/; padGateBefore decides before every gate - here an admin may do anything.
{# _lib/gates.php:
padGate ( 'edit-post', fn ( array $user, array $post ) => $user ['id'] === $post ['author'] );
padGateBefore ( fn ( array $user, string $ability ) => $user ['role'] == 'admin' ? TRUE : NULL );
#}
{posts}
<p>{$title} {can 'edit-post', $posts}<a href="?edit&id={$id}">Edit</a>{/can}</p>
{/posts}
See also
- {cannot} Renders its content when the user may not do something a gate decides - can turned round.
- {auth} Renders its content when a user is logged in, with the user's row as its data, and its else half for a guest.
- {guest} Renders its content when nobody is logged in, and its else half for a user.
- {feature} Renders its content while a feature flag is on for this visitor, and its else half while it is off.