Plugin Quick Start Guide
Build your first AIPostify plugin in under 10 minutes. This guide walks you through folder structure, the BasePlugin class, lifecycle hooks, and the plugin.json manifest.
📦 Example Plugin: postify-announcements
All code examples reference the real, working postify-announcements plugin included in the AIPostify codebase at content/plugins/postify-announcements/.
1. Folder Structure
Every plugin lives inside content/plugins/<your-plugin-slug>/. Here's the minimal structure:
content/plugins/my-first-plugin/
├── plugin.json # Manifest (required)
├── MyFirstPlugin.php # Main class extending BasePlugin (required)
├── views/
│ └── admin/
│ └── settings.blade.php
└── assets/
├── css/
└── js/
The postify-announcements plugin follows this exact structure. Check its PostifyAnnouncements.php main class for a real-world reference.
2. Create plugin.json
This manifest file describes your plugin to the AIPostify core and the Marketplace:
{
"name": "My First Plugin",
"slug": "my-first-plugin",
"version": "1.0.0",
"description": "A demo plugin to learn the AIPostify plugin API.",
"author": "Your Name",
"author_url": "https://example.com",
"main_class": "MyFirstPlugin",
"min_aipostify_version": "1.0.0",
"license": "MIT",
"tags": ["demo", "starter"]
}
⚠️ Known Inconsistency: Some existing plugins use requires_aipostify and others use min_aipostify_version for the minimum version field. The recommended canonical field name is min_aipostify_version. See the plugin.json Reference for full details.
3. Extend BasePlugin
Your main plugin class must extend App\CMS\Plugins\BasePlugin. Override the lifecycle methods to hook into AIPostify:
<?php
namespace Plugins\MyFirstPlugin;
use App\CMS\Plugins\BasePlugin;
use App\CMS\Hooks\Hook;
class MyFirstPlugin extends BasePlugin
{
/**
* Called when the plugin is first activated.
* Use for one-time setup: create DB tables, seed defaults, etc.
*/
public function activate(): void
{
// Run on first activation
\Log::info('MyFirstPlugin activated!');
}
/**
* Called when the plugin is deactivated.
* Use for cleanup: remove scheduled tasks, clear caches.
*/
public function deactivate(): void
{
\Log::info('MyFirstPlugin deactivated.');
}
/**
* Called on every request when the plugin is active.
* Register hooks, shortcodes, post types, menus, etc.
*/
public function boot(): void
{
// Register a hook listener
Hook::listen('after_post_content', function ($content) {
return $content . '<p>Powered by My First Plugin</p>';
});
// Register an admin menu item
$this->registerAdminMenu();
}
protected function registerAdminMenu(): void
{
Hook::listen('admin_menu', function () {
app('admin.menu')->add([
'title' => 'My Plugin Settings',
'slug' => 'my-first-plugin-settings',
'icon' => '⚙️',
'view' => 'plugins.my-first-plugin.views.admin.settings',
]);
});
}
}
BasePlugin Lifecycle Methods
| Method | When Called | Typical Use |
|---|---|---|
activate() | Plugin first enabled by admin | Create tables, seed defaults, register capabilities |
deactivate() | Plugin disabled by admin | Cleanup caches, remove scheduled tasks |
boot() | Every request (when active) | Register hooks, shortcodes, post types, admin menus |
4. Register Your First Hook
The Hook system is the backbone of the AIPostify extension API. Use Hook::listen() for actions and Hook::filter() / Hook::applyFilters() for filters:
// Action: Fire-and-forget event listener
Hook::listen('after_post_save', function ($post) {
\Log::info("Post saved: {$post->title}");
});
// Filter: Modify a value in a pipeline
Hook::listen('the_content', function ($content) {
return str_replace('foo', 'bar', $content);
}, priority: 10);
// WordPress-style aliases also work:
add_action('init', function () { /* ... */ });
add_filter('the_title', function ($title) { return strtoupper($title); });
See the full Hook API Reference for all available methods and known core hook points.
5. Test Your Plugin
- Copy your
my-first-plugin/folder intocontent/plugins/. - Log in to the AIPostify admin dashboard.
- Navigate to Plugins → Installed Plugins.
- Click Activate next to "My First Plugin".
- Your
boot()method will run on the next page load — check the admin menu for your settings link!
💡 Tip: Enable APP_DEBUG=true in your .env and watch storage/logs/laravel.log for your \Log::info() messages during development.
Next Steps
Last verified against AIPostify core. © 2026 AIPostify Marketplace Developer Documentation.