Plugin Structure and Metadata
Every plugin is a pair of files in its own directory: a compiled WASM component
and a TOML manifest that tells Accent CMS what the plugin can do. This page
covers the directory layout and every section of the plugin.toml file.
Plugin Directory Structure
Plugins live in site/plugins/, with each plugin in its own subdirectory:
site/
plugins/
syntax-highlight/
plugin.toml # Metadata (required)
plugin.wasm # Compiled WASM module (required)
contact-form/
plugin.toml
plugin.wasm
search/
plugin.toml
plugin.wasm
Each plugin directory must contain both files:
plugin.toml- Declares the plugin’s name, version, and capabilitiesplugin.wasm- The compiled WebAssembly component built with a Component-Model toolchain (cargo-componentorjco)
If either file is missing, the plugin is skipped with a warning. Invalid plugins do not prevent the server from starting.
Plugin Metadata (plugin.toml)
The plugin.toml file declares what a plugin can do. Here is a complete example:
[plugin]
name = "syntax-highlight"
version = "0.1.0"
api_version = "0.1.0"
description = "Syntax highlighting for code blocks"
[hooks]
on_render = true # Called after markdown-to-HTML rendering
on_page_load = false # Called before markdown processing
on_media_discover = false # Called during content scanning for media files
on_media_process = false # Called after image processing
[filters]
# filter_name = "exported_function_name"
highlight = "apply_highlight"
lang_name = "get_language_name"
[shortcodes]
# List of shortcode names this plugin handles
codes = ["code", "highlight"]
[routes]
# path = "HTTP method"
"/api/highlight" = "POST"
"/api/languages" = "GET"
[config]
# Plugin-specific settings (read via the config capability)
theme = "monokai"
line_numbers = true
Required Fields
The [plugin] section is required:
| Field | Type | Description |
|---|---|---|
name | string | Unique plugin identifier (used as registry key) |
version | string | Semantic version of the plugin |
api_version | string | Host API version the plugin targets (checked against the host’s supported range; see Security) |
description | string | Human-readable description (optional) |
requires_fs | bool | Request scoped WASI filesystem access (optional, default: false) |
allowed_hosts | array | Hosts the plugin may reach over outbound HTTP (optional; see Security) |
host_services | array | Host services the plugin may call through the typed host-services capability: "mail", "data" (optional; see Security) |
Hooks
The [hooks] section declares which lifecycle hooks the plugin listens to:
| Hook | When it fires | Input | Output |
|---|---|---|---|
on_page_load | Before markdown processing | Raw markdown | Modified markdown |
on_render | After HTML rendering | Rendered HTML | Modified HTML |
on_media_discover | During content scanning | File path, MIME type | Metadata key-value pairs |
on_media_process | After image processing | Raw image bytes, dimensions | Modified bytes, metadata |
Multiple plugins can register for the same hook. They are called in the order they were loaded.
The on_media_discover and on_media_process hooks are described in detail in the Media Hooks section.
Filters
The [filters] section declares the template filter names the plugin provides:
[filters]
highlight = "apply" # {{ code | highlight("rust") }}
uppercase = "apply" # {{ text | uppercase }}
The key is the filter name used in templates. The host dispatches every filter
to the component’s single apply export, keyed on the filter name, so the value
is simply that export.
Shortcodes
The [shortcodes] section lists shortcode names the plugin handles. Shortcodes are inline content components that authors embed in markdown using square-bracket notation (see Shortcodes for syntax details).
[shortcodes]
codes = ["note", "warning", "gallery"]
When Accent CMS encounters [note]...[/note] or [gallery/] in content, it calls the plugin’s render export from the shortcodes interface. The plugin receives the shortcode name, attributes, and optional body as typed values and returns rendered HTML.
Plugin shortcodes are checked after built-in and theme shortcodes in the resolution chain. This means a theme can override a plugin shortcode by providing a template with the same name in its shortcodes/ directory.
Routes
The [routes] section registers custom HTTP endpoints:
[routes]
"/api/search" = "GET"
"/api/contact" = "POST"
Plugin Configuration
The [config] section holds plugin-specific settings. A plugin reads them at
runtime through the config capability (config::get(key) /
config::get_all()); they merge under any overrides from plugins.config in
config.yaml:
[config]
theme = "monokai"
line_numbers = true
max_results = 50
A minimal plugin.toml only needs the [plugin] section:
[plugin]
name = "my-plugin"
version = "0.1.0"
api_version = "0.1.0"