519 lines
16 KiB
Markdown
519 lines
16 KiB
Markdown
# 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:**
|
|
```python
|
|
# 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/`
|
|
|
|
```python
|
|
@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()`
|
|
|
|
```php
|
|
/**
|
|
* 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:**
|
|
```php
|
|
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:**
|
|
```php
|
|
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:
|
|
|
|
```python
|
|
# 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:**
|
|
```python
|
|
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)
|
|
```
|
|
|
|
2. **Extract images from Images model:**
|
|
```python
|
|
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
|
|
})
|
|
```
|
|
|
|
3. **Add keywords as tags:**
|
|
```python
|
|
# 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
|
|
```
|
|
|
|
4. **Send complete payload to WordPress:**
|
|
```python
|
|
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:**
|
|
```php
|
|
// 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');
|
|
}
|
|
}
|
|
```
|
|
|
|
2. **Tags:**
|
|
```php
|
|
// 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');
|
|
}
|
|
}
|
|
```
|
|
|
|
3. **Featured Image:**
|
|
```php
|
|
if (!empty($content_data['featured_image_url'])) {
|
|
igny8_set_featured_image($post_id, $content_data['featured_image_url']);
|
|
}
|
|
```
|
|
|
|
4. **Gallery Images:**
|
|
```php
|
|
if (!empty($content_data['gallery_images'])) {
|
|
igny8_set_image_gallery($post_id, $content_data['gallery_images']);
|
|
}
|
|
```
|
|
|
|
5. **Keywords (stored as post meta):**
|
|
```php
|
|
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:**
|
|
```javascript
|
|
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
|