Extensions
Capabilities
Latch extensions are capable of providing any or all of the following behaviors:
- Loading stylesheets. Latch autoloads
css/style.cssfor each active extension when the file exists. - Overriding core scripts and templates. Most files are loaded through
Latch\File\ext_part(), which checks active extensions before core files. Files inappcontain CMS initialization logic and are not extension override targets. - Event handlers. Extensions can run PHP code for any Latch event and can define custom event names for their own code.
- Custom admin forms that write data to the
latch_extensionstable. - Custom shortcodes from
extensions/my_extension/lib/shortcodes. - Custom post templates, page templates, form templates, datatype handlers, cachers, and other files resolved through
ext_part().
Metadata
Every extension must have a package.json file in the root of the extension directory, for example extensions/my_extension/package.json.
Here is an example with the common supported keys:
{
"name": "Backups",
"description": "Schedule backups of your Latch files and database.",
"author": "Sparknight",
"url": "https://sparknight.io",
"version": "0.0.1",
"icon": "fa-solid fa-hard-drive"
}
A few points to keep in mind:
nameis the friendly value shown in the dashboard. The extension directory is the unique identifier used by the filesystem.- If
iconis provided, the extension can appear as a sidebar link in the Admin Dashboard. versionshould follow Semantic Versioning.
Priority
Extensions are loaded in the order they appear in the active extension list.
For file overrides, the first active extension with a matching file takes precedence. Other matches further down the extension list are ignored.
For events, multiple extensions can hook into the same event. The earlier extension in the active extension list runs first.
Events
Event files live at:
extensions/my_extension/lib/events/event_name.php
The event class must use this namespace and class pattern:
<?php
namespace Latch\Ext\MyExtension\Events;
class EventName
{
public static function event($args)
{
// Your processing here.
}
}
For example, to add content to the bottom of a Latch form, create extensions/my_extension/lib/events/form_after.php:
<?php
namespace Latch\Ext\MyExtension\Events;
class FormAfter
{
public static function event($args)
{
return <<<HTML
<button type="button">My Custom Button</button>
HTML;
}
}
The $args variable is a named array provided by $_SESSION["latch"]->events->trigger().
Initialization Event
The init event is triggered immediately after extension event files are loaded. It is a good place to include extension libraries, run installation routines, or initialize namespaced services.
Example init.php:
<?php
namespace Latch\Ext\MyExtension\Events;
class Init
{
public static function event($args)
{
include_once __DIR__ . "/../my-extension.php";
}
}
If your extension exposes reusable code, put it in a namespaced file outside the event handler, such as extensions/my_extension/lib/my-extension.php:
<?php
namespace Latch\Ext\MyExtension;
function get_log()
{
return \Latch\Util\new_log("ext.my_extension");
}
Cron Event
A cron job is a task that runs automatically at a specific time or interval. Latch relies on a single cron job that fires every minute. It calls lib/hooks/cron.php, which triggers the cron event.
An extension can add scheduled behavior by creating:
extensions/my_extension/lib/events/cron.php
The handler should decide for itself whether work is due. For example, the Backups extension checks configured backup jobs and only runs a job when its schedule has elapsed.
