Plugin Development Guide – Hooks, Structure & Examples
Writing Plugins for Xiuno BBS
Xiuno plugins use a hook-based system: the core calls include on hook files at predefined points, letting you inject behaviour without modifying core files.
Plugin Directory Structure
plugin/
your_plugin_name/
info.json
plugin.php
hook/
thread_create_thread_end.php
index_route_case_start.php
view/
lang/
conf/
info.json
{
"name": "My Plugin",
"identifier": "my_plugin",
"version": "1.0.0",
"author": "Your Name",
"description": "What this plugin does."
}
Hook Example
Create plugin/my_plugin/hook/thread_create_thread_end.php:
<?php
// $thread and $tid are available here from the core
$custom_value = param('my_field', '', TRUE);
if ($custom_value) {
$db->execute(
"INSERT INTO my_plugin_meta (tid, value) VALUES (?, ?)",
[$tid, $custom_value]
);
}
Common Hooks
| Hook file name | Fires when |
|---|---|
| index_start.php | Every page load, before routing |
| thread_create_thread_end.php | After a new thread is saved |
| thread_info_start.php | Before thread detail page renders |
| post_create_end.php | After a reply is saved |
| user_login_end.php | After successful login |
Tips
- Keep plugins narrow in scope — one responsibility per plugin
- Never modify core files; always use hooks
- Cache heavy queries with kv_set() / kv_get()
- Test with DEBUG=1 to see SQL queries and request data
Post questions in this forum!