Files
igny8/docs/60-PLUGINS/WORDPRESS-INTEGRATION.md
2026-01-09 22:45:30 +00:00

21 KiB

WordPress Integration Management

Last Updated: January 9, 2026
Status: Production
Scope: App-side management of WordPress plugin distribution and site integrations


Table of Contents

  1. Overview
  2. Architecture
  3. Plugin Distribution System
  4. Database Models
  5. API Endpoints
  6. Django Admin Management
  7. Frontend Integration
  8. Site Integration Flow
  9. Troubleshooting

1. Overview

What This Document Covers

This document covers the app-side management of WordPress integration:

  • How the IGNY8 app distributes the WordPress plugin
  • How site integrations are tracked in the database
  • API endpoints that WordPress plugins call
  • Admin interface for managing plugins and versions
  • Frontend components for plugin download

What This Document Does NOT Cover

  • Internal plugin PHP code and functions (see /plugins/wordpress/source/igny8-wp-bridge/docs/)
  • WordPress-side setup and configuration
  • Plugin installation on WordPress sites

2. Architecture

System Components

┌─────────────────────────────────────────────────────────────────────────┐
│                           IGNY8 App Server                               │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  ┌──────────────────┐    ┌──────────────────┐    ┌──────────────────┐  │
│  │  Django Backend  │    │    PostgreSQL    │    │   Plugin Files   │  │
│  │                  │    │                  │    │                  │  │
│  │  - API Views     │◄──►│  - Plugin        │    │  /plugins/       │  │
│  │  - Admin         │    │  - PluginVersion │    │  └─wordpress/    │  │
│  │  - Signals       │    │  - Installation  │    │    ├─source/     │  │
│  │                  │    │  - Downloads     │    │    └─dist/       │  │
│  └────────┬─────────┘    └──────────────────┘    └────────┬─────────┘  │
│           │                                                │            │
│           │  API Routes: api.igny8.com                    │            │
│           ▼                                                ▼            │
│  ┌──────────────────────────────────────────────────────────────────┐  │
│  │                         API Endpoints                             │  │
│  │                                                                   │  │
│  │  /api/plugins/{slug}/download/      → Serve ZIP file             │  │
│  │  /api/plugins/{slug}/check-update/  → Return update info         │  │
│  │  /api/plugins/{slug}/info/          → Return plugin metadata     │  │
│  │  /api/plugins/{slug}/register/      → Register installation      │  │
│  │  /api/plugins/{slug}/health-check/  → Report plugin status       │  │
│  └──────────────────────────────────────────────────────────────────┘  │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                                    │ HTTPS
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                        WordPress Sites                                   │
│                                                                          │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐    │
│  │   Site A    │  │   Site B    │  │   Site C    │  │   Site N    │    │
│  │  v1.1.1     │  │  v1.1.0     │  │  v1.1.1     │  │  v1.0.0     │    │
│  └─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘    │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

URL Routing

Domain Service Purpose
app.igny8.com Frontend (Vite) User interface
api.igny8.com Backend (Django) API endpoints

Important: WordPress plugins must call api.igny8.com, not app.igny8.com.


3. Plugin Distribution System

Directory Structure

/data/app/igny8/
├── plugins/
│   └── wordpress/
│       ├── source/                          # Development source
│       │   └── igny8-wp-bridge/
│       │       ├── igny8-bridge.php         # Main plugin file
│       │       ├── includes/                # PHP classes
│       │       ├── admin/                   # Admin interface
│       │       ├── sync/                    # Sync functionality
│       │       ├── templates/               # Frontend templates
│       │       └── docs/                    # Plugin-internal docs
│       └── dist/                            # Distribution files
│           ├── igny8-wp-bridge-v1.1.1.zip   # Version ZIP
│           ├── igny8-wp-bridge-v1.1.1.sha256
│           └── igny8-wp-bridge-latest.zip   # Symlink to latest
│
└── backend/
    └── igny8_core/
        └── plugins/                         # Django app
            ├── models.py                    # Database models
            ├── views.py                     # API endpoints
            ├── signals.py                   # Auto-build triggers
            ├── utils.py                     # ZIP creation utilities
            ├── admin.py                     # Django admin config
            └── urls.py                      # URL routing

