{can}

Renders its content when the user may do something a gate decides, and its else half when not.

Users and access Tag pairs

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.

Templateexamples/can/1-guest-gate.pad
<ul>
{posts}
  <li>{can 'read-post', $posts}<a href="#">{$title}</a>{else}{$title} - not published yet{/can}</li>
{/posts}
</ul>
PHPexamples/can/1-guest-gate.php
<?php

  $posts = [
    [ 'title' => 'Release notes',  'published' => TRUE,  'author' => 1 ],
    [ 'title' => 'Draft: roadmap', 'published' => FALSE, 'author' => 1 ] ];

?>
Resultopen alone

A gate for users only

edit-post takes array $user: a guest is never let through and the gate is not even asked.

Templateexamples/can/2-user-gate.pad
<h3>{$post.title}</h3>
{can 'edit-post', $post}
  <a href="#edit">Edit</a>
{else}
  <p>Read only.</p>
{/can}
PHPexamples/can/2-user-gate.php
<?php

  $post = [ 'title' => 'Release notes', 'published' => TRUE, 'author' => 1 ];

?>
Resultopen alone

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.

Templateexamples/can/3-gates.src
{# _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&amp;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.