Developers

Examples

Copy-paste patterns for common module tasks. Each example is self-contained and production-ready.

Register Settings

php

Use the SettingsInterface to register module settings with defaults and validation.

class-module.php
<?php

use Meteorack\SDK\Contracts\SettingsInterface;

class My_Module implements ModuleInterface {

    public function __construct(
        private readonly SettingsInterface $settings,
    ) {}

    public function boot(): void {
        $this->settings->register('my-module', [
            'api_key'  => '',
            'enabled'  => true,
            'per_page' => 25,
        ]);

        // Read a setting
        $key = $this->settings->get('my-module', 'api_key');

        // Update a setting
        $this->settings->set('my-module', 'per_page', 50);
    }
}

Cache Expensive Operations

php

Use the CacheInterface to cache API responses, query results, or computed data with TTL support.

class-module.php
<?php

use Meteorack\SDK\Contracts\CacheInterface;
use Meteorack\SDK\Contracts\HttpInterface;

class Data_Module implements ModuleInterface {

    public function __construct(
        private readonly CacheInterface $cache,
        private readonly HttpInterface $http,
    ) {}

    public function get_stats(): array {
        $key = 'stats:dashboard';

        // Return cached if available
        if ($this->cache->has($key)) {
            return $this->cache->get($key);
        }

        // Fetch fresh data
        $stats = $this->http->get('/api/stats')->json();

        // Cache for 5 minutes
        $this->cache->set($key, $stats, 300);

        return $stats;
    }
}

Dispatch & Listen to Events

php

Use the EventsInterface to dispatch domain events and listen to events from other modules.

class-module.php
<?php

use Meteorack\SDK\Contracts\EventsInterface;

class Orders_Module implements ModuleInterface {

    public function __construct(
        private readonly EventsInterface $events,
    ) {}

    public function boot(): void {
        // Listen to events from other modules
        $this->events->listen('payment.completed', [$this, 'on_payment']);
    }

    public function create_order(array $data): void {
        $order = $this->save_order($data);

        // Dispatch event for other modules
        $this->events->dispatch('order.created', [
            'order_id' => $order['id'],
            'total'    => $order['total'],
        ]);
    }

    public function on_payment(array $payload): void {
        $this->mark_paid($payload['order_id']);
    }
}

React Admin Page

tsx

Mount a full React application inside wp-admin with the Admin Takeover system.

assets/admin.tsx
import { createRoot } from 'react-dom/client';
import { useState, useEffect } from 'react';

function Dashboard() {
  const [stats, setStats] = useState(null);

  useEffect(() => {
    // WordPress REST API is available
    fetch('/wp-json/meteorack/v1/my-module/stats')
      .then((r) => r.json())
      .then(setStats);
  }, []);

  if (!stats) {
    return (
      <div className="animate-pulse space-y-4 p-8">
        <div className="h-8 w-48 rounded bg-gray-200" />
        <div className="h-32 rounded bg-gray-200" />
      </div>
    );
  }

  return (
    <div className="p-8">
      <h1 className="text-2xl font-bold">Dashboard</h1>
      <div className="mt-6 grid grid-cols-3 gap-4">
        {Object.entries(stats).map(([key, value]) => (
          <div key={key} className="rounded-lg border p-4">
            <p className="text-sm text-gray-500">{key}</p>
            <p className="text-2xl font-bold">{String(value)}</p>
          </div>
        ))}
      </div>
    </div>
  );
}

createRoot(
  document.getElementById('meteorack-module-root')!
).render(<Dashboard />);

Error Boundary Component

tsx

Wrap risky components in the SDK's error boundary to prevent full-page crashes in admin.

components/safe-widget.tsx
import { ModuleErrorBoundary } from '@meteorack/sdk/components';

function RiskyChart({ data }: { data: unknown[] }) {
  // This might throw if data is malformed
  return (
    <div className="h-64">
      {data.map((point, i) => (
        <div
          key={i}
          className="inline-block w-2 bg-blue-500"
          style={{ height: `${Number(point)}%` }}
        />
      ))}
    </div>
  );
}

export function SafeWidget({ data }: { data: unknown[] }) {
  return (
    <ModuleErrorBoundary
      slug="my-module"
      fallback={
        <div className="rounded-lg border border-red-200 bg-red-50 p-4">
          <p className="text-sm text-red-600">
            Chart failed to render. Data may be corrupted.
          </p>
        </div>
      }
    >
      <RiskyChart data={data} />
    </ModuleErrorBoundary>
  );
}

Scheduled Tasks

php

Use the SchedulerInterface to run recurring tasks — cron jobs managed by the Hub with crash protection.

class-module.php
<?php

use Meteorack\SDK\Contracts\SchedulerInterface;
use Meteorack\SDK\Contracts\LoggerInterface;

class Cleanup_Module implements ModuleInterface {

    public function __construct(
        private readonly SchedulerInterface $scheduler,
        private readonly LoggerInterface $logger,
    ) {}

    public function boot(): void {
        // Run daily at 3:00 AM
        $this->scheduler->daily('cleanup:expired', [$this, 'cleanup'], '03:00');

        // Run every 15 minutes
        $this->scheduler->every(15, 'sync:external', [$this, 'sync']);
    }

    public function cleanup(): void {
        $deleted = $this->delete_expired_records();
        $this->logger->info('cleanup.completed', [
            'deleted' => $deleted,
        ]);
    }

    public function sync(): void {
        $this->logger->info('sync.started');
        // Sync logic here
    }
}

Need more depth? Check the guides for full walkthroughs.