Files
igny8/igny8-wp-plugin/docs/FIXES-APPLIED-2025-11-30.md
alorig 90b532d13b 1234
2025-12-01 04:55:27 +05:00

16 KiB

Fixes Applied - November 30, 2025

Summary

Fixed 4 critical issues related to WordPress integration:

  1. Status not updating from 'review' to 'published' - Fixed with optimistic status update
  2. Missing WP Status column on Published page - Added WordPress status endpoint
  3. Custom taxonomy/attribute columns - Removed, now using native WP taxonomies
  4. Tags, categories, images, keywords not saving - Now properly extracted and sent to WordPress

Issue 1: Status Not Updating to 'Published'

Problem

When content was published from the Review page, the status in IGNY8 remained as 'review' even after successful WordPress publication.

Root Cause

The publish endpoint was queuing a Celery task but not updating the status immediately. Users had to wait for the background task to complete before seeing status change.

Fix Applied

File: e:\Projects\...\igny8\backend\igny8_core\modules\writer\views.py
Method: ContentViewSet.publish()

Changes:

# OPTIMISTIC UPDATE: Set status to published immediately for better UX
# The Celery task will update external_id and external_url when WordPress responds
content.status = 'published'
content.save(update_fields=['status', 'updated_at'])

# Queue publishing task
result = publish_content_to_wordpress.delay(
    content_id=content.id,
    site_integration_id=site_integration.id
)

# Return with status='published' immediately
return success_response(
    data={
        'content_id': content.id,
        'task_id': result.id,
        'status': 'published',  # ← Now returns 'published' immediately
        'message': 'Publishing queued - content will be published to WordPress shortly'
    },
    message='Content status updated to published and queued for WordPress',
    request=request,
    status_code=status.HTTP_202_ACCEPTED
)

Error Handling:

  • If the Celery task fails to queue, status is reverted to 'review'
  • The background task still sets external_id, external_url, and confirms status after WordPress responds

Result: Users now see status change to 'published' immediately when clicking Publish button


Issue 2: No WP Status Column on Published Page

Problem

The Published page in IGNY8 didn't show the current WordPress status of published content.

Fix Applied

File: e:\Projects\...\igny8\backend\igny8_core\modules\writer\views.py
New Endpoint: GET /api/v1/writer/content/{id}/wordpress_status/

@action(detail=True, methods=['get'], url_path='wordpress_status', url_name='wordpress_status')
def wordpress_status(self, request, pk=None):
    """
    Get WordPress post status for published content.
    Calls WordPress REST API to get current status.
    
    Returns: {
        'wordpress_status': 'publish'|'draft'|'pending'|null,
        'external_id': 123,
        'external_url': 'https://...',
        'post_title': '...',
        'post_modified': '2025-11-30...',
        'last_checked': '2025-11-30T...'
    }
    """

WordPress Plugin Endpoint: GET /wp-json/igny8/v1/post-status/{id}/

File: c:\Users\Hp\vscode\igny8-wp-integration\includes\class-igny8-rest-api.php
Updated Method: get_post_status()

/**
 * Get post status by post ID or content_id
 * Accepts either WordPress post_id or IGNY8 content_id
 */
public function get_post_status($request) {
    $id = intval($request['id']);
    
    // First try as WordPress post ID
    $post = get_post($id);
    
    // If not found, try as IGNY8 content_id
    if (!$post) {
        $posts = get_posts(array(
            'meta_key' => '_igny8_content_id',
            'meta_value' => $id,
            'post_type' => 'any',
            'posts_per_page' => 1,
            'post_status' => 'any'
        ));
        $post = !empty($posts) ? $posts[0] : null;
    }
    
    return rest_ensure_response(array(
        'success' => true,
        'data' => array(
            'post_id' => $post->ID,
            'post_status' => $post->post_status,  // WordPress status
            'post_title' => $post->post_title,
            'post_modified' => $post->post_modified,
            'wordpress_status' => $post->post_status,
            'igny8_status' => igny8_map_wp_status_to_igny8($post->post_status),
            // ... more fields
        )
    ));
}

Frontend Integration:

To display WP Status column on Published page, the frontend should:

  1. Call GET /api/v1/writer/content/{id}/wordpress_status/ for each published content
  2. Display wordpress_status field (e.g., "Published", "Draft", "Pending")
  3. Optionally show post_modified to indicate last update time

Status Mapping:

WordPress Status IGNY8 Status Display
publish completed Published
draft draft Draft
pending pending Pending Review
private completed Private
trash archived Trashed
future scheduled Scheduled

Result: IGNY8 app can now poll WordPress status and display it in the Published page table


Issue 3: Remove Custom Taxonomy/Attribute Columns

Problem

WordPress admin had custom "Taxonomy" and "Attribute" columns that referenced deprecated custom taxonomies instead of using native WordPress categories and tags.

Fix Applied

File: c:\Users\Hp\vscode\igny8-wp-integration\admin\class-admin-columns.php

Removed:

  • render_taxonomy_column() method
  • render_attribute_column() method
  • Custom column registration for igny8_taxonomy and igny8_attribute

