# Libraries

Business logic and data preparation in PHP, called as shortcodes.

A library is a PHP file in `ext/lib/` that holds business logic or data preparation. It is called from a template as a shortcode, so templates stay logic-free and the logic stays in one testable place.

## Write a library

The file name is the shortcode name. The function is that name with dashes turned into underscores, followed by `_sc`:

```php
<?php
// ext/lib/prepare-projects.php

function prepare_projects_sc($params)
{
    $projects = get_variable('data.projects') ?: [];
    $year = (int)date('Y');
    $recent = array_filter($projects, fn($project) => (int)$project['year'] >= $year - 2);
    set_variable('data.recent_projects', $recent);
}
```

```html
[#data projects filter=published:1#]
[#prepare-projects#]
[#repeat data.recent_projects tpl=card-project#]
```

The library reads variables, computes what the page needs and writes the result back as variables. The template then prints it.

A library can also return a value, which the shortcode prints. That suits small classifications:

```php
function project_status_sc($params)
{
    $project = get_variable('project');
    return empty($project['published']) ? 'draft' : 'live';
}
```

```html
[#badge-[#project-status#]#]
```

Parameters given in the template arrive in `$params`: `[#price amount=12.5 currency=EUR#]` gives `$params['amount']` and `$params['currency']`, and `get_param_value($params, 'currency', 'EUR')` reads one with a default. A value without a name, as in `[#price 12.5#]`, is the first item, `current($params)`.

## Markup stays in templates

A library prepares data; it does not build HTML. When a library needs to render a template, it calls `run_buffered()` with the template's file path. Keeping markup out of PHP means a designer can change any piece of the interface without touching logic, and logic can be tested without markup.

## The PHP toolbox

| Function | Does |
|---|---|
| `get_variable('data.projects')` | Reads a template variable by its dot path |
| `set_variable('name', $value)` | Writes a template variable |
| `set_variable_dot('project', $record)` | Writes a record so its fields are `project.title`, `project.year` |
| `load_library('data')` | Loads another library, for example the data layer |
| `data_read($resource, $uuid)` | Reads one record |
| `data_query($resource, [...])` | Reads a filtered, sorted page of records with the total |
| `data_create()`, `data_update()`, `data_delete()` | Writes records, with validation, indexes, history and events |
| `env('KEY')` | Reads a setting from `.env` |

The full list is in [PHP extension points](/en/docs/reference/php/).

## Libraries for one template

A library that only serves one template can sit next to it as `<name>.inc`. It is found from that template and its folder only, and stays out of the shared namespace.

## Read next

- [Templates](/en/docs/concepts/templates/) for the presentation side.
- [Modules](/en/docs/concepts/modules/) to package libraries with routes and data.
