Files
igny8/docs/plans/implemented/phase3-content-template-redesign.md
IGNY8 VPS (Salman) 75e5b148f5 reorg
2026-01-11 16:58:57 +00:00

814 lines
30 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
## 🎨 DESIGN ANALYSIS & PLAN
### Current State Analysis
**WordPress Single Post Template:**
- Uses emojis (📅, 📝, ✍️, 📁, 🏷️) in header metadata
- Shows all metadata including internal/debug data (Content ID, Task ID, Sector ID, Cluster ID, etc.)
- SEO section shows Meta Title & Meta Description in header (should be hidden from users)
- "Section Spotlight" label is hardcoded
- Images not optimally distributed - one per section sequentially
- Container max-width: 1200px
**App ContentViewTemplate:**
- Uses icons properly via component imports
- Similar "Section Spotlight" label issue
- Better image handling with aspect ratio detection
- Shows extensive metadata in header (Meta Title, Meta Description, Primary/Secondary Keywords)
- Container max-width: 1440px
---
## 📐 DESIGN PLAN
### 1. CSS Container Width Update
```
.igny8-content-container {
max-width: 1280px; /* Default for screens <= 1600px */
}
@media (min-width: 1600px) {
.igny8-content-container {
max-width: 1530px; /* For screens > 1600px */
}
}
```
---
### 2. WordPress Header Redesign
**USER-FACING FIELDS (Keep in Header):**
| Field | Display | Icon | Notes |
|-------|---------|------|-------|
| Title | H1 | - | Post title |
| Status Badge | Published/Draft/etc | - | Post status |
| Posted Date | Formatted date | Calendar SVG | Publication date |
| Word Count | Formatted number | Document SVG | Content word count |
| Author | Author name | User SVG | Post author |
| Topic | Cluster name (clickable)| Compass SVG | Display cluster_name as "Topic" |
| Categories | Badge list (Parent > Child clicakble) | Folder SVG | WP Categories |
| Tags | Badge list (clickable)| Tag SVG | WP Tags |
**NON-USER FIELDS (Move to Metadata Section - Editor+ only):**
- Content ID, Task ID
- Content Type, Structure
- Cluster ID (keep cluster_name as Topic in header)
- Sector ID, Sector Name
- Primary Keyword, Secondary Keywords
- Meta Title, Meta Description
- Source, Last Synced
---
### 3. Section Label Redesign
**Current:** "Section Spotlight" (generic text)
**New Approach - Keyword/Tag Matching Algorithm:**
1. **Source Data:**
- Get all WordPress tags assigned to the post
- Get all WordPress categories assigned to the post
- Get primary keyword from post meta
- Get secondary keywords from post meta (if available)
2. **Matching Logic:**
- For each section heading (H2), perform case-insensitive partial matching
- Check if any tag name appears in the heading text
- Check if any category name appears in the heading text
- Check if primary/secondary keywords appear in the heading text
- Prioritize: Primary Keyword > Tags > Categories > Secondary Keywords
3. **Display Rules:**
- If matches found: Display up to 2 matched keywords/tags as badges
- If no matches: Display topic (cluster_name) or leave section without label badges
- Never display generic "Section Spotlight" text
4. **Badge Styling:**
```
[Primary Match] [Secondary Match] ← styled badges replacing "Section Spotlight"
```
**Colors:**
- Primary badge: `theme-color @ 15% opacity` background, `theme-color` text
- Secondary badge: `theme-color @ 8% opacity` background, `theme-color @ 80%` text
**Implementation Function (Pseudo-code):**
```php
function igny8_get_section_badges($heading, $post_id) {
$badges = [];
$heading_lower = strtolower($heading);
// Get post taxonomies and keywords
$tags = get_the_tags($post_id);
$categories = get_the_category($post_id);
$primary_kw = get_post_meta($post_id, '_igny8_primary_keyword', true);
$secondary_kws = get_post_meta($post_id, '_igny8_secondary_keywords', true);
// Priority 1: Primary keyword
if ($primary_kw && stripos($heading_lower, strtolower($primary_kw)) !== false) {
$badges[] = ['text' => $primary_kw, 'type' => 'primary'];
}
// Priority 2: Tags
if ($tags && count($badges) < 2) {
foreach ($tags as $tag) {
if (stripos($heading_lower, strtolower($tag->name)) !== false) {
$badges[] = ['text' => $tag->name, 'type' => 'tag'];
if (count($badges) >= 2) break;
}
}
}
// Priority 3: Categories
if ($categories && count($badges) < 2) {
foreach ($categories as $cat) {
if (stripos($heading_lower, strtolower($cat->name)) !== false) {
$badges[] = ['text' => $cat->name, 'type' => 'category'];
if (count($badges) >= 2) break;
}
}
}
// Priority 4: Secondary keywords
if ($secondary_kws && count($badges) < 2) {
$kw_array = is_array($secondary_kws) ? $secondary_kws : explode(',', $secondary_kws);
foreach ($kw_array as $kw) {
$kw = trim($kw);
if (stripos($heading_lower, strtolower($kw)) !== false) {
$badges[] = ['text' => $kw, 'type' => 'keyword'];
if (count($badges) >= 2) break;
}
}
}
return $badges;
}
```
---
### 4. Image Distribution Strategy
**Available Images (4 total):**
- Position 0: Square (1024×1024)
- Position 1: Landscape (1536×1024 or 1920×1080)
- Position 2: Square (1024×1024)
- Position 3: Landscape (1536×1024 or 1920×1080)
**Distribution Plan - First 4 Sections (with descriptions):**
| Section | Image Position | Type | Width | Alignment | Description |
|---------|---------------|------|-------|-----------|-------------|
| **Featured** | Position 1 | Landscape | 100% max 1024px | Center | Show prompt on first use |
| **Section 1** | Position 0 | Square | 50% | Right | With description + widget placeholder below |
| **Section 2** | Position 3 | Landscape | 100% max 1024px | Full width | With description |
| **Section 3** | Position 2 | Square | 50% | Left | With description + widget placeholder below |
| **Section 4** | Position 1 (reuse) | Landscape | 100% max 1024px | Full width | With description |
**Distribution Plan - Sections 5-7+ (reuse without descriptions):**
| Section | Reuse Image | Type | Width | Alignment | Description |
|---------|-------------|------|-------|-----------|-------------|
| **Section 5** | Featured (pos 1) | Landscape | 100% max 1024px | Full width | NO description |
| **Section 6** | Position 0 | Square | 50% | Right | NO description + widget placeholder |
| **Section 7** | Position 3 | Landscape | 100% max 1024px | Full width | NO description |
| **Section 8+** | Cycle through all 4 | Based on type | Based on type | Based on type | NO description |
**Special Case - Tables:**
- When section contains `<table>` element, always place full-width landscape image BEFORE table
- Use next available landscape image (Position 1 or 3)
- Max width: 1024px, centered
- Spacing: `margin-bottom: 2rem` before table
- Override normal section pattern when table detected
**Image Reuse Rules:**
- Images 1-4 used in first 4 sections WITH descriptions/prompts
- Sections 5+ reuse same images WITHOUT descriptions/prompts
- Use CSS classes: `.igny8-image-first-use` vs `.igny8-image-reuse`
- Maintain same layout pattern (square = 50%, landscape = 100%)
**Widget Placeholders:**
- Show only below square images (left/right aligned)
- Empty div with class `.igny8-widget-placeholder`
- Space reserved for future widget insertion
- Controlled via plugin settings (future implementation)
**Implementation Notes:**
```php
// Check for table in section content
function igny8_section_has_table($section_html) {
return (stripos($section_html, '<table') !== false);
}
// Get image aspect ratio from position
function igny8_get_image_aspect($position) {
// Even positions (0, 2) = square
// Odd positions (1, 3) = landscape
return ($position % 2 === 0) ? 'square' : 'landscape';
}
// Determine if image should show description
function igny8_show_image_description($section_index) {
// First 4 sections (0-3) show descriptions
return ($section_index < 4);
}
```
---
### 5. Image Alignment with Tables
When section contains a `<table>`:
- Place landscape image ABOVE the table
- Full width (max 800px)
- Proper spacing: `margin-bottom: 2rem`
- Table should not wrap around image
---
### 6. Responsive Image Width Rules
```css
/* Landscape images */
.igny8-image-landscape {
max-width: 1024px; /* Updated from 800px */
width: 100%;
margin: 0 auto;
display: block;
}
.igny8-image-landscape.igny8-image-reuse {
/* No description shown on reuse */
}
/* Single square image - Right aligned */
.igny8-image-square-right {
max-width: 50%;
margin-left: auto;
float: right;
margin-left: 2rem;
margin-bottom: 2rem;
}
/* Single square image - Left aligned */
.igny8-image-square-left {
max-width: 50%;
margin-right: auto;
float: left;
margin-right: 2rem;
margin-bottom: 2rem;
}
/* Widget placeholder below square images */
.igny8-widget-placeholder {
clear: both;
min-height: 200px;
padding: 1.5rem;
margin-top: 1rem;
background: rgba(0, 0, 0, 0.02);
border: 1px dashed rgba(0, 0, 0, 0.1);
border-radius: 12px;
display: none; /* Hidden by default, shown when widgets enabled */
}
.igny8-widget-placeholder.igny8-widgets-enabled {
display: block;
}
/* Table-specific image positioning */
.igny8-image-before-table {
max-width: 1024px;
width: 100%;
margin: 0 auto 2rem;
display: block;
}
```
---
### 7. Role-Based Visibility
**Metadata Section (Bottom):**
```php
<?php if (current_user_can('edit_posts')): ?>
<div class="igny8-metadata-footer igny8-editor-only">
<!-- All internal metadata here -->
</div>
<?php endif; ?>
```
**Visible only to:**
- Editor
- Administrator
- Author (for their own posts)
---
### 8. Header Icon Set (Replace Emojis)
Create inline SVG icons matching theme color:
```php
// Calendar Icon
<svg class="igny8-icon" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z"/>
</svg>
// Document Icon (Word Count)
<svg class="igny8-icon" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 6a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7z"/>
</svg>
// User Icon (Author)
<svg class="igny8-icon" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z"/>
</svg>
// Compass Icon (Topic/Cluster)
<svg class="igny8-icon" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z"/>
</svg>
// Folder Icon (Categories)
<svg class="igny8-icon" viewBox="0 0 20 20" fill="currentColor">
<path d="M2 6a2 2 0 012-2h5l2 2h5a2 2 0 012 2v6a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"/>
</svg>
// Tag Icon (Tags)
<svg class="igny8-icon" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M17.707 9.293a1 1 0 010 1.414l-7 7a1 1 0 01-1.414 0l-7-7A.997.997 0 012 10V5a3 3 0 013-3h5c.256 0 .512.098.707.293l7 7zM5 6a1 1 0 100-2 1 1 0 000 2z"/>
</svg>
```
Icon styling:
```css
.igny8-icon {
width: 1rem;
height: 1rem;
color: var(--igny8-theme-color, currentColor);
opacity: 0.8;
display: inline-block;
vertical-align: middle;
}
```
---
### 9. Table of Contents
**Position:** Below featured image, before intro section
**Content:** List all H2 headings from content
**Features:**
- Clickable links with smooth scroll to sections
- Collapsible/expandable (optional)
- Numbered list matching section numbers
- Sticky positioning option (future setting)
**Implementation:**
```php
function igny8_generate_table_of_contents($content) {
$toc_items = [];
// Parse content for H2 headings
preg_match_all('/<h2[^>]*>(.*?)<\/h2>/i', $content, $matches);
if (!empty($matches[1])) {
foreach ($matches[1] as $index => $heading) {
$heading_text = strip_tags($heading);
$slug = sanitize_title($heading_text);
$toc_items[] = [
'number' => $index + 1,
'text' => $heading_text,
'id' => $slug
];
}
}
return $toc_items;
}
```
**HTML Structure:**
```html
<nav class="igny8-table-of-contents">
<div class="igny8-toc-header">
<span class="igny8-toc-icon">📑</span>
<h3>Table of Contents</h3>
</div>
<ol class="igny8-toc-list">
<?php foreach ($toc_items as $item): ?>
<li class="igny8-toc-item">
<a href="#<?php echo esc_attr($item['id']); ?>" class="igny8-toc-link">
<span class="igny8-toc-number"><?php echo $item['number']; ?>.</span>
<span class="igny8-toc-text"><?php echo esc_html($item['text']); ?></span>
</a>
</li>
<?php endforeach; ?>
</ol>
</nav>
```
**CSS:**
```css
.igny8-table-of-contents {
background: var(--wp--preset--color--base, #ffffff);
border: 2px solid rgba(0, 0, 0, 0.12);
border-radius: 16px;
padding: 1.5rem 2rem;
margin-bottom: 2rem;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
}
.igny8-toc-header {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 1rem;
padding-bottom: 1rem;
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
}
.igny8-toc-header h3 {
margin: 0;
font-size: 1.125rem;
font-weight: 600;
}
.igny8-toc-list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.igny8-toc-link {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.5rem 0.75rem;
text-decoration: none;
color: inherit;
border-radius: 8px;
transition: background-color 0.2s ease;
}
.igny8-toc-link:hover {
background: rgba(0, 0, 0, 0.04);
}
.igny8-toc-number {
display: inline-flex;
align-items: center;
justify-content: center;
width: 1.5rem;
height: 1.5rem;
background: rgba(59, 130, 246, 0.1);
color: rgba(59, 130, 246, 1);
border-radius: 50%;
font-size: 0.75rem;
font-weight: 600;
flex-shrink: 0;
}
.igny8-toc-text {
flex: 1;
font-size: 0.9375rem;
}
```
**Settings (Future Implementation):**
```php
// Plugin settings for TOC
$igny8_toc_settings = [
'enabled' => true,
'show_numbers' => true,
'collapsible' => false,
'sticky' => false,
'min_headings' => 3, // Only show if 3+ H2 headings
];
```
---
### 10. Widget System
**Widget Placeholders:**
Widgets appear below square images (left/right aligned) where there's natural space.
**Placeholder Function:**
```php
function igny8_render_widget_placeholder($position, $section_index) {
// Check if widgets are enabled in settings
$widgets_enabled = get_option('igny8_widgets_enabled', false);
if (!$widgets_enabled) {
return '';
}
$placeholder_class = 'igny8-widget-placeholder igny8-widgets-enabled';
$placeholder_class .= ' igny8-widget-' . $position; // left or right
$placeholder_class .= ' igny8-widget-section-' . $section_index;
?>
<div class="<?php echo esc_attr($placeholder_class); ?>"
data-widget-position="<?php echo esc_attr($position); ?>"
data-section-index="<?php echo esc_attr($section_index); ?>">
<!-- Widget content will be inserted here via settings -->
<?php do_action('igny8_widget_placeholder', $position, $section_index); ?>
</div>
<?php
}
```
**Widget Settings (Future Implementation):**
```php
// Plugin settings for widgets
$igny8_widget_settings = [
'enabled' => false,
'sections' => [
'section_1' => [
'position' => 'right',
'widget_type' => 'related_posts', // or 'custom_html', 'ad_unit', etc.
'content' => '',
],
'section_3' => [
'position' => 'left',
'widget_type' => 'newsletter_signup',
'content' => '',
],
],
];
```
**Widget Types (Future):**
- Related Posts
- Newsletter Signup
- Ad Units
- Custom HTML
- Social Share Buttons
- Author Bio
- Call-to-Action Boxes
---
### 11. Updated Structure Overview
**WordPress Single Post:**
```
┌─────────────────────────────────────────────┐
│ HEADER │
│ ← Back to Posts │
│ │
│ [H1 Title] [Status Badge] │
│ │
│ 📅 Posted: Date 📄 Words 👤 Author │
│ 🧭 Topic: Cluster Name │
│ 📁 [Category Badges] 🏷️ [Tag Badges] │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ FEATURED IMAGE (Landscape, max 1024px) │
│ │
│ [Image Prompt - first use only] │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ TABLE OF CONTENTS │
│ 📑 Table of Contents │
│ 1. Section Heading One │
│ 2. Section Heading Two │
│ 3. Section Heading Three │
│ ... (clickable, smooth scroll) │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ INTRO SECTION │
│ Opening Narrative │
│ [Content...] │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ SECTION 1 │
│ [Keyword Badge] [Tag Badge] │
│ 1 [H2 Heading] │
│ │
│ ┌──────────────┐ ┌──────────────────────┐ │
│ │ │ │ │ │
│ │ Content │ │ Square Image (50%) │ │
│ │ │ │ Right Aligned │ │
│ │ │ │ [Image Description] │ │
│ └──────────────┘ └──────────────────────┘ │
│ [Widget Placeholder] │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ SECTION 2 │
│ [Keyword Badge] │
│ 2 [H2 Heading] │
│ │
│ ┌───────────────────────────────────────┐ │
│ │ Landscape Image (100% max 1024px) │ │
│ │ [Image Description] │ │
│ └───────────────────────────────────────┘ │
│ │
│ [Content...] │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ SECTION 3 │
│ [Keyword Badge] [Tag Badge] │
│ 3 [H2 Heading] │
│ │
│ ┌──────────────────────┐ ┌──────────────┐ │
│ │ │ │ │ │
│ │ Square Image (50%) │ │ Content │ │
│ │ Left Aligned │ │ │ │
│ │ [Image Description] │ │ │ │
│ └──────────────────────┘ └──────────────┘ │
│ [Widget Placeholder] │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ SECTION 4 (with table example) │
│ [Keyword Badge] │
│ 4 [H2 Heading] │
│ │
│ ┌───────────────────────────────────────┐ │
│ │ Landscape Image (100% max 1024px) │ │
│ │ [Image Description] │ │
│ └───────────────────────────────────────┘ │
│ │
│ [Content before table...] │
│ │
│ ┌───────────────────────────────────────┐ │
│ │ TABLE │ │
│ │ [Data rows and columns] │ │
│ └───────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ SECTION 5 (reuse - no description) │
│ [Keyword Badge] │
│ 5 [H2 Heading] │
│ │
│ ┌───────────────────────────────────────┐ │
│ │ Featured Image REUSED (no caption) │ │
│ └───────────────────────────────────────┘ │
│ │
│ [Content...] │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ SECTION 6 (reuse - no description) │
│ [Tag Badge] │
│ 6 [H2 Heading] │
│ │
│ ┌──────────────┐ ┌──────────────────────┐ │
│ │ Content │ │ Square Image REUSED │ │
│ │ │ │ (no caption) │ │
│ └──────────────┘ └──────────────────────┘ │
│ [Widget Placeholder] │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ METADATA FOOTER (Editor+ only) │
│ ▸ View IGNY8 Metadata │
│ - Content ID: 123 │
│ - Task ID: 456 │
│ - Meta Title: ... │
│ - Meta Description: ... │
│ - Primary Keyword: ... │
│ - Secondary Keywords: [list] │
│ - Cluster ID: 789 │
│ - Sector: Industry Name │
│ - Source: AI Generated │
│ - Last Synced: Date/Time │
└─────────────────────────────────────────────┘
```
---
### 12. App ContentViewTemplate Updates
**Changes to body section only (not header):**
1. **Remove "Section Spotlight" label** - Replace with keyword badge matching system
2. **Add Table of Contents** below featured image (matching WordPress implementation)
3. **Match image layout rules** from WordPress template:
- Section 1: Square right-aligned 50% (with description)
- Section 2: Landscape full width max 1024px (with description)
- Section 3: Square left-aligned 50% (with description)
- Section 4: Landscape full width max 1024px (with description)
- Sections 5+: Reuse images without descriptions
4. **Featured image** max 1024px centered
5. **Widget placeholders** below square images (empty for now)
6. **Table detection** - full-width image before tables
**Implementation Priority:**
- Phase 1: Update image sizing (1024px max)
- Phase 2: Implement keyword badge matching
- Phase 3: Add table of contents component
- Phase 4: Add widget placeholder divs
---
## Summary of Files to Update
| File | Changes | Priority |
|------|---------|----------|
| `igny8-content-template.css` | Container width breakpoints, image sizing classes, TOC styles, widget placeholder styles | 🔴 High |
| `igny8-header.php` | Remove emojis, add SVG icons, add Topic field, remove SEO/internal metadata | 🔴 High |
| `igny8-metadata.php` | Add role check (`current_user_can('edit_posts')`), include all moved metadata fields | 🔴 High |
| `igny8-content-sections.php` | Keyword badge matching logic, smart image distribution (Section 1-4 pattern), widget placeholders | 🔴 High |
| `igny8-featured-image.php` | Max 1024px, landscape priority | 🟡 Medium |
| `includes/template-functions.php` | Add helper functions: `igny8_get_section_badges()`, `igny8_section_has_table()`, `igny8_show_image_description()`, `igny8_generate_table_of_contents()` | 🔴 High |
| `ContentViewTemplate.tsx` | Match section labels, image layouts, add TOC component, widget placeholders | 🟡 Medium |
| **New File**: `parts/igny8-table-of-contents.php` | Table of contents component | 🟡 Medium |
| **New File**: `admin/settings-page.php` | Widget settings, TOC settings (future) | 🟢 Low |
---
## Configuration Settings (Future Implementation)
```php
// Plugin settings structure
$igny8_plugin_settings = [
'table_of_contents' => [
'enabled' => true,
'show_numbers' => true,
'collapsible' => false,
'sticky' => false,
'min_headings' => 3,
'position' => 'after_featured_image', // or 'before_content', 'floating'
],
'widgets' => [
'enabled' => false,
'sections' => [
'section_1' => [
'position' => 'right',
'widget_type' => 'none', // 'related_posts', 'custom_html', 'ad_unit', etc.
'content' => '',
],
'section_3' => [
'position' => 'left',
'widget_type' => 'none',
'content' => '',
],
],
],
'images' => [
'featured_max_width' => 1024,
'landscape_max_width' => 1024,
'square_width_percentage' => 50,
'show_descriptions_sections' => 4, // Show descriptions in first N sections
],
'badges' => [
'show_section_badges' => true,
'max_badges_per_section' => 2,
'badge_sources' => ['primary_keyword', 'tags', 'categories', 'secondary_keywords'], // Priority order
],
];
```
---
## Implementation Phases
### Phase 1: Core Template Updates (Week 1)
- ✅ Update CSS container widths and image sizing
- ✅ Replace emojis with SVG icons in header
- ✅ Add Topic field to header
- ✅ Move metadata to bottom with role check
- ✅ Implement keyword badge matching logic
### Phase 2: Advanced Features (Week 2)
- ✅ Table of contents component
- ✅ Table detection and image positioning
- ✅ Image reuse logic (sections 5+)
### Phase 3: App Sync (Week 3)
- ✅ Update ContentViewTemplate.tsx to match WordPress
- ✅ Add TOC component to React app
- ✅ Sync image layouts and sizing
### Phase 4: Settings & Configuration (Week 4)
- ⏳ Plugin settings page
- ⏳ TOC configuration options
- ⏳ Widget management interface
- ⏳ Badge display preferences
---
**Last Updated:** January 10, 2026
**Document Version:** 2.0
**Status:** Design Complete - Ready for Implementation