59 KiB
Phase 3 Build Plan — WordPress Ecosystem (4 Docs)
Purpose: This is a single instruction set for Claude Code to build all 4 Phase 3 execution documents. Read this entire file, then build each doc one at a time.
CRITICAL BASELINE RULES (from V2-Execution-Docs-Updated)
Before writing ANY doc, internalize these codebase-verified facts:
Primary Keys
- ALL models use
BigAutoField(integer PKs, NOT UUIDs) DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'- Every ID in API requests/responses is an integer
Model Names (PLURAL)
Clusters(not Cluster),Keywords(not Keyword),Tasks(not Task)ContentIdeas(not ContentIdea),Images(not Image),Content(stays singular)
App Structure
- Project root:
igny8_core/ - SAG app:
igny8_core/sag/ - App labels:
igny8_core_auth,planner,writer,automation,integration, etc. - All tables use
igny8_prefix (e.g.,igny8_content,igny8_clusters)
Frontend Stack
- TypeScript (
.tsxfiles, NOT.jsx) - Zustand for state management (NOT Redux)
- Vite ^6.1.0 as build tool
- React ^19.0.0
- Vitest + Playwright for testing (NOT Selenium/Cypress)
Verified Codebase Versions (what actually runs today)
- Python 3.11-slim (Dockerfile)
- Django >=5.2.7 (requirements.txt)
- Node 18-alpine (Dockerfile.dev)
- Celery >=5.3.0
- WP Plugin: IGNY8 WordPress Bridge v1.5.2
- These are CURRENT versions. Upgrade targets (Python 3.14, Django 6.0, etc.) are in 00B but are SEPARATE tasks.
Model Inheritance
AccountBaseModelprovides:accountFK,created_by,created_at,updated_atSiteSectorBaseModelextends AccountBaseModel with:siteFK,sectorFKSoftDeletableModelmixin provides soft delete viaSoftDeleteManager
Source of Truth
- Start every doc with:
**Source of Truth:** Codebase at /data/app/igny8/ - Codebase overrides any planning doc
DOC STRUCTURE STANDARD
Every doc MUST follow this structure:
# [Phase.Sub] — Title
**Source of Truth:** Codebase at `/data/app/igny8/`
**Version:** 1.0
**Date:** 2026-03-23
## 1. Current State
What exists today relevant to this sub-phase.
## 2. What to Build
Complete scope.
## 3. Data Models & APIs
New/modified models, endpoints, serializers, database tables.
## 4. Implementation Steps
Ordered steps with exact commands, file paths, code snippets.
## 5. Acceptance Criteria
Testable checkboxes.
## 6. Claude Code Instructions
Specific execution guidance — file creation order, test commands, verification.
EXISTING WORDPRESS PLUGIN CONTEXT
The IGNY8 WordPress Bridge Plugin v1.5.2 ALREADY EXISTS. Key facts:
- Location:
/data/app/igny8/plugins/wordpress/source/igny8-wp-bridge/ - Current capabilities: Content sync from IGNY8 → WordPress, site data collection, basic REST endpoints
- Already has: API key authentication, connection management, content push endpoint
- Plugin headers:
IGNY8 WordPress Bridge, version 1.5.2 - Existing REST namespace:
/wp-json/igny8/v1/ - Authentication:
X-IGNY8-API-KEYheader validation
Phase 3 docs describe building the NEXT GENERATION plugin (v2) which is a completely new plugin, not a patch to v1.5.2. The v1.5.2 bridge becomes deprecated once v2 is deployed.
EXISTING IGNY8 BACKEND CONTEXT (relevant to WordPress integration)
Models that WordPress interacts with:
Content(writer app) — content_type: post/page/product/taxonomy; content_structure: article/guide/comparison/review/listicle/landing_page/etc.Tasks(writer app) — writing tasks, status: pending/generating/completed/failedImages(writer app) — generated images for contentClusters(planner app) — keyword clusters, linked to SAGCluster via optional FKSAGBlueprint,SAGAttribute,SAGCluster(sag app) — Phase 1 modelsSiteIntegration(integration app) — stores WordPress connection detailsSyncEvent(integration app) — logs sync operationsPublishingSettings,PublishingRecord(publishing app)
Backend endpoints the plugin consumes:
GET /api/v1/writer/content/?site_id=X&status=approved— content ready for syncGET /api/v1/writer/content/{id}/— single content with HTML, images, taxonomy dataGET /api/v1/planner/clusters/?site_id=X— cluster dataGET /api/v1/sag/blueprints/?site_id=X— SAG blueprint (Phase 1)POST /api/v1/integration/sync-events/— log sync resultsPOST /api/v1/publishing/records/— log publishing
Backend endpoints the plugin exposes (plugin → IGNY8):
POST /wp-json/igny8/v1/sync/push— content push from IGNY8POST /wp-json/igny8/v1/sag/sync-blueprint— SAG blueprint syncPOST /wp-json/igny8/v1/sag/create-taxonomies— taxonomy creationPOST /wp-json/igny8/v1/event— webhook events
WordPress Requirements:
- Minimum: WordPress 5.9+, PHP 7.4+
- GPL v2+ license
- WordPress.org coding standards compliance
- All user-facing strings translatable via
igny8text domain - Sanitize all inputs (
sanitize_text_field,wp_kses_post), escape all outputs (esc_html,esc_attr,esc_url) - Use WP APIs (Settings API, REST API, WP_Query) — no direct DB queries where WP functions exist
DOC 03A: wp-plugin-standalone.md
File: V2-Execution-Docs/03A-wp-plugin-standalone.md
Scope: 10 standalone modules that work WITHOUT an IGNY8 SaaS subscription — a complete free SEO plugin.
Depends On: 02D (Linker internal — IGNY8 backend linking logic feeds plugin's linking module), 02G (Rich Schema — IGNY8 schema generation feeds plugin's schema module)
Source Material:
- temp/IGNY8-Project-Files/IGNY8-Plugin-Build-Plan.md
- temp/IGNY8-Project-Files/DocC-WordPress-Ecosystem-Dev-Guide.md
What to Cover:
1. Current State:
- WP Bridge v1.5.2 exists but is sync-only (no standalone SEO features)
- No standalone SEO capabilities currently
- Users currently rely on Yoast/RankMath alongside IGNY8
2. What to Build — 10 Standalone Modules:
Module 1: SEO Core
- Focus keyword per post/page/product (primary + secondary keywords)
- SEO title + meta description editor with live SERP preview
- Content analysis: keyword density, heading structure, readability score (Flesch-Kincaid)
- Title tag templates (per post type, taxonomy, author, date archives)
- Breadcrumbs (shortcode
[igny8_breadcrumbs]+ functionigny8()->seo->get_breadcrumbs()) - Open Graph meta tags (Facebook: og:title, og:description, og:image, og:type) + Twitter Cards (twitter:card, twitter:title, twitter:description, twitter:image)
- Robots meta per post (noindex, nofollow, noarchive)
- Canonical URL override
- Webmaster verification codes (Google, Bing, Yandex, Pinterest)
- Frontend head output: consolidate all
<title>, meta description, OG tags, robots, canonical, schema into singlewp_headhook at priority 1
Classes:
IGNY8_SEO_Module— module bootstrap, hook registrationIGNY8_Meta_Box— post editor meta box UI + save handlerIGNY8_Title_Tag—<title>management, template system viadocument_title_partsfilterIGNY8_Meta_Tags— output<meta>description, robots, canonical in<head>IGNY8_Content_Analysis— real-time SEO scoring in admin JSIGNY8_Breadcrumbs— breadcrumb HTML generation + BreadcrumbList schemaIGNY8_OpenGraph— OG + Twitter Card meta tagsIGNY8_Robots_Txt— virtual robots.txt managerIGNY8_Verification— webmaster verification code output
Hooks:
- Actions:
wp_head(priority 1),add_meta_boxes,save_post,document_title_parts - Filters:
igny8_title_parts,igny8_title_separator,igny8_meta_description,igny8_robots_meta,igny8_canonical_url,igny8_breadcrumbs,igny8_seo_score
Post meta keys (all _igny8_ prefixed):
_igny8_focus_keyword, _igny8_secondary_keywords (JSON array),
_igny8_seo_title, _igny8_meta_description, _igny8_canonical_url,
_igny8_robots_index, _igny8_robots_follow,
_igny8_og_title, _igny8_og_description, _igny8_og_image (attachment ID),
_igny8_twitter_title, _igny8_twitter_description,
_igny8_seo_score (0-100), _igny8_content_score (0-100),
_igny8_readability_score (Flesch-Kincaid), _igny8_last_analysis (timestamp)
Term meta keys (all _igny8_term_ prefixed):
_igny8_term_seo_title, _igny8_term_meta_description,
_igny8_term_robots_index, _igny8_term_og_image
Options keys (all igny8_ prefixed):
igny8_seo_settings (JSON: title templates, separator, defaults)
igny8_social_profiles (JSON: {facebook, twitter, linkedin, youtube, instagram, pinterest})
Module 2: Schema (JSON-LD)
- Auto-detect schema type per post type
- Supported types: Article/BlogPosting, Organization/Person, WebPage/CollectionPage, BreadcrumbList, FAQPage, HowTo, LocalBusiness, Service, Product (WooCommerce), WebSite+SearchAction
- Custom schema editor (raw JSON-LD)
- Schema validation against Google Rich Results requirements
- Global settings: Organization vs Person, default types per post type
- Single
<script type="application/ld+json">block in head (merged from all types)
Classes:
IGNY8_Schema_Module,IGNY8_Schema_Generator(main dispatcher)- Type-specific:
IGNY8_Schema_Article,IGNY8_Schema_LocalBusiness,IGNY8_Schema_Product,IGNY8_Schema_FAQ,IGNY8_Schema_HowTo,IGNY8_Schema_Organization,IGNY8_Schema_WebPage,IGNY8_Schema_Breadcrumb,IGNY8_Schema_Service,IGNY8_Schema_Custom
Methods: get_json_ld($post_id), render_schema($post_id), detect_schema_type($post_id), get_organization_schema(), get_breadcrumb_schema($post_id)
Post meta: _igny8_schema_type, _igny8_schema_custom, _igny8_schema_faq (connected), _igny8_schema_howto (connected)
Options: igny8_schema_settings (JSON: org type, name, logo, knowledge graph)
Hooks: igny8_schema_types, igny8_schema_{type}, igny8_json_ld
Module 3: Sitemap (XML)
- Sitemap index + sub-sitemaps per post type and taxonomy
- Image sitemaps
- XSL stylesheet for human-readable view
- Respects noindex settings
- Auto-ping search engines on update
- Exclusion rules (specific posts, taxonomies)
Classes: IGNY8_Sitemap_Module, IGNY8_Sitemap_Index, IGNY8_Sitemap_Posts, IGNY8_Sitemap_Taxonomies, IGNY8_Sitemap_Images, IGNY8_Sitemap_XSL
Rewrite rules:
/sitemap_index.xml → sitemap index
/sitemap-{post_type}.xml → post type sitemaps
/sitemap-{taxonomy}.xml → taxonomy sitemaps
/sitemap-images.xml → image sitemap
/sitemap.xsl → XSL stylesheet
Options: igny8_sitemap_settings (JSON: included post types, taxonomies)
Hooks: igny8_sitemap_post_types, igny8_sitemap_taxonomies, igny8_sitemap_excluded_urls
Module 4: Redirects
- CRUD for 301/302/307 redirects
- 404 monitoring with hit counts, referrer, user agent (hashed IP for privacy)
- Auto-redirect on slug change via
post_updatedhook - CSV import/export
- Regex redirect support (advanced)
- One-click redirect creation from 404 log
Classes: IGNY8_Redirects_Module, IGNY8_Redirect_Manager, IGNY8_404_Monitor, IGNY8_Auto_Redirect
Methods: add_redirect($source, $target, $type), log_404($url, $referrer), create_redirect_from_404($url, $target)
Options: igny8_redirect_settings (JSON: auto-redirect on slug change)
Database tables:
{prefix}igny8_redirects
id BIGINT AUTO_INCREMENT PRIMARY KEY
source_url VARCHAR(500) NOT NULL
target_url VARCHAR(500) NOT NULL
type SMALLINT DEFAULT 301 -- 301, 302, 307
hits INT DEFAULT 0
last_hit DATETIME NULL
created_at DATETIME NOT NULL
is_active TINYINT(1) DEFAULT 1
INDEX idx_source (source_url(191))
{prefix}igny8_404_log
id BIGINT AUTO_INCREMENT PRIMARY KEY
url VARCHAR(500) NOT NULL
referrer VARCHAR(500) NULL
user_agent VARCHAR(500) NULL
ip_hash VARCHAR(64) NULL -- SHA-256 hash for privacy
hits INT DEFAULT 1
first_hit DATETIME NOT NULL
last_hit DATETIME NOT NULL
is_resolved TINYINT(1) DEFAULT 0
redirect_id BIGINT NULL -- FK to igny8_redirects
INDEX idx_url (url(191))
Module 5: Site Intelligence
- Site audit runner (WP Cron weekly + manual trigger)
- Orphan page detection (no internal links pointing to it)
- Thin content scanner (configurable word count threshold, default 300)
- Empty taxonomy term detection
- Duplicate title/meta description finder
- Keyword cannibalization detection (multiple pages targeting same keyword)
- Auto-cluster detection (topic grouping across posts via keyword similarity)
- Dashboard with severity badges (critical/warning/info) and actionable fix suggestions
- Connected mode adds: SAG gap analysis, cluster health scoring
Classes: IGNY8_Intelligence_Module, IGNY8_Site_Audit, IGNY8_Orphan_Detector, IGNY8_Thin_Content, IGNY8_Empty_Terms, IGNY8_Cannibalization, IGNY8_Duplicate_Meta, IGNY8_Cluster_Detector, IGNY8_Gap_Analysis (connected), IGNY8_Cluster_Health (connected)
Methods: run_full_audit(), get_audit_results($args), get_orphan_pages(), get_thin_content(), detect_clusters($posts)
Options: igny8_intelligence_settings (JSON: audit schedule, thresholds, exclusions)
Database table:
{prefix}igny8_audit_results
id BIGINT AUTO_INCREMENT PRIMARY KEY
audit_type VARCHAR(50) NOT NULL -- orphan, thin, empty_term, cannibalization, duplicate_meta
post_id BIGINT NULL
term_id BIGINT NULL
severity VARCHAR(20) NOT NULL -- critical, warning, info
message TEXT NOT NULL
data LONGTEXT NULL -- JSON extra data
audit_date DATETIME NOT NULL
is_resolved TINYINT(1) DEFAULT 0
INDEX idx_type_date (audit_type, audit_date)
Module 6: Internal Linking
- Full site link crawl + link map stored in
{prefix}igny8_link_map - Per-post link audit: outbound count, inbound count, orphan status
- Link suggestions: "This post should link to X" based on content similarity
- Link equity visualization (which pages pass authority)
- Orphan content detection (pages with zero inbound internal links)
- Connected mode adds: auto-link insertion based on keyword rules from IGNY8
Classes: IGNY8_Linking_Module, IGNY8_Link_Auditor, IGNY8_Link_Suggestions, IGNY8_Orphan_Links, IGNY8_Link_Graph, IGNY8_Auto_Linker (connected), IGNY8_Link_Rules (connected)
Methods: crawl_links(), get_post_links($post_id), get_link_suggestions($post_id), get_orphan_pages(), auto_link_content($post_id) (connected)
Post meta: _igny8_related_links (JSON: [{post_id, anchor_text, priority}]), _igny8_link_suggestions (JSON)
Options: igny8_linking_settings (JSON: auto-link rules, max links per post)
Database table:
{prefix}igny8_link_map
id BIGINT AUTO_INCREMENT PRIMARY KEY
source_post_id BIGINT NOT NULL
target_post_id BIGINT NOT NULL
anchor_text VARCHAR(500) NULL
is_follow TINYINT(1) DEFAULT 1
link_position VARCHAR(20) NULL -- content, sidebar, footer
last_crawled DATETIME NOT NULL
INDEX idx_source (source_post_id)
INDEX idx_target (target_post_id)
Module 7: Google Search Console
- OAuth 2.0 connection flow to Google
- Search performance dashboard: clicks, impressions, CTR, avg position
- Keyword position tracking over time
- Date range filtering
- Top pages by performance
- Data stored locally for historical tracking
- Connected mode adds: URL Inspection API, indexing requests, status sync from IGNY8 backend
Classes: IGNY8_GSC_Module, IGNY8_GSC_Auth, IGNY8_GSC_Dashboard, IGNY8_GSC_Keywords, IGNY8_GSC_Indexing (connected), IGNY8_GSC_URL_Inspection (connected)
Methods: authorize_gsc(), get_search_metrics($args), get_keyword_positions($args), inspect_url($url) (connected), request_indexing($url) (connected)
Options: igny8_gsc_token (encrypted), igny8_gsc_property (selected GSC property URL)
Module 8: Socializer
- Pure CSS/JS share buttons (<5KB total, no external scripts)
- Position options: floating sidebar, above content, below content, inline
- Networks: Facebook, X/Twitter, LinkedIn, Pinterest, WhatsApp, Telegram, Email, Copy Link
- Social profile management (org social URLs)
- Share count display (optional, via API)
- Connected mode adds: auto-post on publish, Twitter API, Facebook Pages API, LinkedIn API, dynamic OG image generation
Classes: IGNY8_Socializer_Module, IGNY8_Share_Buttons, IGNY8_Social_Profiles, IGNY8_Auto_Poster (connected), IGNY8_Twitter_API (connected), IGNY8_Facebook_API (connected), IGNY8_LinkedIn_API (connected), IGNY8_OG_Image_Generator (connected)
Methods: render_share_buttons($post_id), get_social_profiles(), post_to_social($post_id) (connected)
Options: igny8_share_settings (JSON: networks, position, style), igny8_social_profiles
Frontend assets: share-buttons.css (<3KB), share-buttons.js (<2KB) — conditionally enqueued only when enabled
Module 9: Analytics + SMTP
- GA4 measurement ID connector (script injection via
wp_head) - Google Tag Manager container ID
- Facebook Pixel, TikTok Pixel, Pinterest Tag
- Custom header/footer scripts (with placement control)
- SMTP mail override (host, port, user, pass, encryption SSL/TLS)
- Email delivery log with status tracking
- Test email sender
Classes:
- Analytics:
IGNY8_Analytics_Module,IGNY8_GA_Connector,IGNY8_GTM_Connector,IGNY8_Pixel_Manager,IGNY8_Script_Manager - SMTP:
IGNY8_SMTP_Module,IGNY8_SMTP_Mailer,IGNY8_Email_Log,IGNY8_Email_Test
Options: igny8_analytics_settings (JSON: GA ID, GTM ID, pixel IDs, custom scripts), igny8_smtp_settings (JSON: host, port, user, pass, encryption, from_name, from_email)
Database table:
{prefix}igny8_email_log
id BIGINT AUTO_INCREMENT PRIMARY KEY
to_email VARCHAR(320) NOT NULL
subject VARCHAR(500) NOT NULL
status VARCHAR(20) NOT NULL -- sent, failed
error_message TEXT NULL
sent_at DATETIME NOT NULL
SMTP hooks: wp_mail (override), wp_mail_from, wp_mail_from_name
Module 10: Import (Migration)
- One-click import from: Yoast SEO, RankMath, All in One SEO
- Imports: focus keywords, SEO titles, meta descriptions, robots settings, redirects, schema settings
- Pre-import preview showing what will be migrated (dry run mode)
- Rollback capability (stores original values before overwrite)
Classes: IGNY8_Importer (base), IGNY8_Yoast_Importer, IGNY8_RankMath_Importer, IGNY8_AIOSEO_Importer
Meta key mapping (Yoast → IGNY8):
_yoast_wpseo_focuskw → _igny8_focus_keyword
_yoast_wpseo_title → _igny8_seo_title
_yoast_wpseo_metadesc → _igny8_meta_description
_yoast_wpseo_canonical → _igny8_canonical_url
_yoast_wpseo_meta-robots-noindex → _igny8_robots_index
_yoast_wpseo_opengraph-title → _igny8_og_title
_yoast_wpseo_opengraph-description → _igny8_og_description
Similar mappings for RankMath (rank_math_*) and AIOSEO (_aioseo_*).
3. Data Models & APIs (WordPress side):
6 custom database tables total (listed above under each module):
{prefix}igny8_redirects{prefix}igny8_404_log{prefix}igny8_link_map{prefix}igny8_audit_results{prefix}igny8_email_log{prefix}igny8_sync_queue(table created in standalone for connected mode readiness)
REST API endpoints (public, for theme + external consumers):
GET /wp-json/igny8/v1/related/{post_id}— related content linksGET /wp-json/igny8/v1/cluster/{cluster_id}— cluster content listGET /wp-json/igny8/v1/term/{term_id}/content— rich term contentGET /wp-json/igny8/v1/audit/summary— site audit resultsGET /wp-json/igny8/v1/structure/overview— site structure summary
4. Architecture:
igny8/
├── igny8.php # Plugin header, bootstrap, constants
├── readme.txt # WordPress.org readme
├── uninstall.php # Full cleanup on uninstall
├── includes/
│ ├── class-igny8.php # Main singleton class
│ ├── class-module-manager.php # Register/activate/deactivate modules
│ ├── class-api-client.php # IGNY8 SaaS API client (connected mode)
│ ├── class-connection.php # API key validation, connection status
│ ├── class-utils.php # Shared utilities
│ ├── class-rest-api.php # Plugin REST endpoints
│ ├── class-compatibility.php # Detect Yoast/RankMath conflicts
│ ├── modules/
│ │ ├── seo/ # Module 1 (9 class files)
│ │ ├── schema/ # Module 2 (12 class files)
│ │ ├── sitemap/ # Module 3 (6 class files)
│ │ ├── redirects/ # Module 4 (4 class files)
│ │ ├── site-intelligence/ # Module 5 (10 class files)
│ │ ├── linking/ # Module 6 (7 class files)
│ │ ├── gsc/ # Module 7 (6 class files)
│ │ ├── socializer/ # Module 8 (8 class files)
│ │ ├── analytics/ # Module 9a (5 class files)
│ │ ├── smtp/ # Module 9b (4 class files)
│ │ ├── content-sync/ # Module 11 [CONNECTED] (6 class files)
│ │ └── sag/ # Module 12 [CONNECTED] (6 class files)
│ ├── admin/
│ │ ├── class-admin-menu.php
│ │ ├── class-dashboard.php
│ │ ├── class-setup-wizard.php
│ │ ├── class-compatibility-notice.php
│ │ ├── views/ (wizard steps, dashboard, connect prompt)
│ │ └── assets/ (admin.css, admin.js, meta-box.css, meta-box.js)
│ ├── frontend/
│ │ ├── class-head-output.php # All <head> tag consolidation
│ │ ├── class-share-output.php # Share button rendering
│ │ └── assets/ (share-buttons.css, share-buttons.js)
│ ├── data/
│ │ ├── class-installer.php # Create all DB tables on activation
│ │ ├── class-migrator.php # Version-based migration handler
│ │ └── class-importer.php # SEO data importer
│ └── integrations/
│ ├── class-woocommerce.php # WooCommerce SEO + schema
│ └── class-theme-bridge.php # Communication with companion theme
└── languages/
└── igny8.pot # Translation template
Module Manager pattern:
- Each module:
register(),activate(),deactivate(),is_active(),boot() - Public API:
igny8()returns singleton,igny8()->seo->get_title(),igny8()->schema->get_json_ld(), etc. - All modules toggleable from Settings → Modules
Admin menu structure:
IGNY8 (top-level, dashicons-chart-area)
├── Dashboard (overview + quick actions)
├── SEO (meta box settings, title templates)
├── Schema (default types, organization settings)
├── Sitemaps (post type/taxonomy inclusion)
├── Redirects (CRUD + 404 monitor)
├── Site Intelligence (audit dashboard)
├── Internal Links (link map, suggestions)
├── Search Console (GSC dashboard)
├── Socializer (buttons, profiles)
├── Analytics (GA4, GTM, pixels)
├── SMTP (mail settings, log)
├── Import (migration wizard)
└── Settings (modules toggle, general settings)
Setup Wizard (6 steps, runs on first activation):
- Site Type — Blog, Business, eCommerce, Local Business, SaaS, Portfolio
- SEO Import — Detect existing Yoast/RankMath/AIOSEO, offer import
- Site Basics — Site name, Organization/Person, logo, title separator
- Social Profiles — Social URLs + default sharing image
- Connect to IGNY8 — API key (optional, clear skip button)
- Done — Summary, run first audit CTA
5. Performance Rules:
| Rule | Implementation |
|---|---|
| Zero CSS on frontend unless share buttons enabled | Conditional enqueue check |
| Zero JS on frontend unless interactive features | Conditional enqueue check |
All <head> output in single hook at priority 1 |
class-head-output.php consolidation |
| Schema as single JSON-LD block | class-schema-generator.php merges all types |
| Admin assets only on IGNY8 admin pages | get_current_screen() check |
| Meta box assets only on post editor | Screen check before enqueue |
| Site audit via WP Cron, never on page load | wp_schedule_event() weekly |
| Link crawl as background process | WP Cron, batch processing |
| Connected API calls never block page requests | WP Cron queue, async |
| Option reads via object cache | wp_cache_get/set wrapping |
6. WordPress.org Compliance:
- GPL v2+ license
- No phone-home without explicit user consent
- All user-facing strings translatable via
igny8text domain - Sanitize all inputs, escape all outputs
- Use WP APIs everywhere (Settings API, REST API, WP_Query)
- No direct database queries where WP functions exist
- Min requirements: WordPress 5.9+, PHP 7.4+
7. Build Sequence (10 phases):
- Phase 1 (Days 1-3): Foundation — skeleton, module manager, admin menu, setup wizard, DB tables, REST API base
- Phase 2 (Days 4-7): SEO Core — meta box, title tags, content analysis, OG, breadcrumbs, robots
- Phase 3 (Days 8-10): Schema + Sitemap + Redirects
- Phase 4 (Days 11-13): Site Intelligence (all audit types + dashboard)
- Phase 5 (Days 14-15): Internal Linking (crawl + map + suggestions)
- Phase 6 (Days 16-18): Socializer + Analytics/SMTP + GSC
- Phase 7 (Days 19-20): Import (Yoast, RankMath, AIOSEO)
- Phase 8-9: Reserved for connected mode (doc 03B)
- Phase 10 (Days 28-30): WordPress.org compliance, readme, screenshots, i18n
Cross-references: 02D (Linker internal — IGNY8 backend linking logic feeds plugin's linking module), 02G (Rich Schema — IGNY8 schema generation feeds plugin's schema module), 03B (connected mode extends this), 03C (theme consumes plugin API)
DOC 03B: wp-plugin-connected.md
File: V2-Execution-Docs/03B-wp-plugin-connected.md
Scope: 2 connected-mode modules that require an IGNY8 SaaS subscription. These extend the standalone plugin from 03A.
Depends On: 03A (standalone base required) + 01G (SAG health monitoring — blueprint data)
Source Material:
- temp/IGNY8-Project-Files/IGNY8-Plugin-Build-Plan.md
- temp/IGNY8-Project-Files/DocC-WordPress-Ecosystem-Dev-Guide.md
What to Cover:
1. Current State:
- WP Bridge v1.5.2 already does basic content sync
- v2 connected mode replaces and extends v1.5.2 capabilities
- Requires standalone plugin (03A) installed and active
2. What to Build — 2 Connected Modules:
Module 11: Content Sync
Content push from IGNY8 → WordPress with queue + review workflow.
Content Type Mapping:
| IGNY8 content_type | WP post_type | Notes |
|---|---|---|
| post | post | Default blog post |
| page | page | Standard page |
| product | product | Requires WooCommerce |
| service | service | Requires theme CPT |
| company_page | page | page-company template |
| taxonomy_landing | — | Written to term description (not a post) |
| cluster_hub | page | Landing page preset applied |
| comparison | post | Standard post with comparison structure |
| brand_page | page | Standard page |
Classes:
IGNY8_Sync_Module— module entry, webhook receiverIGNY8_Content_Puller— fetch content from IGNY8 SaaS APIIGNY8_Content_Mapper— map IGNY8 content_type → WP post_typeIGNY8_Image_Downloader— download AI images →wp_upload_dir(),wp_insert_attachment()IGNY8_Sync_Queue— sync queue DB table managementIGNY8_Publish_Scheduler— review queue, scheduled publishing workflow
Methods: push_content_to_queue($data), process_sync_queue(), map_content_type($igny8_type), create_post_from_content($data), download_images($content), schedule_publish($post_id, $date), get_review_queue()
Content Sync Flow:
IGNY8 SaaS publishes content
→ POST /wp-json/igny8/v1/sync/push
{igny8_content_id, content_type, title, content_html, excerpt,
featured_image, meta: {focus_keyword, secondary_keywords,
cluster_id, taxonomies: {service_category: [...], cluster: [...]}}}
→ Plugin creates igny8_sync_queue entry (status: pending)
→ WP Cron processes queue:
1. Download images → wp_upload_dir(), wp_insert_attachment()
2. Map content_type → WP post_type
3. wp_insert_post() or wp_update_post()
4. Set post meta (_igny8_content_id, _igny8_cluster_id, _igny8_sync_status)
5. wp_set_object_terms() for taxonomy assignment
6. Status: 'review' (manual mode) or 'synced' (auto-publish mode)
→ Plugin POSTs confirmation to IGNY8 /api/v1/integration/sync-events/
Database table:
{prefix}igny8_sync_queue
id BIGINT AUTO_INCREMENT PRIMARY KEY
igny8_content_id VARCHAR(100) NOT NULL
content_type VARCHAR(50) NOT NULL
sync_status VARCHAR(20) NOT NULL -- pending, synced, failed, review
wp_post_id BIGINT NULL
wp_term_id BIGINT NULL
data LONGTEXT NULL -- JSON payload from IGNY8
created_at DATETIME NOT NULL
synced_at DATETIME NULL
error_message TEXT NULL
INDEX idx_status (sync_status)
Post meta (connected mode):
_igny8_content_id -- int, links WP post to IGNY8 Content record
_igny8_cluster_id -- int, links WP post to IGNY8 SAGCluster
_igny8_sync_status -- pending/synced/failed/modified
_igny8_last_sync -- timestamp
_igny8_related_links -- JSON: [{post_id, anchor_text, priority}]
_igny8_link_suggestions -- JSON: AI-generated link suggestions
Hooks:
- Actions:
wp_scheduled_event(igny8_process_sync_queue),rest_api_init - Filters:
igny8_content_before_sync,igny8_post_mapped,igny8_sync_status_updated
Module 12: SAG Structure (Blueprint Sync)
Receive SAG blueprint → create taxonomies → create terms → map clusters → visualize.
Classes:
IGNY8_SAG_Module— module entryIGNY8_Blueprint_Sync— receive + cache SAG blueprint from IGNY8IGNY8_Taxonomy_Builder—register_taxonomy()from SAG attributesIGNY8_Term_Builder—wp_insert_term()from attribute values with hierarchyIGNY8_Cluster_Manager— map clusters → hub pages/termsIGNY8_Structure_Visualizer— visual site structure admin page
Methods: sync_blueprint($json), create_taxonomies_from_blueprint($bp), create_terms_from_blueprint($bp), map_cluster_to_page($cluster_id, $page_id), get_blueprint(), get_structure_overview()
SAG Blueprint Sync Flow:
IGNY8 confirms blueprint
→ POST /wp-json/igny8/v1/sag/sync-blueprint
{blueprint: {dimensions: [{id, name, slug, attributes: [{id, name, slug}]}],
clusters: [{id, name, dimension_ids, hub_page_id, recommended_content_count}]}}
→ Plugin stores in option igny8_sag_blueprint
→ Admin sees "Blueprint Review" notice
→ User clicks "Approve Blueprint":
1. Loop dimensions → register_taxonomy() if not exists
2. Loop attribute values → wp_insert_term() with parent hierarchy
3. Set term meta (_igny8_term_sag_attribute, _igny8_term_sag_level)
4. Loop clusters → create/link hub pages
→ POST confirmation back with {term_ids_map, hub_page_ids_map}
Term meta (connected mode, all _igny8_term_ prefixed):
_igny8_term_content -- rich HTML content for term landing page
_igny8_term_faq -- JSON: [{question, answer}]
_igny8_term_related_terms -- JSON: [term_id, term_id, ...]
_igny8_term_sag_attribute -- attribute name from SAG
_igny8_term_sag_level -- primary/secondary/tertiary
_igny8_term_cluster_id -- linked SAGCluster ID (int)
_igny8_term_igny8_id -- ID in IGNY8 platform (int)
_igny8_term_seo_title -- SEO title for term archive
_igny8_term_meta_description -- meta description for term archive
_igny8_term_robots_index -- index/noindex
_igny8_term_og_image -- OG image attachment ID
Options (connected mode):
igny8_api_key -- API key for IGNY8 SaaS (encrypted)
igny8_api_connected -- boolean
igny8_api_url -- base URL (default: https://api.igny8.com/api/v1/)
igny8_site_id -- IGNY8 Site record ID (int)
igny8_last_sync -- timestamp
igny8_sag_blueprint -- JSON: full blueprint data
REST endpoints (inbound from IGNY8, all validate X-IGNY8-API-KEY):
POST /wp-json/igny8/v1/sync/push -- content push
POST /wp-json/igny8/v1/sag/sync-blueprint -- blueprint sync
POST /wp-json/igny8/v1/sag/create-taxonomies -- taxonomy creation
POST /wp-json/igny8/v1/terms/{id}/content -- term content push
POST /wp-json/igny8/v1/schema/bulk-update -- schema JSON-LD bulk push
POST /wp-json/igny8/v1/gsc/status-sync -- GSC index statuses
POST /wp-json/igny8/v1/event -- webhook events
Endpoint payloads (documented with full request/response JSON):
POST /sync/push request:
{
"igny8_content_id": 12345,
"content_type": "post",
"title": "Content Title",
"content": "<p>HTML content...</p>",
"excerpt": "Short excerpt",
"featured_image": "https://cdn.igny8.com/image.jpg",
"meta": {
"focus_keyword": "main keyword",
"secondary_keywords": ["kw2", "kw3"],
"cluster_id": 123,
"taxonomies": {"service_category": ["emergency-plumbing"], "cluster": ["drain-services"]}
}
}
POST /sag/sync-blueprint request:
{
"blueprint": {
"dimensions": [
{"id": 1, "name": "Service Type", "slug": "service_type",
"attributes": [{"id": 1, "name": "Emergency Plumbing", "slug": "emergency-plumbing"}]}
],
"clusters": [
{"id": 1, "name": "Emergency Drain Cleaning", "dimension_ids": [1, 2],
"hub_page_id": null, "recommended_content_count": 12}
]
}
}
POST /terms/{id}/content request:
{
"term_id": 1001,
"content": "<p>HTML content for term landing page</p>",
"faq": [{"question": "Q1?", "answer": "A1"}],
"related_terms": [1002, 1003],
"meta": {"seo_title": "Custom title", "meta_description": "Custom description"}
}
POST /schema/bulk-update request:
{
"schemas": [
{"post_id": 123, "schema_type": "Article", "schema_data": {"@context": "https://schema.org", ...}}
]
}
POST /gsc/status-sync request:
{
"statuses": [
{"url": "https://example.com/post", "index_status": "Indexed",
"coverage_state": "Submitted and indexed", "last_checked": "2026-03-22T12:00:00Z"}
]
}
3. API Client (class-api-client.php):
- Handles all outbound requests to IGNY8 SaaS API
- Base URL from
igny8_api_urloption (default:https://api.igny8.com/api/v1/) - Authentication:
Authorization: Bearer {igny8_api_key} - Methods:
get($endpoint, $params),post($endpoint, $data),put($endpoint, $data),delete($endpoint) - Error handling: WP_Error wrapping, log failures
- Rate limiting: respect 429 responses with exponential backoff (1s → 2s → 4s → 8s)
- Connection test:
GET /api/v1/system/status/
4. Admin UI additions (connected mode):
IGNY8 (top-level)
├── ... (all standalone modules from 03A)
├── Content Sync (sync queue, review queue, settings, sync log)
└── SAG Structure (blueprint review, cluster manager, structure visualizer)
Cross-references: 03A (standalone base required), 01G (SAG health monitoring — blueprint data), 01A (SAG models — data source), 01D (setup wizard — blueprint generation triggers sync), 02B (taxonomy term content — generates content pushed via /terms/{id}/content)
DOC 03C: companion-theme.md
File: V2-Execution-Docs/03C-companion-theme.md
Scope: Full Site Editing (FSE) block theme optimized for IGNY8 + SAG architecture. 7 CPTs, 9 taxonomies, term landing page templates, cluster hub templates, 15 landing page section types, 50+ block patterns, 5 site-type starters, 6 interlinking display components.
Depends On: 03B (connected mode: term meta, blueprint data)
Source Material:
- temp/IGNY8-Project-Files/Theme-Build-Plan.md
- temp/IGNY8-Project-Files/DocC-WordPress-Ecosystem-Dev-Guide.md
What to Cover:
1. Current State:
- No IGNY8 companion theme exists
- Users use generic themes (Astra, GeneratePress, etc.)
- Plugin provides data (SEO, schema, links) but can't control template rendering
2. What to Build:
7 Custom Post Types:
CPT 1: service
- Archive enabled, supports: title, editor, thumbnail, excerpt, revisions, page-attributes
- Taxonomies: service_category, service_area, service_attribute, cluster
- Rewrite:
/services/%service_category%/%postname%/ - Templates:
single-service.html,archive-service.html - 10 meta fields:
_theme_service_price_range -- "$150 - $500" _theme_service_duration -- "2-4 hours" _theme_service_process_steps -- JSON: [{step_number, title, desc, icon}] _theme_service_outcomes -- JSON: [{title, description}] _theme_service_faqs -- JSON: [{question, answer}] _theme_service_cta_text -- button text _theme_service_cta_url -- button URL _theme_service_areas_served -- JSON: geographic areas _theme_service_gallery -- JSON: attachment IDs _theme_service_related_services -- JSON: post IDs
CPT 2: landing_page
- NO archive, does NOT support editor (section meta box instead)
- Rewrite:
/l/%postname%/ - Template:
single-landing_page.html - Section-based rendering from
_theme_landing_sectionsrepeater meta - 15 section types + 8 presets (detailed below)
CPT 3: portfolio
- Archive enabled, supports: title, editor, thumbnail, excerpt, revisions
- Taxonomies: portfolio_category, portfolio_tag, service_category (shared)
- Rewrite:
/portfolio/%portfolio_category%/%postname%/ - Templates:
single-portfolio.html,archive-portfolio.html - 8 meta fields:
_theme_portfolio_client -- client name _theme_portfolio_date -- YYYY-MM-DD _theme_portfolio_url -- live project URL _theme_portfolio_results -- JSON: [{metric, value, description}] _theme_portfolio_technologies -- comma-separated _theme_portfolio_testimonial_id -- linked testimonial post ID _theme_portfolio_gallery -- JSON: attachment IDs _theme_portfolio_before_after -- JSON: {before_img, after_img}
CPT 4: team_member
- Archive enabled (team page), supports: title, editor, thumbnail
- Rewrite:
/team/%postname%/ - Templates:
single-team-member.html,archive-team-member.html - 6 meta fields:
_theme_team_position, _theme_team_email, _theme_team_phone, _theme_team_social (JSON: {linkedin, twitter, facebook, website}), _theme_team_order (int), _theme_team_department
CPT 5: testimonial
- Public: false (displayed via blocks/shortcodes only, no individual pages)
- Supports: title, editor, thumbnail
- 8 meta fields:
_theme_testimonial_author_name, _theme_testimonial_author_title, _theme_testimonial_company, _theme_testimonial_rating (1-5 int), _theme_testimonial_image (attachment ID), _theme_testimonial_featured (bool), _theme_testimonial_service_id (linked service), _theme_testimonial_product_id
CPT 6: faq
- Archive enabled, supports: title, editor (title=question, editor=answer)
- Taxonomies: faq_category, cluster
- Rewrite:
/faq/%faq_category%/%postname%/ - Templates:
single-faq.html,archive-faq.html - 2 meta fields:
_theme_faq_order(int),_theme_faq_schema_enabled(bool)
CPT 7: documentation
- Archive enabled, hierarchical (parent/child docs)
- Supports: title, editor, thumbnail, page-attributes
- Taxonomies: doc_category
- Rewrite:
/docs/%doc_category%/%postname%/ - Templates:
single-documentation.html,archive-documentation.html - 4 meta fields:
_theme_doc_sidebar_enabled (bool), _theme_doc_toc_enabled (bool), _theme_doc_last_reviewed (date), _theme_doc_related_docs (JSON: post IDs)
Note: WooCommerce taxonomies (product_cat, product_tag, pa_*) are NOT registered by theme. Theme provides rich templates for them. Theme registers cluster for product post type.
9 Custom Taxonomies:
| # | Slug | For CPTs | Hierarchical | SAG Mapping | Rewrite |
|---|---|---|---|---|---|
| 1 | service_category |
service, portfolio | yes | Primary attribute | /services/%postname%/ |
| 2 | service_area |
service | yes | Tertiary (geographic) | /area/%postname%/ |
| 3 | service_attribute |
service | no | Secondary attributes | /attribute/%postname%/ |
| 4 | portfolio_category |
portfolio | yes | — | /portfolio/%postname%/ |
| 5 | portfolio_tag |
portfolio | no | — | /tag/%postname%/ |
| 6 | faq_category |
faq | yes | Cluster assignment | /faq/%postname%/ |
| 7 | doc_category |
documentation | yes | — | /docs/%postname%/ |
| 8 | cluster |
post, page, service, faq, product | no | Core cluster assignment | /topic/%postname%/ |
| 9 | topic_tag |
post, service, faq, documentation | no | Granular tagging | /topic/%postname%/ |
Term Landing Page Templates (7-section structure): Every taxonomy term archive renders as a rich landing page:
- Term Hero — H1 (term name), description (from
_igny8_term_contentif active), breadcrumbs, post count - Key Subtopics — grid of child term cards (if hierarchical + children exist)
- Content Grid — posts/services/products in term, filterable, paginated, layout options (grid 2/3/4 col, list)
- Related Terms — sibling terms or
_igny8_term_related_terms - Cluster Cross-Links — related clusters sharing dimensional axes (if IGNY8 connected)
- FAQ Section — accordion from
_igny8_term_faqor matching faq_category posts - CTA — configurable per term or global default
Cluster Hub Template (taxonomy-cluster.html):
- Cluster hero (H1, description, dimensional breadcrumb, content count)
- Hub content (pillar article from
_igny8_term_content) - Supporting content grid (posts/services/products grouped by type)
- Attribute navigation (browse intersecting attributes)
- Related clusters (cross-linking via SAG data)
- FAQ (cluster-specific)
- CTA
6 Interlinking Display Components (template parts):
parts/related-content.html— after post content, reads_igny8_related_links, fallback to category match, 3-4 cardsparts/cluster-navigation.html— readsigny8()->linking->get_cluster_navigation(), fallback to same cluster termparts/attribute-browse.html— term archive sidebar, pills/tags of browsable attribute valuesparts/breadcrumbs.html— readsigny8()->seo->get_breadcrumbs()or theme fallback, SAG-aware dimensional pathparts/term-quick-links.html— single post sidebar/footer, all terms assigned to post grouped by taxonomyparts/child-term-grid.html— term archive, card grid with term image/name/description/post count
Landing Page System (15 section types):
hero— headline, subheadline, CTA, background image/video/gradientfeatures-grid— columns 2/3/4, items: icon/title/descriptionhow-it-works— numbered steps: title/description/iconsocial-proof— testimonials: grid/slider/single layoutpricing— billing toggle monthly/annual, plans: features/price/CTAfaq— Q&A items, schema_enabled option for FAQPage JSON-LDcta-band— headline, subheadline, CTA, background colorscontent-block— title, WYSIWYG editor, image left/right, backgroundstats-counter— stats: number/suffix/label, animated countersteam— from team_member CPT or manual entriesportfolio-grid— from portfolio CPTcontact-form— form shortcode, optional map, address blockvideo-embed— URL, poster image, autoplay, full-width optionscomparison-table— columns, rows, highlight column optionlogo-bar— logo images, grid or horizontal scroll
Section template files in inc/landing-pages/sections/: one .php per section type.
8 Landing Page Presets:
- SaaS Product: hero → logo-bar → features → how-it-works → social-proof → pricing → faq → cta
- Service Business: hero → features → content → stats → social-proof → team → contact-form → cta
- Product Launch: hero → content → features → video → social-proof → pricing → faq → cta
- Lead Generation: hero → features → social-proof → cta
- Portfolio/Agency: hero → portfolio → how-it-works → social-proof → stats → contact-form
- Event/Webinar: hero → content → features → social-proof → faq → cta
- Cluster Hub: hero → content → features → faq → cta
- Term Landing: hero → content → features → social-proof → faq → cta
50+ Block Patterns (by category):
- Heroes (4): hero-centered, hero-split, hero-video-bg, hero-slider
- Content (4): features-3col, features-alternating, how-it-works, benefits-icons
- Social Proof (4): testimonials-grid, testimonials-slider, logo-bar, stats-row
- Conversion (4): cta-simple, cta-with-form, pricing-section, newsletter-signup
- Services (3): service-cards, service-list, service-with-sidebar
- Portfolio (3): portfolio-grid, portfolio-masonry, case-study-layout
- Footers (3): footer-4col, footer-centered, footer-minimal
- 13+ custom block patterns: pricing-table, feature-grid, testimonial-slider, stats-counter, team-grid, faq-accordion, cta-banner, logo-carousel, comparison-table, icon-box, service-grid, portfolio-showcase, doc-sidebar
13 Custom Gutenberg Blocks (in inc/blocks/):
- pricing-table, 2. feature-grid, 3. testimonial-slider, 4. stats-counter, 5. team-grid, 6. faq-accordion, 7. cta-banner, 8. logo-carousel, 9. comparison-table, 10. icon-box, 11. service-grid (CPT-powered), 12. portfolio-showcase (CPT-powered), 13. doc-sidebar (documentation nav)
5 Site-Type Starter Templates (with demo content):
- Blog — front-page, single.html, archive.html
- SaaS — front-page, page-features.html, page-pricing.html, page-docs.html
- Corporate — front-page, page-about.html, page-services.html, page-contact.html
- eCommerce — front-page, archive-product.html, single-product.html
- Portfolio — front-page, archive-portfolio.html, single-portfolio.html
Each includes full template files, sample CPT entries, sample taxonomy terms, demo images.
3. Theme Architecture:
FSE block theme structure:
igny8-theme/
├── style.css, theme.json, functions.php
├── assets/ (css/, js/, fonts/, images/)
├── inc/
│ ├── setup.php -- theme supports, menus, sidebars, image sizes
│ ├── cleanup.php -- remove WP bloat (emojis, embeds, etc.)
│ ├── enqueue.php -- conditional CSS/JS loading
│ ├── template-tags.php -- custom template tags
│ ├── breadcrumbs.php -- theme breadcrumb fallback (when plugin not active)
│ ├── walkers.php -- custom nav walkers
│ ├── customizer.php -- logo, colors, fonts, layout, social URLs, footer text
│ ├── theme-bridge.php -- communication layer with IGNY8 plugin
│ ├── cpt/ -- register.php + 7 per-CPT files
│ ├── taxonomies/ -- register.php + 9 per-taxonomy files
│ ├── meta-fields/ -- class-meta-box-base.php + per-CPT meta handlers
│ ├── landing-pages/ -- register-cpt.php, meta-boxes.php, presets.php, render.php, sections/
│ ├── interlinking/ -- 6 component files (related-content, cluster-nav, etc.)
│ ├── blocks/ -- 13 custom block registrations
│ └── patterns/ -- register.php + category folders
├── templates/ -- FSE templates (20+ template files)
│ ├── index.html, home.html, single.html, page.html, archive.html
│ ├── single-service.html, single-portfolio.html, single-landing_page.html, single-documentation.html
│ ├── archive-service.html, archive-portfolio.html, archive-faq.html, archive-documentation.html
│ ├── taxonomy-service_category.html, taxonomy-service_area.html, taxonomy-service_attribute.html
│ ├── taxonomy-cluster.html, taxonomy-faq_category.html
│ ├── taxonomy-product_cat.html, taxonomy-product_tag.html (WooCommerce)
│ ├── search.html, 404.html
│ └── starters/ (5 starter template sets)
├── parts/ -- FSE template parts (20+ parts)
│ ├── header.html, header-transparent.html, header-minimal.html
│ ├── footer.html, footer-minimal.html
│ ├── sidebar.html, sidebar-docs.html
│ ├── post-meta.html, author-box.html, comments.html, pagination.html
│ ├── related-content.html, cluster-navigation.html, attribute-browse.html
│ ├── breadcrumbs.html, term-quick-links.html, child-term-grid.html
│ ├── term-hero.html, term-content.html, term-faq.html
│ └── (additional parts)
└── woocommerce/ -- WooCommerce template overrides
├── archive-product.php, single-product.php
├── taxonomy-product_cat.php
├── content-product.php
├── cart/, checkout/, myaccount/ overrides
Design System (theme.json):
- Colors: Primary palette (primary, primary-light, primary-dark, primary-accent), Neutral (background, surface, text, text-secondary, border), Semantic (success, warning, error, info)
- Typography: Heading + body font pairings from curated list, sizes: xs, sm, base, lg, xl, 2xl, 3xl, 4xl
- Spacing scale: xs (0.25rem), sm (0.5rem), base (1rem), lg (1.5rem), xl (2rem), 2xl (3rem), 3xl (4rem)
- Border radius: none, sm, base, lg, full
- Custom tokens for term pages and interlinking components
- CSS approach: BEM naming
.tn-block__element--modifier, <35KB gzipped total - JS: ES6+, vanilla (no jQuery on frontend), <15KB gzipped
Performance targets: FCP <1.0s, LCP <1.5s, TBT <50ms, CLS <0.05, PageSpeed Insights 95+ mobile
4. Plugin Integration (graceful degradation):
- Theme checks
function_exists('igny8')before calling any plugin API - Without plugin: theme breadcrumbs, basic related content by category, no SAG features
- With plugin standalone: SEO breadcrumbs, schema, link suggestions, share buttons
- With plugin connected: full SAG term pages, cluster navigation, blueprint visualization, rich term content
5. WooCommerce Integration (when active):
- Product cluster taxonomy support (register
clusterforproductpost type) - Rich category pages following term landing structure
- Product attribute support in templates
- Integration with IGNY8 schema (Product schema type)
- Template overrides: archive-product, single-product, taxonomy-product_cat, content-product
Cross-references: 03A (plugin API: igny8() singleton), 03B (connected mode: term meta, blueprint data), 01A (SAGCluster → cluster taxonomy), 01B (SAGAttribute → service_category/service_attribute/service_area mapping)
DOC 03D: toolkit-plugin.md
File: V2-Execution-Docs/03D-toolkit-plugin.md
Scope: Separate utility plugin with 5 infrastructure modules. Independent from main IGNY8 plugin but complements the companion theme.
Depends On: 03C (companion theme is the primary consumer)
Source Material:
- temp/IGNY8-Project-Files/IGNY8-Plugin-Build-Plan.md (Toolkit section)
- temp/IGNY8-Project-Files/DocC-WordPress-Ecosystem-Dev-Guide.md
What to Cover:
1. Current State:
- No toolkit plugin exists
- Users rely on multiple plugins: WP Super Cache, Contact Form 7, Wordfence, WP Mail SMTP, etc.
- Goal: reduce plugin count with a single, lightweight toolkit
2. What to Build — 5 Modules:
Module 1: Performance
- Page cache (file-based, auto-purge on post update via
save_posthook) - HTML minification (remove whitespace, comments)
- Asset optimizer (combine/minify CSS+JS with exclusion rules)
- Image optimizer (WebP conversion via GD/Imagick, lazy loading, responsive srcset)
- Critical CSS generation (extract above-fold CSS)
- Browser cache headers (expires, cache-control via
.htaccessorsend_headers) - Preload/prefetch for key resources (
<link rel="preload">) - Gzip compression check
- Database optimizer (clean transients, revisions, spam comments)
Classes: Toolkit_Performance_Module, Toolkit_Page_Cache, Toolkit_Asset_Optimizer, Toolkit_Image_Optimizer, Toolkit_Critical_CSS, Toolkit_HTML_Minifier, Toolkit_Browser_Cache, Toolkit_Preload, Toolkit_Database_Optimizer
Free: page cache (basic), HTML minification Premium: full asset optimizer, image optimization + WebP, critical CSS, browser cache, preload, DB optimizer
Database table:
{prefix}igny8_toolkit_cache_stats
id BIGINT AUTO_INCREMENT PRIMARY KEY
hits INT DEFAULT 0
misses INT DEFAULT 0
purges INT DEFAULT 0
last_purge DATETIME NULL
Module 2: Forms
- Drag-and-drop form builder (admin only, not Gutenberg block — simpler)
- Field types: text, email, textarea, select, checkbox, radio, file upload, hidden, number, date
- Submissions handler: store in DB + email notification
- Anti-spam: honeypot field + basic token validation (no external service)
- Entries admin page: view, export CSV, delete
- Conditional logic (premium): show/hide fields based on other field values
- Multi-step forms (premium)
- Shortcode
[igny8_form id="X"]+ block for embedding
Classes: Toolkit_Forms_Module, Toolkit_Form_Builder, Toolkit_Form_Renderer, Toolkit_Form_Processor, Toolkit_Form_Notifications, Toolkit_Form_Entries, Toolkit_Form_AntiSpam
Free: basic builder (5 field types: text, email, textarea, select, checkbox), simple rendering Premium: all field types, conditional logic, multi-step, submissions dashboard
Database table:
{prefix}igny8_toolkit_submissions
id BIGINT AUTO_INCREMENT PRIMARY KEY
form_id INT NOT NULL
data LONGTEXT NOT NULL -- JSON form field values
ip_hash VARCHAR(64) NULL
user_agent VARCHAR(500) NULL
created_at DATETIME NOT NULL
INDEX idx_form (form_id)
Module 3: Security
- Login protection: limit login attempts (default 5), lockout duration (default 15min), whitelist IPs
- Basic firewall: block known bad user agents, block PHP execution in uploads dir
- WordPress hardening: disable XML-RPC, disable file editor (
DISALLOW_FILE_EDIT), hide WP version, security headers (X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy) - Audit log: track login attempts, settings changes, plugin activations, user role changes
- 2FA via email code (premium)
- IP allowlist/blocklist (premium)
Classes: Toolkit_Security_Module, Toolkit_Login_Protection, Toolkit_Firewall, Toolkit_Hardening, Toolkit_Headers, Toolkit_Audit_Log
Free: basic login protection, file editor disable, security headers Premium: advanced firewall, 2FA, full audit logging, IP management
Database table:
{prefix}igny8_toolkit_audit_log
id BIGINT AUTO_INCREMENT PRIMARY KEY
event_type VARCHAR(50) NOT NULL -- login_success, login_failed, settings_change, plugin_activated, etc.
user_id BIGINT NULL
object_type VARCHAR(50) NULL -- post, user, plugin, option
object_id BIGINT NULL
details LONGTEXT NULL -- JSON extra data
ip VARCHAR(45) NULL
created_at DATETIME NOT NULL
INDEX idx_event (event_type, created_at)
Module 4: SMTP
- For sites NOT using the IGNY8 plugin (if both installed, this module defers to IGNY8's SMTP)
- SMTP mail override: host, port, username, password, encryption (SSL/TLS)
- Email delivery log with status tracking
- Test email sender
- From name + from email override
Classes: Toolkit_SMTP_Module, Toolkit_SMTP_Mailer, Toolkit_Email_Log, Toolkit_Email_Test
Free: basic SMTP override, mail sending Premium: email delivery log, templates, resend failed, analytics
Database table:
{prefix}igny8_toolkit_email_log
id BIGINT AUTO_INCREMENT PRIMARY KEY
to_email VARCHAR(320) NOT NULL
subject VARCHAR(500) NOT NULL
status VARCHAR(20) NOT NULL -- sent, failed
error_message TEXT NULL
sent_at DATETIME NOT NULL
Module 5: WooCommerce Enhancements
- Quick view modal on shop/archive pages
- Wishlist (cookie-based for guests, user meta for logged in)
- AJAX add-to-cart on archive pages
- Product filters (price range, attributes, categories) with AJAX
- Gallery enhancement (zoom, lightbox, thumbnails)
Classes: Toolkit_WooCommerce_Module, Toolkit_Quick_View, Toolkit_Wishlist, Toolkit_AJAX_Cart, Toolkit_Product_Filters, Toolkit_Product_Gallery
Entirely premium — WooCommerce enhancements only available in paid version.
3. Architecture:
igny8-toolkit/
├── igny8-toolkit.php # Plugin header, module loader
├── readme.txt
├── includes/
│ ├── class-toolkit.php # Main singleton class
│ ├── class-module-manager.php # Module toggle (same pattern as main plugin)
│ ├── modules/
│ │ ├── performance/ # Module 1 (9 class files)
│ │ ├── forms/ # Module 2 (7 class files)
│ │ ├── security/ # Module 3 (6 class files)
│ │ ├── smtp/ # Module 4 (4 class files)
│ │ └── woocommerce/ # Module 5 (6 class files)
│ └── admin/
│ ├── class-dashboard.php
│ └── views/ (dashboard template)
├── admin/ (CSS, JS for admin)
├── frontend/ (CSS, JS for frontend)
└── languages/ (i18n)
Each module: independent toggle, zero impact when disabled. Module manager same pattern as main IGNY8 plugin (register(), activate(), deactivate(), is_active(), boot()).
4 database tables total:
{prefix}igny8_toolkit_submissions— form submissions{prefix}igny8_toolkit_email_log— SMTP email log{prefix}igny8_toolkit_audit_log— security audit log{prefix}igny8_toolkit_cache_stats— performance cache stats
Cross-references: 03C (companion theme is the primary consumer), 03A (if both plugins installed, SMTP module defers to main plugin's SMTP)
BUILD SEQUENCE
Claude Code builds these docs in order:
Phase 3 Doc Build Order
═══════════════════════
1. 03A — WP Plugin Standalone (10 modules)
Foundation: standalone plugin is the base everything else extends/consumes
2. 03B — WP Plugin Connected (2 modules)
Extends 03A with IGNY8 SaaS integration
3. 03C — Companion Theme
Depends on plugin API from 03A/03B
4. 03D — Toolkit Plugin
Independent but complements theme, built last
For each doc:
- Read this plan's section for that doc
- Read the source files listed in "Source Material"
- Read the relevant existing V2 docs referenced in "Cross-references"
- Write the doc following the DOC STRUCTURE STANDARD
- Verify all IDs from IGNY8 backend are integers (BigAutoField, not UUIDs)
- Verify all IGNY8 model references use PLURAL names (Clusters, Keywords, Tasks, etc.)
- Verify all frontend references use .tsx + Zustand
- Verify all WP-side code follows WordPress coding standards
- Save to
V2-Execution-Docs/03X-filename.md
SOURCE FILES TO READ
Before writing ANY Phase 3 doc, read these source files:
temp/IGNY8-Project-Files/IGNY8-Plugin-Build-Plan.md
temp/IGNY8-Project-Files/Theme-Build-Plan.md
temp/IGNY8-Project-Files/DocC-WordPress-Ecosystem-Dev-Guide.md
Also read the master baseline:
V2-Execution-Docs/00-MASTER-EXECUTION-PLAN.md
And the relevant Phase 1/2 docs for cross-references:
V2-Execution-Docs/01A-sag-data-foundation.md (SAG models)
V2-Execution-Docs/01D-setup-wizard-case2-new-site.md (wizard triggers blueprint sync)
V2-Execution-Docs/01G-sag-health-monitoring.md (health scoring context)
V2-Execution-Docs/02D-linker-internal.md (linking logic feeds plugin)
V2-Execution-Docs/02G-rich-schema-serp.md (schema generation feeds plugin)
OUTPUT LOCATION
Write all 4 docs to:
V2-Execution-Docs/