How ZIP Files Are Created

When a PluginVersion status changes to released or update_ready, the system automatically:

  1. Reads source files from /plugins/wordpress/source/igny8-wp-bridge/
  2. Updates version numbers in PHP files
  3. Removes development files (tests, .git, pycache)
  4. Creates ZIP in /plugins/wordpress/dist/
  5. Calculates SHA256 checksum
  6. Updates database with file_path, file_size, checksum
  7. Updates *-latest.zip symlink

This is handled by signals.py:

# backend/igny8_core/plugins/signals.py

@receiver(pre_save, sender=PluginVersion)
def auto_build_plugin_on_release(sender, instance, **kwargs):
    """Automatically build ZIP when version is released."""
    # Triggered on status change to 'released' or 'update_ready'

Manual Build (If Needed)

# From project root
cd /data/app/igny8/plugins/wordpress/source

# Create ZIP manually
zip -r ../dist/igny8-wp-bridge-v1.2.0.zip igny8-wp-bridge/ \
    -x "*.git*" -x "*__pycache__*" -x "*.DS_Store" -x "*tester*"

# Update checksum
sha256sum ../dist/igny8-wp-bridge-v1.2.0.zip > ../dist/igny8-wp-bridge-v1.2.0.sha256

# Update symlink
ln -sf igny8-wp-bridge-v1.2.0.zip ../dist/igny8-wp-bridge-latest.zip

4. Database Models

Plugin

Represents a plugin type (WordPress, Shopify, etc.).

class Plugin(models.Model):
    name = models.CharField(max_length=100)      # "IGNY8 WordPress Bridge"
    slug = models.SlugField(unique=True)          # "igny8-wp-bridge"
    platform = models.CharField(...)              # "wordpress", "shopify", "custom"
    description = models.TextField()
    homepage_url = models.URLField()
    is_active = models.BooleanField(default=True)

Current Records:

ID Name Slug Platform
1 IGNY8 WordPress Bridge igny8-wp-bridge wordpress

PluginVersion

Tracks each version of a plugin.

class PluginVersion(models.Model):
    plugin = models.ForeignKey(Plugin, ...)
    version = models.CharField(max_length=20)     # "1.1.1"
    version_code = models.IntegerField()          # 10101 (for comparison)
    status = models.CharField(...)                # "draft", "released", "update_ready"
    
    # File info (auto-populated on release)
    file_path = models.CharField(...)             # "igny8-wp-bridge-v1.1.1.zip"
    file_size = models.IntegerField()             # 167589 (bytes)
    checksum = models.CharField(max_length=64)    # SHA256
    
    # Release info
    changelog = models.TextField()
    min_php_version = models.CharField(default='7.4')
    released_at = models.DateTimeField(null=True)
    force_update = models.BooleanField(default=False)

Version Status Flow:

draft → testing → staged → released → update_ready → deprecated
                              │              │
                              │              └─ Notifies WP sites
                              └─ Available for download

PluginInstallation

Tracks where plugins are installed.

class PluginInstallation(models.Model):
    site = models.ForeignKey('Site', ...)
    plugin = models.ForeignKey(Plugin, ...)
    current_version = models.ForeignKey(PluginVersion, ...)
    is_active = models.BooleanField(default=True)
    last_health_check = models.DateTimeField(null=True)
    health_status = models.CharField(...)  # "healthy", "outdated", "error"

PluginDownload

Tracks download analytics.

class PluginDownload(models.Model):
    plugin = models.ForeignKey(Plugin, ...)
    version = models.ForeignKey(PluginVersion, ...)
    ip_address = models.GenericIPAddressField()
    user_agent = models.CharField(max_length=500)
    download_type = models.CharField(...)  # "manual", "auto_update"
    created_at = models.DateTimeField(auto_now_add=True)

