Events

Latch allows extensions to execute code when named events are triggered. Events can return snippets of output, modify a passthrough array, or replace one passthrough value depending on how the event is triggered.

For more information on extension structure, see extensions.md.

Event Handler Structure

Create event files in your extension's lib/events directory. The filename is the event name:

extensions/my_extension/lib/events/form_after.php

The class name must be the PascalCase form of the event filename, inside this namespace:

Latch\Ext\<ExtensionDirectoryPascalCase>\Events

For an extension directory named my_extension, the form_after handler looks like this:

<?php

namespace Latch\Ext\MyExtension\Events;

class FormAfter
{
    public static function event($args)
    {
        return "<button type=\"button\">My Custom Button</button>";
    }
}

Latch loads handlers for active extensions in extension order. If multiple extensions listen to the same event, the earlier extension in the active extension list runs first.

The event registry is cached, but core versions and active extension manifests form a deployment fingerprint. A changed fingerprint or missing cached handler rebuilds the registry, so versioned extension deployments can add, remove, or rename handlers without a manual cache clear. Run php tests/benchmarks/events_restore.php after changing this restore path.

Return Behavior

Events are triggered in one of three modes:

  • Normal collection: each handler return value is collected into an array.
  • Array passthrough: handlers receive $args and may return an array merged into the running $args value.
  • Named passthrough: handlers may return a replacement for one named $args key.

When using passthrough events, return the full modified $args array unless the event specifically expects a single named value.

Core Events

cron

Triggered by lib/hooks/cron.php, normally once per minute.

Arguments: none by default.

Use this for scheduled extension tasks.

form_before

Triggered before form fields are rendered.

Arguments:

  • form: Form name.
  • form_id: Form parent ID.
  • form_fields: Array of field rows.

Return a modified $args array to add, remove, or alter fields before rendering.

form_after

Triggered after form fields and the submit button are rendered.

Arguments:

  • form: Form name.
  • form_id: Form parent ID.
  • errors: Present on login/register form renders that have validation errors.

Return an HTML string to append to the form.

form_post_validate

Triggered during form submission before Latch writes the post data.

Arguments:

  • form_id: Form parent ID.
  • _post: Submitted POST data.
  • errors: Optional array of validation errors.

Return a modified $args array. To fail validation, add at least one value to $args["errors"].

file_deleted

Triggered immediately after Latch deletes a managed upload. The file itself no longer exists when handlers run.

Arguments:

  • absolute_path: Former absolute filesystem path.
  • relative_path: Path relative to the Latch root.
  • context: Upload context such as admin, form, or profile.
  • Context-specific values such as field_id, field_name, post_id, or user_id may also be present.

Use this event to remove derivatives or external indexes associated with a managed file. Handlers must not assume the deleted source can still be read.

file_replaced

Triggered after Latch successfully replaces a managed upload at the same path and before file_uploaded is triggered for the replacement.

Arguments match file_uploaded and describe the new file at the retained path. Use this event to remove stale derivatives or indexes before rebuilding them from the subsequent file_uploaded event.

file_uploaded

Triggered after Latch has successfully moved a managed upload into its final location.

Arguments:

  • absolute_path: Absolute filesystem path.
  • relative_path: Path relative to the Latch root.
  • mime_type: MIME type detected from file contents.
  • size: File size in bytes.
  • width and height: Image dimensions, or zero for non-image files.
  • context: Upload context such as admin, form, profile, or suneditor.
  • Context-specific values such as field_id, field_name, field_type, form_name, post_id, user_id, or original_name may also be present.

Use this event for asynchronous or queued media work. Avoid performing expensive conversions inside the upload request.

image_variants

Triggered when the shared Media renderer looks for alternate files for an image.

Arguments:

  • image: Description containing the source URL, local paths when available, MIME type, dimensions, and caller context.
  • context: Renderer-specific context such as post-content or featured-media.
  • variants: Alternate sources accumulated from earlier handlers.

Return the full $args array with each variant represented by type, srcset, and an optional sizes value. Preserve existing variants and order additions by preference. Providers should return only distinct public URLs; the renderer escapes attributes and retains the original image as the fallback.

media_forms

Triggered when Latch resolves which post forms participate in the shared Media Library and SunEditor image gallery.

Arguments:

  • forms: Form names, initially containing the stock Media form.

Return the full $args array. Append form names to retain the stock library, or replace forms to substitute another media housing form. Participating forms should use database-action value create-post and tag their canonical upload field is_media.

extensions_update

Triggered while the Extensions form is being saved, after extension rows are updated but before the active-extension cache and event registry are reloaded.

Arguments:

  • active_extensions: Extension directory identifiers that will be active.
  • previous_active_extensions: Extension directory identifiers that were active before the submission.

This event is delivered through the previous event registry so an extension being disabled can remove runtime configuration that would otherwise remain behind. A newly enabled extension should perform setup from its init handler after the registry reloads.

html_attributes

Triggered before the <html> element is printed.

Arguments are an associative array of HTML attributes.

Return the modified attribute array.

init

Triggered immediately after extension event files are loaded.

Arguments: none by default.

Use this to include extension libraries, run one-time installation routines, or initialize namespaced extension services.

login_validate_before

Triggered before built-in login or registration validation.

Arguments:

  • _POST: Submitted POST data.
  • errors: Current errors array.
  • form_name: The active form name.

Return a modified $args array.

login_validate_after

Triggered after built-in login validation locates a user.

Arguments:

  • _POST: Submitted POST data.
  • errors: Current errors array.
  • form_name: The active form name.
  • id: User ID.

Return a modified $args array.

meta_tags

Triggered before meta tags are printed in the page <head>.

Arguments include page context plus meta_tags, an associative array where each key is the tag name or property and each value is the content.

Return the modified meta_tags array.

page_load

Triggered during early page loading. This is used by extensions that need request-level checks before normal page output.

Return behavior depends on the caller.

post_metadata_validate

Triggered while submitted post metadata is being validated.

Arguments:

  • field_id
  • form_id
  • form_name
  • setting_name
  • setting_val
  • valid

Return a modified $args array.

register_init

Triggered before registration form handling completes its setup.

Return a modified registration argument array.

register

Triggered after a user registration is created.

Arguments:

  • param_username
  • param_password
  • email_safe
  • token

reset_password

Triggered when a password reset token is issued.

Arguments:

  • id: User ID.
  • token: Reset token.
  • email: User email.
  • name: User display name.

save_post

Triggered after a form submission is saved.

Arguments:

  • post_id: Post ID for Create post forms. Non-post database actions may leave this as -1.
  • form_id: Form parent ID.
  • metadata_json: Saved metadata JSON string.
  • type: Form name.

title_tag

Triggered before the document title is printed.

Return the title string or a modified argument value, depending on the caller.