# IGNY8 Phase 3: WordPress Plugin — Standalone SEO (03A) ## 10-Module Free SEO Plugin for WordPress **Document Version:** 1.0 **Date:** 2026-03-23 **Phase:** IGNY8 Phase 3 — WordPress Ecosystem **Status:** Build Ready **Source of Truth:** Codebase at `/data/app/igny8/` **Audience:** Claude Code, WordPress Developers, Architects --- ## 1. CURRENT STATE ### Existing WordPress Integration The IGNY8 WordPress Bridge Plugin v1.5.2 exists at `/data/app/igny8/plugins/wordpress/source/igny8-wp-bridge/`. It provides: - Content sync from IGNY8 SaaS → WordPress via `POST /wp-json/igny8/v1/sync/push` - SAG blueprint sync via `POST /wp-json/igny8/v1/sag/sync-blueprint` - Taxonomy creation via `POST /wp-json/igny8/v1/sag/create-taxonomies` - API key authentication using `X-IGNY8-API-KEY` header - REST namespace: `/wp-json/igny8/v1/` ### What Does NOT Exist - No standalone SEO capabilities (users rely on Yoast/RankMath alongside IGNY8) - No schema generation, sitemap control, redirect management, or site audit - No internal link mapping or social sharing features - No analytics connector or SMTP mail management - No migration path from competing plugins ### Phase 2 Foundation Available - 02D Linker Internal: SAGLink model and link scoring logic in IGNY8 backend — feeds the plugin's internal linking module in connected mode - 02G Rich Schema SERP: 10 JSON-LD schema types and schema validation in IGNY8 backend — feeds the plugin's schema module in connected mode ### What v2 Changes Phase 3 builds a **completely new plugin** (not a patch to v1.5.2). The v1.5.2 bridge becomes deprecated once v2 is deployed. The new plugin works in two modes: - **Standalone mode** (this doc): Full free SEO plugin — no IGNY8 subscription required - **Connected mode** (03B): Extends standalone with IGNY8 SaaS integration --- ## 2. WHAT TO BUILD ### Overview A comprehensive WordPress SEO plugin with 10 standalone modules that function without an IGNY8 SaaS subscription. Each module is independently toggleable from Settings → Modules. The plugin replaces Yoast SEO, RankMath, or All in One SEO as a complete, free alternative. ### Plugin Identity - **Plugin Name:** IGNY8 - **Text Domain:** `igny8` - **REST Namespace:** `/wp-json/igny8/v1/` - **Option Prefix:** `igny8_` - **Post Meta Prefix:** `_igny8_` - **Term Meta Prefix:** `_igny8_term_` - **Table Prefix:** `{wp_prefix}igny8_` - **Min Requirements:** WordPress 5.9+, PHP 7.4+ - **License:** GPL v2+ - **Public API:** `igny8()` returns main singleton — e.g., `igny8()->seo->get_title()`, `igny8()->schema->get_json_ld()` ### Module 1: SEO Core **Purpose:** Focus keyword management, title/meta tag control, content analysis, Open Graph, breadcrumbs, and robots meta — the foundation of on-page SEO. **Classes:** | Class | File | Purpose | |-------|------|---------| | `IGNY8_SEO_Module` | `modules/seo/class-seo-module.php` | Module bootstrap, hook registration | | `IGNY8_Meta_Box` | `modules/seo/class-meta-box.php` | Post editor meta box UI + save handler | | `IGNY8_Title_Tag` | `modules/seo/class-title-tag.php` | `` management via `document_title_parts` filter | | `IGNY8_Meta_Tags` | `modules/seo/class-meta-tags.php` | Output `<meta>` description, robots, canonical in `<head>` | | `IGNY8_Content_Analysis` | `modules/seo/class-content-analysis.php` | Real-time SEO scoring in admin JS | | `IGNY8_Breadcrumbs` | `modules/seo/class-breadcrumbs.php` | Breadcrumb HTML generation + BreadcrumbList schema | | `IGNY8_OpenGraph` | `modules/seo/class-opengraph.php` | OG + Twitter Card meta tags | | `IGNY8_Robots_Txt` | `modules/seo/class-robots-txt.php` | Virtual robots.txt manager | | `IGNY8_Verification` | `modules/seo/class-verification.php` | Webmaster verification code output | **Features:** - Focus keyword per post/page/product (primary + secondary keywords array) - SEO title + meta description editor with live SERP preview - Content analysis: keyword density, heading structure, readability (Flesch-Kincaid) - Title tag templates per post type, taxonomy, author, and date archives - Breadcrumbs via shortcode `[igny8_breadcrumbs]` + function `igny8()->seo->get_breadcrumbs()` - Open Graph meta tags (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) - Consolidated `wp_head` output at priority 1 — single hook for all `<title>`, meta, OG, robots, canonical, schema **Post Meta Keys:** ``` _igny8_focus_keyword -- string: primary focus keyword _igny8_secondary_keywords -- JSON array: additional target keywords _igny8_seo_title -- string: custom SEO title _igny8_meta_description -- string: custom meta description _igny8_canonical_url -- string: canonical URL override _igny8_robots_index -- string: index/noindex _igny8_robots_follow -- string: follow/nofollow _igny8_og_title -- string: OG title override _igny8_og_description -- string: OG description override _igny8_og_image -- int: attachment ID for OG image _igny8_twitter_title -- string: Twitter title override _igny8_twitter_description -- string: Twitter description override _igny8_seo_score -- int: 0-100 overall SEO score _igny8_content_score -- int: 0-100 content quality score _igny8_readability_score -- float: Flesch-Kincaid readability _igny8_last_analysis -- string: ISO timestamp of last analysis ``` **Term Meta Keys:** ``` _igny8_term_seo_title -- string: term archive SEO title _igny8_term_meta_description -- string: term archive meta description _igny8_term_robots_index -- string: index/noindex _igny8_term_og_image -- int: attachment ID ``` **Options:** ``` igny8_seo_settings -- JSON: {title_templates: {...}, separator: " | ", defaults: {...}} igny8_social_profiles -- JSON: {facebook, twitter, linkedin, youtube, instagram, pinterest} ``` **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` ### Module 2: Schema (JSON-LD) **Purpose:** Automatic and customizable structured data markup for rich search results. **Classes:** | Class | File | Purpose | |-------|------|---------| | `IGNY8_Schema_Module` | `modules/schema/class-schema-module.php` | Module bootstrap | | `IGNY8_Schema_Generator` | `modules/schema/class-schema-generator.php` | Main dispatcher, merges all types | | `IGNY8_Schema_Article` | `modules/schema/class-schema-article.php` | Article/BlogPosting schema | | `IGNY8_Schema_LocalBusiness` | `modules/schema/class-schema-local-business.php` | LocalBusiness schema | | `IGNY8_Schema_Product` | `modules/schema/class-schema-product.php` | Product schema (WooCommerce) | | `IGNY8_Schema_FAQ` | `modules/schema/class-schema-faq.php` | FAQPage schema | | `IGNY8_Schema_HowTo` | `modules/schema/class-schema-howto.php` | HowTo schema | | `IGNY8_Schema_Organization` | `modules/schema/class-schema-organization.php` | Organization/Person | | `IGNY8_Schema_WebPage` | `modules/schema/class-schema-webpage.php` | WebPage/CollectionPage | | `IGNY8_Schema_Breadcrumb` | `modules/schema/class-schema-breadcrumb.php` | BreadcrumbList | | `IGNY8_Schema_Service` | `modules/schema/class-schema-service.php` | Service schema | | `IGNY8_Schema_Custom` | `modules/schema/class-schema-custom.php` | Raw JSON-LD editor | **Features:** - Auto-detect schema type per post type - 10 supported types: Article/BlogPosting, Organization/Person, WebPage/CollectionPage, BreadcrumbList, FAQPage, HowTo, LocalBusiness, Service, Product (WooCommerce), WebSite+SearchAction - Custom schema editor (raw JSON-LD input) - 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) **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) **Purpose:** XML sitemaps with image support and search engine notification. **Classes:** | Class | File | Purpose | |-------|------|---------| | `IGNY8_Sitemap_Module` | `modules/sitemap/class-sitemap-module.php` | Module bootstrap | | `IGNY8_Sitemap_Index` | `modules/sitemap/class-sitemap-index.php` | Sitemap index file | | `IGNY8_Sitemap_Posts` | `modules/sitemap/class-sitemap-posts.php` | Post type sub-sitemaps | | `IGNY8_Sitemap_Taxonomies` | `modules/sitemap/class-sitemap-taxonomies.php` | Taxonomy sub-sitemaps | | `IGNY8_Sitemap_Images` | `modules/sitemap/class-sitemap-images.php` | Image sitemap | | `IGNY8_Sitemap_XSL` | `modules/sitemap/class-sitemap-xsl.php` | XSL stylesheet for browser view | **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 ``` **Features:** - Sitemap index + sub-sitemaps per post type and taxonomy - Image sitemaps - XSL stylesheet for human-readable browser view - Respects noindex settings from SEO Core module - Auto-ping search engines on update - Exclusion rules (specific posts, taxonomies) **Options:** `igny8_sitemap_settings` — JSON: `{included_post_types, included_taxonomies, excluded_urls}` **Hooks:** `igny8_sitemap_post_types`, `igny8_sitemap_taxonomies`, `igny8_sitemap_excluded_urls` ### Module 4: Redirects **Purpose:** 301/302/307 redirect management with 404 monitoring and auto-redirect on slug changes. **Classes:** | Class | File | Purpose | |-------|------|---------| | `IGNY8_Redirects_Module` | `modules/redirects/class-redirects-module.php` | Module bootstrap | | `IGNY8_Redirect_Manager` | `modules/redirects/class-redirect-manager.php` | CRUD + matching engine | | `IGNY8_404_Monitor` | `modules/redirects/class-404-monitor.php` | 404 logging with hit counts | | `IGNY8_Auto_Redirect` | `modules/redirects/class-auto-redirect.php` | Auto-redirect on slug change via `post_updated` | **Features:** - 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_updated` hook - CSV import/export - Regex redirect support (advanced) - One-click redirect creation from 404 log **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: true}` **Database Table: `{prefix}igny8_redirects`** ```sql CREATE TABLE {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, 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)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` **Database Table: `{prefix}igny8_404_log`** ```sql CREATE TABLE {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, hits INT DEFAULT 1, first_hit DATETIME NOT NULL, last_hit DATETIME NOT NULL, is_resolved TINYINT(1) DEFAULT 0, redirect_id BIGINT NULL, INDEX idx_url (url(191)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` ### Module 5: Site Intelligence **Purpose:** Automated site audit with orphan page detection, thin content scanning, duplicate meta finder, and keyword cannibalization detection. **Classes:** | Class | File | Purpose | |-------|------|---------| | `IGNY8_Intelligence_Module` | `modules/site-intelligence/class-intelligence-module.php` | Module bootstrap | | `IGNY8_Site_Audit` | `modules/site-intelligence/class-site-audit.php` | Full audit runner | | `IGNY8_Orphan_Detector` | `modules/site-intelligence/class-orphan-detector.php` | Pages with no inbound links | | `IGNY8_Thin_Content` | `modules/site-intelligence/class-thin-content.php` | Below threshold word count | | `IGNY8_Empty_Terms` | `modules/site-intelligence/class-empty-terms.php` | Taxonomy terms with 0 posts | | `IGNY8_Cannibalization` | `modules/site-intelligence/class-cannibalization.php` | Multiple pages targeting same keyword | | `IGNY8_Duplicate_Meta` | `modules/site-intelligence/class-duplicate-meta.php` | Duplicate title/description finder | | `IGNY8_Cluster_Detector` | `modules/site-intelligence/class-cluster-detector.php` | Topic grouping via keyword similarity | | `IGNY8_Gap_Analysis` | `modules/site-intelligence/class-gap-analysis.php` | SAG gap analysis (connected mode only) | | `IGNY8_Cluster_Health` | `modules/site-intelligence/class-cluster-health.php` | Cluster health scoring (connected mode only) | **Features:** - Site audit runner via 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 (from 01G) **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: {thin_content_min: 300}, exclusions}` **Database Table: `{prefix}igny8_audit_results`** ```sql CREATE TABLE {prefix}igny8_audit_results ( id BIGINT AUTO_INCREMENT PRIMARY KEY, audit_type VARCHAR(50) NOT NULL, post_id BIGINT NULL, term_id BIGINT NULL, severity VARCHAR(20) NOT NULL, message TEXT NOT NULL, data LONGTEXT NULL, audit_date DATETIME NOT NULL, is_resolved TINYINT(1) DEFAULT 0, INDEX idx_type_date (audit_type, audit_date) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` ### Module 6: Internal Linking **Purpose:** Site-wide link crawl, per-post link audit, link suggestions, and orphan content detection. **Classes:** | Class | File | Purpose | |-------|------|---------| | `IGNY8_Linking_Module` | `modules/linking/class-linking-module.php` | Module bootstrap | | `IGNY8_Link_Auditor` | `modules/linking/class-link-auditor.php` | Per-post link audit | | `IGNY8_Link_Suggestions` | `modules/linking/class-link-suggestions.php` | Content similarity link suggestions | | `IGNY8_Orphan_Links` | `modules/linking/class-orphan-links.php` | Pages with zero inbound links | | `IGNY8_Link_Graph` | `modules/linking/class-link-graph.php` | Link equity visualization | | `IGNY8_Auto_Linker` | `modules/linking/class-auto-linker.php` | Auto-link insertion (connected mode only) | | `IGNY8_Link_Rules` | `modules/linking/class-link-rules.php` | Keyword-based link rules (connected mode only) | **Features:** - 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 backend (02D) **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`** ```sql CREATE 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, last_crawled DATETIME NOT NULL, INDEX idx_source (source_post_id), INDEX idx_target (target_post_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` ### Module 7: Google Search Console **Purpose:** OAuth 2.0 GSC connection with search performance dashboard and keyword tracking. **Classes:** | Class | File | Purpose | |-------|------|---------| | `IGNY8_GSC_Module` | `modules/gsc/class-gsc-module.php` | Module bootstrap | | `IGNY8_GSC_Auth` | `modules/gsc/class-gsc-auth.php` | OAuth 2.0 flow | | `IGNY8_GSC_Dashboard` | `modules/gsc/class-gsc-dashboard.php` | Performance dashboard | | `IGNY8_GSC_Keywords` | `modules/gsc/class-gsc-keywords.php` | Keyword position tracking | | `IGNY8_GSC_Indexing` | `modules/gsc/class-gsc-indexing.php` | URL indexing requests (connected mode only) | | `IGNY8_GSC_URL_Inspection` | `modules/gsc/class-gsc-url-inspection.php` | URL Inspection API (connected mode only) | **Features:** - OAuth 2.0 connection flow to Google Search Console - 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 (02C) **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 **Purpose:** Lightweight share buttons and social profile management. **Classes:** | Class | File | Purpose | |-------|------|---------| | `IGNY8_Socializer_Module` | `modules/socializer/class-socializer-module.php` | Module bootstrap | | `IGNY8_Share_Buttons` | `modules/socializer/class-share-buttons.php` | CSS/JS share button rendering | | `IGNY8_Social_Profiles` | `modules/socializer/class-social-profiles.php` | Organization social URLs | | `IGNY8_Auto_Poster` | `modules/socializer/class-auto-poster.php` | Auto-post on publish (connected mode only) | | `IGNY8_Twitter_API` | `modules/socializer/class-twitter-api.php` | Twitter/X API (connected mode only) | | `IGNY8_Facebook_API` | `modules/socializer/class-facebook-api.php` | Facebook Pages API (connected mode only) | | `IGNY8_LinkedIn_API` | `modules/socializer/class-linkedin-api.php` | LinkedIn API (connected mode only) | | `IGNY8_OG_Image_Generator` | `modules/socializer/class-og-image-generator.php` | Dynamic OG image (connected mode only) | **Features:** - 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 via 02H SocialAccount OAuth, dynamic OG image generation **Methods:** `render_share_buttons($post_id)`, `get_social_profiles()`, `post_to_social($post_id)` (connected) **Options:** `igny8_share_settings` — JSON: `{networks, position, style}` **Frontend Assets:** `share-buttons.css` (<3KB), `share-buttons.js` (<2KB) — conditionally enqueued only when enabled ### Module 9: Analytics + SMTP **Purpose:** Analytics script injection (GA4, GTM, pixels) and SMTP mail override. **Classes (Analytics):** | Class | File | Purpose | |-------|------|---------| | `IGNY8_Analytics_Module` | `modules/analytics/class-analytics-module.php` | Module bootstrap | | `IGNY8_GA_Connector` | `modules/analytics/class-ga-connector.php` | GA4 measurement ID injection | | `IGNY8_GTM_Connector` | `modules/analytics/class-gtm-connector.php` | Google Tag Manager container | | `IGNY8_Pixel_Manager` | `modules/analytics/class-pixel-manager.php` | Facebook, TikTok, Pinterest pixels | | `IGNY8_Script_Manager` | `modules/analytics/class-script-manager.php` | Custom header/footer scripts | **Classes (SMTP):** | Class | File | Purpose | |-------|------|---------| | `IGNY8_SMTP_Module` | `modules/smtp/class-smtp-module.php` | Module bootstrap | | `IGNY8_SMTP_Mailer` | `modules/smtp/class-smtp-mailer.php` | SMTP mail override | | `IGNY8_Email_Log` | `modules/smtp/class-email-log.php` | Delivery log with status | | `IGNY8_Email_Test` | `modules/smtp/class-email-test.php` | Test email sender | **Features (Analytics):** - 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) **Features (SMTP):** - SMTP mail override (host, port, user, pass, encryption SSL/TLS) - Email delivery log with status tracking - Test email sender - From name + from email override **Options:** ``` igny8_analytics_settings -- JSON: {ga_id, gtm_id, fb_pixel, tiktok_pixel, pinterest_tag, custom_scripts} igny8_smtp_settings -- JSON: {host, port, user, pass, encryption, from_name, from_email} ``` **SMTP Hooks:** `wp_mail` (override), `wp_mail_from`, `wp_mail_from_name` **Database Table: `{prefix}igny8_email_log`** ```sql CREATE 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, error_message TEXT NULL, sent_at DATETIME NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` ### Module 10: Import (Migration) **Purpose:** One-click migration from Yoast SEO, RankMath, and All in One SEO. **Classes:** | Class | File | Purpose | |-------|------|---------| | `IGNY8_Importer` | `data/class-importer.php` | Base importer with rollback | | `IGNY8_Yoast_Importer` | `data/class-yoast-importer.php` | Yoast SEO migration | | `IGNY8_RankMath_Importer` | `data/class-rankmath-importer.php` | RankMath migration | | `IGNY8_AIOSEO_Importer` | `data/class-aioseo-importer.php` | All in One SEO migration | **Features:** - 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) **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 ``` **Meta Key Mapping (RankMath → IGNY8):** ``` rank_math_focus_keyword → _igny8_focus_keyword rank_math_title → _igny8_seo_title rank_math_description → _igny8_meta_description rank_math_canonical_url → _igny8_canonical_url rank_math_robots → _igny8_robots_index + _igny8_robots_follow rank_math_facebook_title → _igny8_og_title rank_math_facebook_description → _igny8_og_description ``` **Meta Key Mapping (AIOSEO → IGNY8):** ``` _aioseo_title → _igny8_seo_title _aioseo_description → _igny8_meta_description _aioseo_canonical_url → _igny8_canonical_url _aioseo_robots_noindex → _igny8_robots_index _aioseo_og_title → _igny8_og_title _aioseo_og_description → _igny8_og_description ``` --- ## 3. DATA MODELS & APIS ### Database Tables (6 total) All tables created on plugin activation by `class-installer.php`: | # | Table | Module | Purpose | |---|-------|--------|---------| | 1 | `{prefix}igny8_redirects` | Redirects | 301/302/307 redirect rules | | 2 | `{prefix}igny8_404_log` | Redirects | 404 error logging | | 3 | `{prefix}igny8_link_map` | Internal Linking | Page-to-page link relationships | | 4 | `{prefix}igny8_audit_results` | Site Intelligence | Audit findings | | 5 | `{prefix}igny8_email_log` | SMTP | Email delivery log | | 6 | `{prefix}igny8_sync_queue` | (Connected prep) | Sync queue for connected mode readiness | **Table 6: `{prefix}igny8_sync_queue`** (created in standalone for connected mode readiness) ```sql CREATE 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 DEFAULT 'pending', wp_post_id BIGINT NULL, wp_term_id BIGINT NULL, data LONGTEXT NULL, created_at DATETIME NOT NULL, synced_at DATETIME NULL, error_message TEXT NULL, INDEX idx_status (sync_status) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` ### REST API Endpoints (public) All endpoints under `/wp-json/igny8/v1/`: | Method | Endpoint | Purpose | Auth | |--------|----------|---------|------| | GET | `/related/{post_id}` | Related content links | None (public) | | GET | `/cluster/{cluster_id}` | Cluster content list | None (public) | | GET | `/term/{term_id}/content` | Rich term content | None (public) | | GET | `/audit/summary` | Site audit results | Admin nonce | | GET | `/structure/overview` | Site structure summary | Admin nonce | ### Options Summary All options use `igny8_` prefix and store JSON: | Option Key | Module | Content | |------------|--------|---------| | `igny8_seo_settings` | SEO Core | Title templates, separator, defaults | | `igny8_social_profiles` | SEO Core | Organization social URLs | | `igny8_schema_settings` | Schema | Org type, name, logo, knowledge graph | | `igny8_sitemap_settings` | Sitemap | Included post types, taxonomies | | `igny8_redirect_settings` | Redirects | Auto-redirect on slug change | | `igny8_intelligence_settings` | Site Intelligence | Audit schedule, thresholds, exclusions | | `igny8_linking_settings` | Internal Linking | Auto-link rules, max links per post | | `igny8_gsc_token` | GSC | Encrypted OAuth token | | `igny8_gsc_property` | GSC | Selected GSC property URL | | `igny8_share_settings` | Socializer | Networks, position, style | | `igny8_analytics_settings` | Analytics | GA4, GTM, pixel IDs, custom scripts | | `igny8_smtp_settings` | SMTP | Host, port, user, pass, encryption | --- ## 4. IMPLEMENTATION STEPS ### File Structure ``` igny8/ ├── igny8.php # Plugin header, constants, bootstrap ├── 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 # Top-level menu + submenus │ │ ├── class-dashboard.php # Overview + quick actions │ │ ├── class-setup-wizard.php # 6-step first-run wizard │ │ ├── class-compatibility-notice.php │ │ ├── views/ # PHP template files │ │ └── 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 # Base importer + Yoast/RankMath/AIOSEO │ └── integrations/ │ ├── class-woocommerce.php # WooCommerce SEO + schema │ └── class-theme-bridge.php # Communication with companion theme └── languages/ └── igny8.pot # Translation template ``` ### Build Sequence **Phase 1: Foundation (Days 1-3)** 1. Create plugin skeleton: `igny8.php` with header, constants, autoloader 2. Build `class-igny8.php` singleton — `instance()`, `init()`, `load_modules()` 3. Build `class-module-manager.php` — `register()`, `activate()`, `deactivate()`, `is_active()`, `boot()` 4. Build admin menu structure: `class-admin-menu.php` with top-level + submenus 5. Build setup wizard: `class-setup-wizard.php` with 6 steps 6. Build `class-installer.php` — create all 6 DB tables via `dbDelta()` 7. Build `class-rest-api.php` — register 5 public endpoints 8. Build `class-compatibility.php` — detect Yoast/RankMath/AIOSEO active **Phase 2: SEO Core (Days 4-7)** 1. Build `IGNY8_SEO_Module` — module bootstrap + all hook registrations 2. Build `IGNY8_Meta_Box` — post editor meta box with all 16 post meta fields 3. Build `IGNY8_Title_Tag` — template system via `document_title_parts` filter 4. Build `IGNY8_Meta_Tags` — `<meta>` output in `<head>` 5. Build `IGNY8_Content_Analysis` — real-time SEO scoring (keyword density, heading structure, readability) 6. Build `IGNY8_Breadcrumbs` — shortcode + BreadcrumbList schema 7. Build `IGNY8_OpenGraph` — OG + Twitter Card tags 8. Build `IGNY8_Robots_Txt` — virtual robots.txt 9. Build `IGNY8_Verification` — webmaster codes 10. Build `class-head-output.php` — consolidated `wp_head` at priority 1 **Phase 3: Schema + Sitemap + Redirects (Days 8-10)** 1. Build schema module: generator dispatcher + 10 type-specific classes 2. Build sitemap module: index + post/taxonomy/image sub-sitemaps + XSL 3. Build redirects module: CRUD + 404 monitor + auto-redirect **Phase 4: Site Intelligence (Days 11-13)** 1. Build audit runner with WP Cron weekly schedule 2. Build 7 audit type classes (orphan, thin, empty terms, cannibalization, duplicate meta, cluster detector) 3. Build audit dashboard with severity badges **Phase 5: Internal Linking (Days 14-15)** 1. Build link crawl engine + link map table 2. Build per-post link audit + suggestions 3. Build link graph visualization **Phase 6: Socializer + Analytics/SMTP + GSC (Days 16-18)** 1. Build share buttons (<5KB CSS/JS) 2. Build analytics script connectors 3. Build SMTP override + email log 4. Build GSC OAuth flow + dashboard **Phase 7: Import (Days 19-20)** 1. Build base importer with dry run + rollback 2. Build Yoast → IGNY8 mapping 3. Build RankMath → IGNY8 mapping 4. Build AIOSEO → IGNY8 mapping **Phase 8: Compliance (Days 28-30)** 1. WordPress.org compliance audit — sanitize all inputs, escape all outputs 2. i18n pass — all strings through `__()` / `esc_html__()` with `igny8` domain 3. readme.txt with full feature list, changelog, screenshots 4. Accessibility review — ARIA labels, keyboard navigation in admin ### Setup Wizard (6 Steps) | Step | Title | Content | |------|-------|---------| | 1 | Site Type | Blog, Business, eCommerce, Local Business, SaaS, Portfolio | | 2 | SEO Import | Detect existing Yoast/RankMath/AIOSEO, offer import | | 3 | Site Basics | Site name, Organization/Person, logo, title separator | | 4 | Social Profiles | Social URLs + default sharing image | | 5 | Connect to IGNY8 | API key input (optional, clear skip button) | | 6 | Done | Summary, run first audit CTA | ### 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 ``` ### Performance Rules | Rule | Implementation | |------|---------------| | Zero CSS on frontend unless share buttons enabled | Conditional `wp_enqueue_style` check | | Zero JS on frontend unless interactive features active | Conditional `wp_enqueue_script` 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 | ### WordPress.org Compliance - GPL v2+ license header in all files - No phone-home without explicit user consent - All user-facing strings translatable via `igny8` text domain using `__()`, `esc_html__()`, `_e()`, `esc_html_e()` - Sanitize all inputs: `sanitize_text_field()`, `wp_kses_post()`, `absint()`, `sanitize_url()` - Escape all outputs: `esc_html()`, `esc_attr()`, `esc_url()`, `wp_kses_post()` - Use WP APIs: Settings API, REST API, `WP_Query` — no direct DB queries where WP functions exist - Nonce verification on all form submissions: `wp_nonce_field()` / `wp_verify_nonce()` - Capability checks: `current_user_can('manage_options')` for admin pages --- ## 5. ACCEPTANCE CRITERIA ### Foundation - [ ] Plugin activates without errors on WordPress 5.9+ with PHP 7.4+ - [ ] All 6 database tables created on activation via `dbDelta()` - [ ] Setup wizard runs on first activation with all 6 steps functional - [ ] Module manager toggles modules on/off without errors - [ ] `igny8()` public API returns singleton with module access - [ ] Compatibility checker detects active Yoast/RankMath/AIOSEO and shows admin notice ### SEO Core (Module 1) - [ ] Meta box renders on post/page/product edit screens with all fields - [ ] SEO title and meta description save to post meta and render in `<head>` - [ ] Title tag templates work with variables: `{title}`, `{site_name}`, `{separator}` - [ ] Content analysis scores keyword density, heading structure, readability (0-100) - [ ] Breadcrumbs render via shortcode `[igny8_breadcrumbs]` with BreadcrumbList schema - [ ] Open Graph + Twitter Card tags render correctly in `<head>` - [ ] Robots meta (noindex/nofollow) respected by output and sitemaps - [ ] Canonical URL override renders in `<head>` ### Schema (Module 2) - [ ] Auto-detects schema type per post type - [ ] Renders valid JSON-LD in single `<script>` block - [ ] All 10 schema types produce valid structured data - [ ] Custom JSON-LD editor accepts and renders user input - [ ] Schema passes Google Rich Results Test validation ### Sitemap (Module 3) - [ ] `/sitemap_index.xml` renders with sub-sitemap links - [ ] Per-post-type and per-taxonomy sub-sitemaps render - [ ] Image sitemap included - [ ] XSL stylesheet provides human-readable browser view - [ ] Noindexed posts excluded from sitemap - [ ] Search engines pinged on sitemap update ### Redirects (Module 4) - [ ] Create/read/update/delete 301/302/307 redirects - [ ] 404 errors logged with hit count, referrer, hashed IP - [ ] Auto-redirect created on slug change - [ ] One-click redirect from 404 log entry - [ ] CSV import/export functional ### Site Intelligence (Module 5) - [ ] Full audit runs via WP Cron weekly and manual trigger - [ ] Orphan pages, thin content, empty terms, duplicates, cannibalization detected - [ ] Dashboard shows severity badges (critical/warning/info) with counts - [ ] Individual audit items dismissible/resolvable ### Internal Linking (Module 6) - [ ] Full site link crawl completes and populates `igny8_link_map` - [ ] Per-post link audit shows inbound/outbound counts - [ ] Link suggestions generated based on content similarity - [ ] Orphan pages (zero inbound links) identified ### GSC (Module 7) - [ ] OAuth 2.0 flow connects to Google Search Console - [ ] Dashboard shows clicks, impressions, CTR, avg position with date range - [ ] Keyword position tracking displays historical data ### Socializer (Module 8) - [ ] Share buttons render at configured position (<5KB total) - [ ] All 8 networks functional (Facebook, X, LinkedIn, Pinterest, WhatsApp, Telegram, Email, Copy) - [ ] Button display conditionally enqueued — zero CSS/JS when disabled ### Analytics + SMTP (Module 9) - [ ] GA4, GTM, Facebook Pixel, TikTok Pixel scripts inject correctly - [ ] Custom header/footer scripts render in correct position - [ ] SMTP override sends mail via configured server - [ ] Email log records all sent/failed emails - [ ] Test email sends successfully ### Import (Module 10) - [ ] Yoast SEO meta data imports correctly with key mapping - [ ] RankMath meta data imports correctly with key mapping - [ ] All in One SEO meta data imports correctly with key mapping - [ ] Dry run preview shows migration summary without writing - [ ] Rollback restores original values ### Performance & Compliance - [ ] Zero frontend CSS/JS impact when share buttons disabled - [ ] All `<head>` output consolidated in single `wp_head` hook at priority 1 - [ ] Admin assets loaded only on IGNY8 admin pages - [ ] All user strings translatable via `igny8` text domain - [ ] All inputs sanitized, all outputs escaped - [ ] Nonce verification on all form submissions - [ ] Plugin passes WordPress Plugin Check (PCP) tool --- ## 6. CLAUDE CODE INSTRUCTIONS ### Context Requirements Before starting implementation: 1. Read existing WP Bridge plugin at `/data/app/igny8/plugins/wordpress/source/igny8-wp-bridge/` — understand current structure 2. Read 02D (Linker Internal) for IGNY8 backend linking logic that feeds Module 6 3. Read 02G (Rich Schema SERP) for schema types that feed Module 2 ### Execution Order ``` Foundation → SEO Core → Schema+Sitemap+Redirects → Intelligence → Linking → Social+Analytics+GSC → Import → Compliance ``` ### Critical Rules 1. **All IDs are integers** — BigAutoField on IGNY8 side, BIGINT AUTO_INCREMENT on WP side 2. **IGNY8 model names are PLURAL** — Clusters, Keywords, Tasks, ContentIdeas, Images, Content (stays singular) 3. **Table prefix** — All WP tables use `{wp_prefix}igny8_` prefix 4. **Post meta prefix** — All `_igny8_` prefixed 5. **Term meta prefix** — All `_igny8_term_` prefixed 6. **Option prefix** — All `igny8_` prefixed 7. **Text domain** — `igny8` for all translatable strings 8. **REST namespace** — `/wp-json/igny8/v1/` 9. **No direct DB queries** where WP functions exist (`WP_Query`, `get_post_meta`, `get_option`) 10. **Sanitize inputs** — `sanitize_text_field()`, `wp_kses_post()`, `absint()`, `sanitize_url()` 11. **Escape outputs** — `esc_html()`, `esc_attr()`, `esc_url()`, `wp_kses_post()` 12. **Nonce on forms** — `wp_nonce_field()` / `wp_verify_nonce()` / `check_ajax_referer()` 13. **Capability checks** — `current_user_can('manage_options')` for admin pages 14. **Module pattern** — Every module implements `register()`, `activate()`, `deactivate()`, `is_active()`, `boot()` ### Testing - Activate plugin on WordPress 5.9+ with PHP 7.4+ - Run setup wizard through all 6 steps - Toggle each module on/off — verify no errors - Create a post, fill all SEO meta, verify `<head>` output - Check sitemap renders at `/sitemap_index.xml` - Create redirect, trigger 404, verify logging - Run manual audit, verify dashboard results - Run link crawl, verify link map populated - Connect GSC via OAuth, verify dashboard data - Test share buttons at all positions - Configure GA4 + SMTP, verify injection + mail delivery - Import from Yoast test data, verify mapping - Run WordPress Plugin Check (PCP) tool for compliance ### File Creation Order ``` 1. igny8.php (plugin header + bootstrap) 2. includes/class-igny8.php (singleton) 3. includes/class-module-manager.php (module orchestration) 4. includes/data/class-installer.php (DB tables) 5. includes/admin/class-admin-menu.php (menu structure) 6. includes/admin/class-setup-wizard.php (first-run wizard) 7. includes/class-rest-api.php (public endpoints) 8. includes/class-compatibility.php (conflict detection) 9. includes/modules/seo/* (Module 1 — 9 files) 10. includes/frontend/class-head-output.php (consolidated <head>) 11. includes/modules/schema/* (Module 2 — 12 files) 12. includes/modules/sitemap/* (Module 3 — 6 files) 13. includes/modules/redirects/* (Module 4 — 4 files) 14. includes/modules/site-intelligence/* (Module 5 — 10 files) 15. includes/modules/linking/* (Module 6 — 7 files) 16. includes/modules/gsc/* (Module 7 — 6 files) 17. includes/modules/socializer/* (Module 8 — 8 files) 18. includes/modules/analytics/* (Module 9a — 5 files) 19. includes/modules/smtp/* (Module 9b — 4 files) 20. includes/data/class-importer.php + importers (Module 10 — 4 files) 21. includes/integrations/class-woocommerce.php (WooCommerce) 22. includes/integrations/class-theme-bridge.php (theme communication) 23. uninstall.php (cleanup) 24. languages/igny8.pot (i18n template) ``` ### Cross-References | Doc | Relationship | |-----|-------------| | 02D Linker Internal | IGNY8 backend SAGLink scoring → feeds Module 6 auto-linker in connected mode | | 02G Rich Schema SERP | IGNY8 backend schema generation → feeds Module 2 via bulk push in connected mode | | 02C GSC Integration | IGNY8 backend GSC metrics → feeds Module 7 URL Inspection in connected mode | | 02H Socializer | IGNY8 backend SocialAccount OAuth → feeds Module 8 auto-poster in connected mode | | 03B WP Plugin Connected | Extends this plugin with 2 connected-mode modules (Content Sync, SAG Structure) | | 03C Companion Theme | Theme consumes plugin API: `igny8()->seo`, `igny8()->schema`, `igny8()->linking` | | 03D Toolkit Plugin | If both installed, toolkit SMTP defers to this plugin's SMTP module |