5. API Endpoints

Public Endpoints (No Auth Required)

Download Plugin

GET /api/plugins/{slug}/download/

Returns the latest released ZIP file.

Response: Binary ZIP file download

Example:

curl -O https://api.igny8.com/api/plugins/igny8-wp-bridge/download/

Check for Updates

GET /api/plugins/{slug}/check-update/?current_version=1.0.0

Called by installed WordPress plugins to check for updates.

Response:

{
    "update_available": true,
    "current_version": "1.0.0",
    "latest_version": "1.1.1",
    "latest_version_code": 10101,
    "download_url": "https://api.igny8.com/api/plugins/igny8-wp-bridge/download/",
    "changelog": "Bug fixes and improvements",
    "info_url": "https://api.igny8.com/api/plugins/igny8-wp-bridge/info/",
    "force_update": false,
    "checksum": "6b9e231c07434df1dcfe81596b57f3571c30b6c2..."
}

Plugin Info

GET /api/plugins/{slug}/info/

Returns plugin metadata for WordPress update modal.

Response:

{
    "name": "IGNY8 WordPress Bridge",
    "slug": "igny8-wp-bridge",
    "version": "1.1.1",
    "author": "IGNY8",
    "homepage": "https://igny8.com",
    "description": "Lightweight bridge plugin...",
    "changelog": "Bug fixes and improvements",
    "download_url": "https://api.igny8.com/api/plugins/igny8-wp-bridge/download/",
    "file_size": 167589,
    "requires_php": "7.4",
    "tested_wp": "6.7"
}

Authenticated Endpoints

Register Installation

POST /api/plugins/{slug}/register/
Headers: Authorization: Api-Key {site_api_key}

Called when plugin is activated on a WordPress site.

Request Body:

{
    "site_id": 123,
    "version": "1.1.1",
    "wp_version": "6.7",
    "php_version": "8.2"
}

Health Check

POST /api/plugins/{slug}/health-check/
Headers: Authorization: Api-Key {site_api_key}

Periodic status report from installed plugins.

Request Body:

{
    "site_id": 123,
    "version": "1.1.1",
    "status": "active",
    "last_sync": "2026-01-09T12:00:00Z"
}

6. Django Admin Management

Accessing Plugin Admin

  1. Go to: https://api.igny8.com/backend/
  2. Login with admin credentials
  3. Navigate to Plugin Distribution section

Admin Sections

Plugins

View and manage plugin registry.

Field Description
Name Display name
Slug URL identifier (cannot change after creation)
Platform wordpress, shopify, custom
Is Active Whether available for download

Plugin Versions

Manage versions and trigger releases.

Field Description
Plugin Parent plugin
Version Semantic version (e.g., 1.1.1)
Status draft, testing, staged, released, update_ready, deprecated
File Path Auto-set on release
File Size Auto-calculated on release
Checksum Auto-calculated on release
Changelog What's new (shown to users)
Force Update Set true for critical security fixes

To Release a New Version:

  1. Create new PluginVersion record with status draft
  2. Enter version number, changelog
  3. Change status to released or update_ready
  4. Save → ZIP is automatically built

Plugin Installations

View where plugins are installed.

Field Description
Site IGNY8 site record
Plugin Which plugin
Current Version Installed version
Health Status healthy, outdated, error
Last Health Check Timestamp

Plugin Downloads

View download analytics.

Field Description
Plugin Which plugin
Version Which version
Download Type manual, auto_update
IP Address Client IP
User Agent Browser/client info
Created At Timestamp

7. Frontend Integration

Download Button Location

Page: Site Settings → Integrations → WordPress

Component: frontend/src/components/sites/WordPressIntegrationForm.tsx

How Download Works

// WordPressIntegrationForm.tsx

import { API_BASE_URL } from '../../services/api';

