Files
WooNooW/docs/ADDONS_GUIDE.md

5.4 KiB

WooNooW Addon & Module Development Guide

Version: 2.0.0
Status: Production Ready

This document is the single source of truth for extending WooNooW. It covers everything from basic code snippets (Bridge Patterns) to full-featured React SPAs (Addon Modules).


📋 Table of Contents

  1. Philosophy & Architecture
  2. Addon Types & Integration Levels
    • Level 1: Vanilla JS / Bridge Patterns
    • Level 2: React Runtime Expansion (Recommended)
    • Level 3: Slot-Based Components
  3. Developing a Full Addon
    • Registration
    • Settings & Options
    • The Hook System
  4. Addon & Built-in Module Unification
  5. Examples

1. Philosophy & Architecture

WooNooW Core = Zero Addon Dependencies

We don't integrate specific addons (like shipping or payment plugins) directly into WooNooW core. Instead, we provide:

  1. Hook system for external addons to extend functionality.
  2. Exposed React Runtime so addons don't have to bundle heavy libraries.
  3. Unified Module Registry where built-in features (like Affiliates, Newsletters) and external addons share the same UI and enablement toggles.

2. Addon Types & Integration Levels

Level 1: Vanilla JS / Bridge Patterns (Basic)

Use this for simple snippets to make existing WooCommerce plugins (e.g. Rajaongkir) work with WooNooW.

// Wait for WooNooW to load
window.addEventListener('woonoow:loaded', function() {
  window.WooNooW.hooks.addFilter('woonoow_order_form_after_shipping', function(container, formData) {
    const div = document.createElement('div');
    div.innerHTML = `<select id="custom-dest"><option>Select...</option></select>`;
    container.appendChild(div);
    return container;
  });
});

WooNooW exposes React, ReactDOM, its hooks, and its components on window.WooNooW. This allows addons to build rich UIs without bundling React.

Webpack/Vite Setup (Externals):

// vite.config.js
export default {
  build: {
    rollupOptions: {
      external: ['react', 'react-dom'],
      output: {
        globals: {
          react: 'window.WooNooW.React',
          'react-dom': 'window.WooNooW.ReactDOM'
        }
      }
    }
  }
};

Usage:

const { React, hooks, components } = window.WooNooW;
const { addFilter } = hooks;
const { Select } = components;

function CustomField({ formData, setFormData }) {
  return <Select label="Custom" onChange={(val) => setFormData({...})} />;
}

addFilter('woonoow_order_form_after_shipping', (container, props) => {
  const root = window.WooNooW.ReactDOM.createRoot(container);
  root.render(<CustomField {...props} />);
  return container;
});

Level 3: SPA Route Injection (Admin Pages)

You can inject entire new pages into the WooNooW admin SPA.

add_filter('woonoow/spa_routes', function($routes) {
    $routes[] = [
        'path'          => '/my-addon',
        'component_url' => plugin_dir_url(__FILE__) . 'dist/MyPage.js',
        'title'         => 'My Addon',
    ];
    return $routes;
});

3. Developing a Full Addon

Step 1: Registration

Register the addon via PHP filters so WooNooW knows it exists.

add_filter('woonoow/addon_registry', function($addons) {
    $addons['my-addon'] = [
        'id'           => 'my-addon',
        'name'         => 'My Custom Addon',
        'description'  => 'Does something awesome.',
        'version'      => '1.0.0',
        'category'     => 'shipping', // Auto-groups in the UI
        'icon'         => 'truck', 
        'spa_bundle'   => plugin_dir_url(__FILE__) . 'dist/addon.js',
        'has_settings' => true, // Enables the ⚙️ icon
    ];
    return $addons;
});

Step 2: Settings & Options

By declaring 'has_settings' => true, WooNooW expects your settings to live at /settings/modules/{addon_id}.

Option A: Schema-based (No React needed)

add_filter('woonoow/module_settings_schema', function($schemas) {
    $schemas['my-addon'] = [
        'api_key' => ['type' => 'text', 'label' => 'API Key'],
    ];
    return $schemas;
});

Option B: Custom React Settings Component

// In addon_registry registration array:
'settings_component' => plugin_dir_url(__FILE__) . 'dist/Settings.js',

Access data in React:

const { useModuleSettings } = window.WooNooW.hooks;
const { settings, updateSettings } = useModuleSettings('my-addon');

4. Addon & Built-in Module Unification

Concept: External addons and built-in features (e.g. Affiliates, Newsletters) look and act exactly the same in the Admin UI.

  • Both use ModuleRegistry.
  • Both generate dynamic categories (e.g. "Marketing", "Shipping").
  • Both persist settings to woonoow_module_{id}_settings.

5. Hook System Reference

Frontend Extension Hooks

// Add fields
'woonoow_order_form_after_billing'
'woonoow_order_form_after_shipping'
'woonoow_order_form_custom_sections'

// Validation & Data Modification
'woonoow_order_form_validation'
'woonoow_order_form_data'

Backend Action Hooks

apply_filters('woonoow_before_shipping_calculate', $shipping_data);
apply_filters('woonoow_after_shipping_calculate', $rates, $shipping_data);
apply_filters('woonoow_shipping_data', $data);

For specific implementation examples, consult the examples/ directory in the repository.