Before:

public function add_columns($columns) {
    $new_columns = array();
    foreach ($columns as $key => $value) {
        $new_columns[$key] = $value;
        if ($key === 'title') {
            $new_columns['igny8_taxonomy'] = __('Taxonomy', 'igny8-bridge');
            $new_columns['igny8_attribute'] = __('Attribute', 'igny8-bridge');
        }
    }
    return $new_columns;
}

After:

public function add_columns($columns) {
    // Removed custom taxonomy and attribute columns
    // Posts now use native WordPress taxonomies (categories, tags, etc.)
    return $columns;
}

Result:

  • Posts, pages, and products now only show native WordPress taxonomy columns
  • Categories, tags, product categories, etc. are displayed in standard WordPress columns
  • Cleaner admin UI aligned with WordPress standards

Issue 4: Tags, Categories, Images, Keywords Not Saving

Problem

When publishing content from IGNY8 to WordPress:

  • Tags were not being saved
  • Categories were not being saved
  • Featured and gallery images were not being attached
  • Keywords (primary and secondary) were not being added as tags

Root Cause

The publish_content_to_wordpress Celery task was sending empty arrays:

# BEFORE (BROKEN):
content_data = {
    'title': content.title,
    'content_html': content.content_html,
    # ...
    'featured_image_url': None,  # ← Empty
    'sectors': [],  # ← Empty
    'clusters': [],  # ← Empty
    'tags': []  # ← Empty
}

Fix Applied

File: e:\Projects\...\igny8\backend\igny8_core\tasks\wordpress_publishing.py
Function: publish_content_to_wordpress()

Changes:

  1. Extract taxonomy terms from ContentTaxonomyMap:
from igny8_core.business.content.models import ContentTaxonomyMap
taxonomy_maps = ContentTaxonomyMap.objects.filter(content=content).select_related('taxonomy')

categories = []
tags = []
for mapping in taxonomy_maps:
    tax = mapping.taxonomy
    if tax:
        # Add taxonomy term name to categories
        categories.append(tax.name)
  1. Extract images from Images model:
from igny8_core.modules.writer.models import Images
featured_image_url = None
gallery_images = []

images = Images.objects.filter(content=content).order_by('position')
for image in images:
    if image.image_type == 'featured' and image.image_url:
        featured_image_url = image.image_url
    elif image.image_type == 'in_article' and image.image_url:
        gallery_images.append({
            'url': image.image_url,
            'alt': image.alt_text or '',
            'position': image.position
        })
  1. Add keywords as tags:
# Add primary and secondary keywords as tags
if content.primary_keyword:
    tags.append(content.primary_keyword)

if content.secondary_keywords:
    if isinstance(content.secondary_keywords, list):
        tags.extend(content.secondary_keywords)
    elif isinstance(content.secondary_keywords, str):
        import json
        try:
            keywords = json.loads(content.secondary_keywords)
            if isinstance(keywords, list):
                tags.extend(keywords)
        except (json.JSONDecodeError, TypeError):
            pass
  1. Send complete payload to WordPress:
content_data = {
    'content_id': content.id,
    'task_id': task_id,
    'title': content.title,
    'content_html': content.content_html or '',
    # ... SEO fields ...
    'featured_image_url': featured_image_url,  # ✅ Now populated
    'gallery_images': gallery_images,  # ✅ Now populated
    'categories': categories,  # ✅ Now populated from taxonomy mappings
    'tags': tags,  # ✅ Now populated from keywords
    # ...
}

How WordPress Processes This Data

File: c:\Users\Hp\vscode\igny8-wp-integration\sync\igny8-to-wp.php
Function: igny8_create_wordpress_post_from_task()

  1. Categories:
// Handle categories
if (!empty($content_data['categories'])) {
    $category_ids = igny8_process_categories($content_data['categories'], $post_id);
    if (!empty($category_ids)) {
        wp_set_post_terms($post_id, $category_ids, 'category');
    }
}
  1. Tags:
// Handle tags
if (!empty($content_data['tags'])) {
    $tag_ids = igny8_process_tags($content_data['tags'], $post_id);
    if (!empty($tag_ids)) {
        wp_set_post_terms($post_id, $tag_ids, 'post_tag');
    }
}
  1. Featured Image:
if (!empty($content_data['featured_image_url'])) {
    igny8_set_featured_image($post_id, $content_data['featured_image_url']);
}
  1. Gallery Images:
if (!empty($content_data['gallery_images'])) {
    igny8_set_image_gallery($post_id, $content_data['gallery_images']);
}
  1. Keywords (stored as post meta):
if (!empty($content_data['primary_keyword'])) {
    update_post_meta($post_id, '_igny8_primary_keyword', $content_data['primary_keyword']);
}

if (!empty($content_data['secondary_keywords'])) {
    update_post_meta($post_id, '_igny8_secondary_keywords', $content_data['secondary_keywords']);
}

Result:

  • Categories created/assigned from taxonomy mappings
  • Tags created/assigned from keywords (primary + secondary)
  • Featured image downloaded and set as post thumbnail
  • Gallery images downloaded and attached to post
  • Keywords stored in post meta for SEO plugins