const handleDownloadPlugin = () => {
    // Uses API_BASE_URL which resolves to https://api.igny8.com/api
    const pluginUrl = `${API_BASE_URL}/plugins/igny8-wp-bridge/download/`;
    window.open(pluginUrl, '_blank');
    toast.success('Plugin download started');
};

Plugin Information Display

The frontend shows:

  • Plugin name and version
  • File size
  • PHP requirements
  • Download button
  • Changelog (expandable)

8. Site Integration Flow

Integration Creation Flow

┌─────────────────────────────────────────────────────────────────────────┐
│                        WordPress Site Setup                              │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  1. User downloads plugin from IGNY8 app                                │
│     └─ GET /api/plugins/igny8-wp-bridge/download/                       │
│                                                                          │
│  2. User installs and activates plugin in WordPress                     │
│                                                                          │
│  3. User enters Site ID and API Key in WP plugin settings               │
│     └─ These are generated in IGNY8 app                                 │
│                                                                          │
│  4. WP Plugin calls IGNY8 to register                                   │
│     └─ POST /api/plugins/igny8-wp-bridge/register/                      │
│                                                                          │
│  5. IGNY8 creates SiteIntegration record                                │
│     └─ Links WordPress site to IGNY8 site                               │
│                                                                          │
│  6. Integration is now active                                           │
│     └─ Content can be published from IGNY8 to WordPress                 │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Integration Data Model

# SiteIntegration model (in auth/models.py)

class SiteIntegration(models.Model):
    site = models.ForeignKey(Site, ...)           # IGNY8 site
    platform = models.CharField(...)               # "wordpress"
    external_site_url = models.URLField()          # WordPress URL
    api_key = models.CharField(...)                # Encrypted key
    sync_enabled = models.BooleanField()
    last_sync = models.DateTimeField()
    connection_status = models.CharField(...)      # "connected", "error"

9. Troubleshooting

Common Issues

"404 Not Found" on Download

Cause: Using wrong domain (app.igny8.com instead of api.igny8.com)

Solution: Ensure URL is https://api.igny8.com/api/plugins/igny8-wp-bridge/download/

"Plugin file not found" Error

Cause: ZIP file doesn't exist in dist/ directory

Solution:

# Check if file exists
ls -la /data/app/igny8/plugins/wordpress/dist/

# If missing, rebuild manually or change version status to trigger auto-build

Updates Not Showing in WordPress

Cause 1: WordPress caches plugin update checks

Solution: In WordPress admin, go to Dashboard → Updates → Check Again

Cause 2: Version status is not released or update_ready

Solution: Check PluginVersion status in Django admin

Wrong File Size/Checksum

Cause: Database values don't match actual file

Solution:

# Get actual values
stat -c %s /data/app/igny8/plugins/wordpress/dist/igny8-wp-bridge-v1.1.1.zip
sha256sum /data/app/igny8/plugins/wordpress/dist/igny8-wp-bridge-v1.1.1.zip

# Update in Django admin or shell

Verification Commands

# Test download endpoint
curl -I https://api.igny8.com/api/plugins/igny8-wp-bridge/download/

# Test check-update endpoint
curl "https://api.igny8.com/api/plugins/igny8-wp-bridge/check-update/?current_version=1.0.0"

# Test info endpoint
curl https://api.igny8.com/api/plugins/igny8-wp-bridge/info/

# Check ZIP contents
unzip -l /data/app/igny8/plugins/wordpress/dist/igny8-wp-bridge-v1.1.1.zip

# Verify API URL in plugin
unzip -p /data/app/igny8/plugins/wordpress/dist/igny8-wp-bridge-v1.1.1.zip \
    igny8-wp-bridge/igny8-bridge.php | grep "api.igny8.com"

Log Locations

Log Location
Django logs /data/app/logs/django.log
Plugin build logs Check Django log for "Created plugin ZIP" messages
Download tracking PluginDownload model in database