Build a complete Meteorack module from scratch — manifest, entry point, services, and admin page.
Every module lives in wp-content/meteorack/modules/<slug>/. The Hub auto-discovers any folder with a valid module.json manifest. No registration code needed.
wp-content/meteorack/modules/my-module/
├── module.json # Manifest
├── class-module.php # Entry point
├── src/
│ └── class-handler.php
└── assets/
└── admin.jsmodule.json declares your module's identity, PHP requirements, requested services, and admin integration. The Hub reads this before booting your code.
{
"slug": "my-module",
"name": "My Module",
"version": "1.0.0",
"entry": "class-module.php",
"requires": {
"php": "^8.2",
"hub": "^1.0"
},
"services": ["settings", "logger", "cache"],
"admin": {
"page": true,
"menu_title": "My Module"
}
}Your entry class implements ModuleInterface. The container auto-injects every service listed in module.json. The boot() method is your setup hook — register WordPress hooks, filters, and admin pages here.
<?php
declare(strict_types=1);
use Meteorack\SDK\Contracts\ModuleInterface;
use Meteorack\SDK\Contracts\SettingsInterface;
use Meteorack\SDK\Contracts\LoggerInterface;
class My_Module implements ModuleInterface {
public function __construct(
private readonly SettingsInterface $settings,
private readonly LoggerInterface $logger,
) {}
public function boot(): void {
$this->logger->info('my-module.boot');
add_action('admin_init', [$this, 'init']);
}
public function slug(): string {
return 'my-module';
}
public function init(): void {
$this->settings->register('my-module', [
'enabled' => true,
]);
}
}Use WP-CLI to confirm your module is discovered and active. The Hub boots modules in isolation — a crash in your module won't affect others.
wp meteorack modules list
# Expected output:
# +-----------+---------+--------+
# | Module | Version | Status |
# +-----------+---------+--------+
# | my-module | 1.0.0 | active |
# +-----------+---------+--------+