Skip to content

API Pages

Dory Azar edited this page Nov 15, 2026 · 2 revisions

Controllers and views

Caligrafy Quill 2.26.0. Generated from the source by php qa/build-api-reference.php; the guides explain how to use these classes, this reference says exactly what each public method takes and returns. Back to the API reference.

Rendering pages: the controller base class, the page controller of Route::page, views and design styles.

Class What it is
Caligrafy\Controller Parent Class that defines the properties and methods of a controller
Caligrafy\PageController Route::page('/books/{id}', 'Books/show', ['data' => ['book' => 'get_book']]) renders a view through this controller: 1. access: 'signedIn' => true sends visitors to /login; 'level' => N also sends people below level N to
Caligrafy\View Class View is the view renderer of the application
Caligrafy\Designs A style is a DESIGN.md and the override stylesheet written from it, public/css/designs/<name>.css.
Caligrafy\HttpCache A capability declared with cache (#[Capability(..., readOnly: true, public: true, cache: 30)]) answered over REST, or a page declared with Route::page(..., ['cache' => 30]), is sent with Cache-Control: public, ...

class Caligrafy\Controller

Parent Class that defines the properties and methods of a controller

Its 17 public methods have a page of their own: Caligrafy\Controller.

class Caligrafy\PageController

namespace Caligrafy;

class PageController extends Controller

Source: framework/core/PageController.php:25

Class PageController Route::page('/books/{id}', 'Books/show', ['data' => ['book' => 'get_book']]) renders a view through this controller:

  1. access: 'signedIn' => true sends visitors to /login; 'level' => N also sends people below level N to /notAuthorized (Auth::guard on Context::$levelAttribute)
  2. data: each 'data' entry calls a read-only capability as the person who opens the page ($this->call(): the same rules as REST and MCP), with the query string and the route variables as inputs (the route variables win), or with the inputs it lists (['book' => ['get_book', ['id' => 3]]]). A refusal becomes the page's answer: a visitor is sent to sign in; otherwise 403 (error 1006) or 404 (error 1005), or the 'notFound' view (route variables, 'with', 'message', who opens it) with a 404 status
  3. the view gets the route variables, 'with' values, the data, 'authorized' and 'user' (id, username, level) - never the query string Pages never read models: capabilities do, so a page, REST and AI agents follow the same rules.

Constants

  • RESERVED = array('authorized', 'user')

Methods

->__construct()

public function __construct()

Nothing to connect for a page without data: the controller is set up when a capability is called

Source: framework/core/PageController.php:32

->render()

public function render($view, array $options = array())

Parameters

  • $view string: the view, as for view(): 'Books/show'
  • $options array, default array(): 'signedIn' (bool), 'level' (int), 'data' (array name => read-only capability or [capability, inputs]), 'with' (array of fixed view data), 'notFound' (a view for 404s); 2.20.0: 'visitorsOnly' (a path: signed-in people go there), 'comeBack' (bool: visitors come back here after signing in), 'query' (names of the query string the view gets, as strings, '' when absent); 2.26.0: 'cache' (seconds a visitor's copy may be shared, see HttpCache)

Source: framework/core/PageController.php:44

PageController::admit()

public static function admit(array $options, $label)

The access options of Route::page and Route::action: 'signedIn', 'level', 'comeBack', 'visitorsOnly'

Parameters

  • $options array
  • $label

Returns bool: true when the person was sent elsewhere

Source: framework/core/PageController.php:107

PageController::identity()

public static function identity()

Who opens the page: 'authorized' and 'user' (id, username, level), for every view the page controller renders

Source: framework/core/PageController.php:132

PageController::signInAddress()

public static function signInAddress()

The sign-in page, with this page and its query string to come back to (2.20.0, 'comeBack'): /login?return=/books/3%3Fpage%3D2. Route::auth goes back there after signing in.

Source: framework/core/PageController.php:145

PageController::routeVariables()

public static function routeVariables()

The variables of the route pattern only (/books/{id} -> id), not the query string

Source: framework/core/PageController.php:156

class Caligrafy\View

namespace Caligrafy;

class View extends \stdClass

Source: framework/core/View.php:21

Class View is the view renderer of the application

Public properties

  • public $viewName
  • public $viewData

Methods

->__construct()

public function __construct($viewName, $viewData = array())

No doc comment.

Parameters

  • $viewName
  • $viewData, default array()

Source: framework/core/View.php:28

View::display()

public static function display($path, array $data = array())

Prints a Pug file (2.19.0). A view already compiled and up to date runs through Phug's Optimizer, which includes the compiled PHP without building Phug's compiler (3 classes instead of about 100); a view to compile, or a project that customized Phug at run time (its renderer already built), goes through Phug's renderer as before.

Parameters

  • $path
  • $data array, default array()

Source: framework/core/View.php:49

View::debug()

public static function debug()

Phug's debug mode (line numbers of the Pug file in errors) only with APP_DEBUG=true: it makes every page about three times slower (2.19.0)

Source: framework/core/View.php:80

View::cache()

public static function cache()

Compiled templates are kept between requests: a view is compiled to PHP once, then again only when it or a file it includes or extends changes. On by default; VIEW_CACHE=false compiles every view on every request. A project that sets Phug's cache_dir itself keeps its own. Returns the folder used, or null (no cache). Also sets Phug's debug mode from APP_DEBUG.

Source: framework/core/View.php:91

View::cacheFolder()

public static function cacheFolder()

A folder of the system's temporary directory for this project and this system user only (compiled templates are PHP that runs): created private (0700), refused when someone else owns it or it cannot be written. Views compiled in debug mode are kept apart (the cache does not know the options a view was compiled with).

Source: framework/core/View.php:109

class Caligrafy\Designs

namespace Caligrafy;

class Designs

Source: framework/core/Designs.php:21

Class Designs A style is a DESIGN.md and the override stylesheet written from it, public/css/designs/<name>.css. DESIGN.md files are looked up in this order, the first one wins on a name clash:

application/design/<name>/                the project's own styles
framework/design/local/<name>/            styles added to Caligrafy itself
framework/design/vendor/<vendor>/<name>/  collections copied from elsewhere (awesome-design-md...), by vendor name

The layout loads that stylesheet after the Caligrafy stylesheets when DESIGN_STYLE names it; an empty DESIGN_STYLE, an unknown name or a style without its stylesheet keeps Caligrafy's own look.

Constants

  • VENDOR = 'framework/design/vendor'
  • LOCAL = 'framework/design/local'
  • APPLICATION = 'application/design'
  • STYLESHEETS = 'public/css/designs'

Methods

Designs::name()

public static function name($value)

The style name of a value when it is a valid one (lowercase letters, digits, dot, dash, underscore), else ''

Parameters

  • $value

Source: framework/core/Designs.php:31

Designs::setting()

public static function setting()

DESIGN_STYLE as loaded from .env (raw, trimmed): '' means Caligrafy's own look

Source: framework/core/Designs.php:40

Designs::sources()

public static function sources($root = '.')

The folders that hold styles, first one wins: label => folder relative to the root

Parameters

  • $root, default '.'

Source: framework/core/Designs.php:49

Designs::all()

public static function all($name, $root = '.')

Every DESIGN.md of a name, in lookup order (the first one is used): label => path

Parameters

  • $name
  • $root, default '.'

Source: framework/core/Designs.php:63

Designs::available()

public static function available($root = '.')

The styles available, name => path of the DESIGN.md that is used (application, then local, then vendors)

Parameters

  • $root, default '.'

Source: framework/core/Designs.php:78

Designs::source()

public static function source($file, $root = '.')

Where a DESIGN.md comes from: application, local or vendor/<vendor>

Parameters

  • $file
  • $root, default '.'

Source: framework/core/Designs.php:94

Designs::find()

public static function find($name, $root = '.')

The DESIGN.md of a style, null when there is none

Parameters

  • $name
  • $root, default '.'

Source: framework/core/Designs.php:105

Designs::stylesheet()

public static function stylesheet($name, $root = '.')

Path of the override stylesheet of a style (it may not exist yet)

Parameters

  • $name
  • $root, default '.'

Source: framework/core/Designs.php:114

Designs::stylesheetUrl()

public static function stylesheetUrl($public, $root = '.')

URL of the stylesheet of the selected style, versioned by its modification time, or '' for Caligrafy's own look

Parameters

  • $public
  • $root, default '.'

Source: framework/core/Designs.php:122

Designs::describe()

public static function describe($file, $max = 110)

One line describing a style: the description of its front matter, else its first paragraph

Parameters

  • $file
  • $max, default 110

Source: framework/core/Designs.php:133

Designs::status()

public static function status($root = '.')

The state of the selected style, for doctor and design status

Parameters

  • $root, default '.'

Returns array: [status OK|WARN, message, fix]

Source: framework/core/Designs.php:155

Designs::cli()

public static function cli(array $args, $root = '.', $envFile = '.env')

php caligrafer.php design list | show <name> | use <name> | off | status

Parameters

  • $args array
  • $root, default '.'
  • $envFile, default '.env'

Returns int: exit code

Source: framework/core/Designs.php:183

class Caligrafy\HttpCache

namespace Caligrafy;

class HttpCache

Source: framework/core/HttpCache.php:23

Class HttpCache A capability declared with cache (#[Capability(..., readOnly: true, public: true, cache: 30)]) answered over REST, or a page declared with Route::page(..., ['cache' => 30]), is sent with Cache-Control: public, max-age=30 when the request is a GET or HEAD with no session cookie and no Authorization header: the production image's Apache cache (docker/production/cache.conf), a CDN or a proxy then answer the next visitors from memory, without PHP.

Never kept: an answer to a signed-in person or a token (it is not marked), an answer that sets a cookie (a session started while answering: a form's CSRF token) and any answer other than 200: guard() turns them into Cache-Control: private, no-store just before the headers are sent. Vary: Cookie, Authorization keeps the copy for visitors without them.

Constants

  • MAX = 86400

Methods

HttpCache::publicFor()

public static function publicFor($seconds)

Marks the current answer public for $seconds when this request may share it

Parameters

  • $seconds

Returns bool: whether it was marked

Source: framework/core/HttpCache.php:33

HttpCache::shareable()

public static function shareable()

Whether this request may receive a shared answer: GET or HEAD, no session cookie, no Authorization header

Source: framework/core/HttpCache.php:52

HttpCache::guard()

public static function guard()

Right before the headers go out: an answer that sets a cookie or is not a 200 is never kept

Source: framework/core/HttpCache.php:67

HttpCache::reset()

public static function reset()

For tests: forget that the header callback is registered

Source: framework/core/HttpCache.php:86

Caligrafy: Describe it. Approve it. Ship it. Your idea turned into a complete app: every feature built once, for web pages, Vue apps, a REST API and AI agents, and online.

Start here

Why Caligrafy: the benefits, the measurements, and what it is not yet

  1. Quickstart with Claude: describe it, approve it, ship it

    or the Quickstart: the same three steps by hand, in 5 minutes

  2. How Caligrafy works: the ideas in 5 minutes
  3. Your first capability: build a feature, page included

Capabilities

Experiences

Data and people

  1. Models
  2. Relationships
  3. Queries: filters, paging, related rows
  4. Sign-in, users and tokens

Built-in features

Put it online

Build with AI

Reference

Clone this wiki locally