RaisFastRaisFast
Plugins

Hooks

17+ hooks — filter, action, and render override types. Priority ordering, content type filtering, and dispatch flow.

Hooks are the event system for plugins. Register a hook in the manifest, implement the function in your entry file, and RaisFast calls it at the right time.

Hook Types

TypeBehavior
FilterChain transform. Receives input, returns modified data. Result passes to the next plugin.
ActionFire-and-forget. Return value ignored. All plugins execute sequentially.
Render OverrideFirst-wins. First plugin returning data wins; remaining plugins skipped.

All Hooks

Content Lifecycle

HookTypeWhen
on-content-creatingFilterBefore content is created (modify data)
on-content-createdActionAfter content is created
on-content-updatingFilterBefore content is updated (modify data)
on-content-updatedActionAfter content is updated
on-content-deletedActionAfter content is deleted
on-content-viewedActionWhen a single record is fetched by ID

Post Lifecycle

HookTypeWhen
on-post-creatingFilterBefore a post is created
on-post-createdActionAfter a post is created
on-post-updatingFilterBefore a post is updated
on-post-updatedActionAfter a post is updated
on-post-deletedActionAfter a post is deleted

Comment Lifecycle

HookTypeWhen
on-comment-creatingFilterBefore a comment is created
on-comment-createdActionAfter a comment is created
on-comment-updatedActionAfter a comment is updated
on-comment-deletedActionAfter a comment is deleted

Product & Order

HookTypeWhen
on-product-createdActionAfter a product is created
on-product-updatedActionAfter a product is updated
on-product-deletedActionAfter a product is deleted
on-order-createdActionAfter an order is created
on-order-paidActionAfter an order is paid
on-order-shippedActionAfter an order is shipped
on-order-completedActionAfter an order is completed
on-order-cancelledActionAfter an order is cancelled

Payment & Wallet

HookTypeWhen
on-payment-order-createdActionAfter a payment order is created
on-payment-paidActionAfter payment succeeds
on-payment-refundedActionAfter payment is refunded
on-wallet-creditedActionAfter wallet is credited
on-wallet-debitedActionAfter wallet is debited

Tag & Category & Page & Media

HookTypeWhen
on-tag-createdActionAfter a tag is created
on-tag-updatedActionAfter a tag is updated
on-tag-deletedActionAfter a tag is deleted
on-category-createdActionAfter a category is created
on-category-updatedActionAfter a category is updated
on-category-deletedActionAfter a category is deleted
on-page-createdActionAfter a page is created
on-page-updatedActionAfter a page is updated
on-page-deletedActionAfter a page is deleted
on-media-uploadedActionAfter a file is uploaded
on-media-deletedActionAfter a file is deleted

User & Auth

HookTypeWhen
on-user-registeredActionAfter a user registers
on-loginActionAfter a user logs in
on-password-reset-requestedActionWhen password reset is requested
on-email-verification-requestedActionWhen email verification is requested

Utility

HookTypeWhen
render-markdownRender OverrideOverride markdown rendering
filter-htmlRender OverrideFilter HTML output
on-cron-tickActionCron job fires

Custom Events

Plugins can emit custom events via emitEvent(). Other plugins can listen by registering a hook matching the event type:

[hooks.order-created]
priority = 10
export function order_created(input) {
  const data = JSON.parse(input);
  logInfo("order created: " + data.id);
}

Priority Ordering

Hooks execute in ascending priority order (lower number = runs first):

[hooks.on-content-creating]
priority = 10   # runs first

[hooks.on-content-creating]
priority = 50   # runs second

[hooks.on-content-creating]
priority = 100  # runs last (default)

Default priority is 100 if not specified.

For filter hooks, each plugin receives the output of the previous plugin in the chain. For action hooks, all plugins run independently.

Content Type Filtering

Limit a hook to specific content types:

[hooks.on-content-creating]
priority = 10
content_types = ["product", "course"]

Or use the shorthand match:

[hooks.on-content-creating]
priority = 10
match = "product"

When content_types is empty (default), the hook fires for all content types.

Filter Hooks

Filter hooks can modify data before it is saved. Return the modified data:

export function on_content_creating(input) {
  const data = JSON.parse(input);
  if (!data.slug) {
    data.slug = data.title.toLowerCase().replace(/ /g, '-');
  }
  return JSON.stringify(data);
}
Plugin.on_content_creating = function(input)
  local data = sdk.extractJson(input, "body")
  if not data.slug then
    data.slug = string.lower(data.title):gsub(" ", "-")
  end
  return sdk.ok(data)
end
fn on_content_creating(input) {
  if input.slug == "" {
    input.slug = to_lower(input.title);
    input.slug = replace(input.slug, " ", "-");
  }
  input
}

Action Hooks

Action hooks are for side effects — logging, notifications, cache invalidation. Return value is ignored:

export function on_content_created(input) {
  const data = JSON.parse(input);
  logInfo("created: " + data.id);
  eventEmit("content.created", JSON.stringify({ id: data.id }));
}
Plugin.on_content_created = function(input)
  local data = sdk.extractJson(input, "body")
  sdk.logInfo("created: " .. tostring(data.id))
  sdk.eventEmit("content.created", sdk.jsonEncode({ id = data.id }))
end
fn on_content_created(input) {
  log("info", "created: " + input.id);
  emit_event("content.created", to_json(input));
}

Render Override Hooks

Render overrides use a first-wins strategy. The first plugin to return a non-null value wins, and the remaining plugins are skipped:

[hooks.render-markdown]
priority = 10
export function render_markdown(input) {
  const data = JSON.parse(input);
  return customMarkdownRenderer(data.content);
}

Error Recovery

  • After 5 consecutive errors, the plugin is auto-disabled
  • Error count resets to 0 on a successful invocation
  • You can re-enable via Admin API: POST /api/v1/admin/plugins/{id}/enable
  • Uncommitted transactions are automatically rolled back on timeout or crash

On this page