Data Flow (Complete)

Before Fixes

IGNY8 Content Model
  ├─ title ✓
  ├─ content_html ✓
  ├─ taxonomy_terms → NOT SENT ❌
  ├─ images → NOT SENT ❌
  ├─ keywords → NOT SENT ❌
  └─ status stays 'review' ❌
        ↓
WordPress Post
  ├─ Title + Content ✓
  ├─ No categories ❌
  ├─ No tags ❌
  ├─ No images ❌
  └─ IGNY8 status still 'review' ❌

After Fixes

IGNY8 Content Model
  ├─ title ✓
  ├─ content_html ✓
  ├─ ContentTaxonomyMap → categories[] ✓
  ├─ Images (featured + gallery) → image URLs ✓
  ├─ primary_keyword + secondary_keywords → tags[] ✓
  └─ status = 'published' immediately ✓
        ↓
WordPress Post
  ├─ Title + Content ✓
  ├─ Categories (from taxonomy terms) ✓
  ├─ Tags (from keywords) ✓
  ├─ Featured Image + Gallery ✓
  └─ IGNY8 can query WordPress status ✓

Testing Checklist

1. Test Status Update

  • Create content in IGNY8 with status 'review'
  • Click "Publish" button
  • Verify status changes to 'published' immediately (not waiting for background task)
  • Verify content appears in WordPress with full content
  • Check IGNY8 external_id and external_url populated after Celery task completes

2. Test WordPress Status Endpoint

  • Publish content from IGNY8
  • Call GET /api/v1/writer/content/{id}/wordpress_status/
  • Verify response contains wordpress_status: 'publish'
  • Change post status in WordPress to 'draft'
  • Call endpoint again
  • Verify response contains wordpress_status: 'draft'

3. Test Custom Columns Removed

  • Go to WordPress admin → Posts → All Posts
  • Verify no "Taxonomy" or "Attribute" columns appear
  • Verify only native WP columns (Title, Author, Categories, Tags, Date) are shown

4. Test Tags, Categories, Images

  • Create content in IGNY8 with:
    • primary_keyword: "SEO Strategy"
    • secondary_keywords: ["Digital Marketing", "Content Marketing"]
    • ContentTaxonomyMap: link to taxonomy term "Marketing"
    • Images: 1 featured image, 2 gallery images
  • Publish to WordPress
  • In WordPress admin, check the post:
    • Categories: "Marketing" exists
    • Tags: "SEO Strategy", "Digital Marketing", "Content Marketing" exist
    • Featured image is set
    • Gallery images attached to post

Files Modified

IGNY8 Backend

  1. e:\Projects\...\igny8\backend\igny8_core\tasks\wordpress_publishing.py

    • Added taxonomy term extraction
    • Added image extraction from Images model
    • Added keyword extraction as tags
    • Populated categories, tags, images in payload
  2. e:\Projects\...\igny8\backend\igny8_core\modules\writer\views.py

    • Updated ContentViewSet.publish() to set status='published' immediately (optimistic update)
    • Added ContentViewSet.wordpress_status() endpoint
    • Added error handling to revert status on failure

WordPress Plugin

  1. c:\Users\Hp\vscode\igny8-wp-integration\includes\class-igny8-rest-api.php

    • Updated get_post_status() to accept both WordPress post_id and IGNY8 content_id
    • Enhanced response with more post metadata
  2. c:\Users\Hp\vscode\igny8-wp-integration\admin\class-admin-columns.php

    • Removed render_taxonomy_column() and render_attribute_column()
    • Removed custom taxonomy/attribute column registration
    • Simplified to use only native WP columns

Breaking Changes

None - All changes are backward compatible. The WordPress plugin will still accept old payload formats.


Frontend Integration Required

Published Page - Add WP Status Column

The frontend Published page should:

  1. Add "WordPress Status" column to the table

  2. For each row, call: GET /api/v1/writer/content/{id}/wordpress_status/

  3. Display status with color coding:

    • publish → Green badge "Published"
    • draft → Gray badge "Draft"
    • pending → Yellow badge "Pending"
    • trash → Red badge "Trashed"
    • future → Blue badge "Scheduled"
  4. Optional: Add refresh button to re-check WordPress status

Example:

async function fetchWordPressStatus(contentId) {
  const response = await fetch(`/api/v1/writer/content/${contentId}/wordpress_status/`);
  const data = await response.json();
  return data.data.wordpress_status; // 'publish', 'draft', etc.
}

Summary

Status: All 4 issues fixed and ready for testing

Impact:

  • Better UX: Users see immediate status changes
  • Complete data sync: Tags, categories, images now sync to WordPress
  • Cleaner admin: Removed confusing custom columns
  • Monitoring: Can now check WordPress status from IGNY8

Next Steps:

  1. Test all fixes in staging environment
  2. Update frontend to use wordpress_status endpoint
  3. Add WP Status column to Published page UI
  4. Monitor Celery logs for any publishing errors

Generated: November 30, 2025
Priority: HIGH - Core publishing functionality
Breaking Changes: None