This commit is contained in:
alorig
2025-12-01 09:32:06 +05:00
parent aeaac01990
commit 71a38435b1
46 changed files with 75 additions and 17130 deletions

View File

@@ -1,239 +0,0 @@
# Content Publishing Fixes Applied
**Date:** November 29, 2025
**Issue:** Only title was being published to WordPress, not the full content_html
**Root Cause:** WordPress REST endpoint was fetching from wrong API endpoint (Tasks model instead of Content model) + Field name mismatches
---
## Critical Issue Identified
**Problem:** WordPress posts were created with only the title, no content body.
**Root Cause Analysis:**
1. WordPress REST endpoint (`class-igny8-rest-api.php`) was making an API callback to `/writer/tasks/{task_id}/`
2. This endpoint returns the **Tasks** model, which does NOT have a `content_html` field
3. Tasks model only has: `title`, `description`, `keywords` (no actual content)
4. Meanwhile, IGNY8 backend was already sending full `content_html` in the POST body
5. WordPress was ignoring the POST body and using the API callback response instead
---
## Fixes Applied
### Fix #1: WordPress REST Endpoint (CRITICAL)
**File:** `includes/class-igny8-rest-api.php`
**Function:** `publish_content_to_wordpress()`
**Lines Modified:** 460-597
**What Changed:**
-**REMOVED** 80+ lines of API callback logic (lines 507-545)
-**REMOVED** call to `/writer/tasks/{task_id}/` endpoint
-**CHANGED** to parse POST body directly: `$content_data = $request->get_json_params()`
-**ADDED** validation for required fields: `content_id`, `title`, `content_html`
-**ADDED** debug logging when `IGNY8_DEBUG` flag is defined
**Before:**
```php
// WordPress was making a redundant API call
$response = $api->get("/writer/tasks/{$task_id}/");
$content_data = $response['data'] ?? array(); // ❌ This had NO content_html
```
**After:**
```php
// WordPress now uses the data IGNY8 already sent
$content_data = $request->get_json_params(); // ✅ This has content_html
```
**Impact:** WordPress now receives and uses the full `content_html` field sent by IGNY8 backend.
---
### Fix #2: IGNY8 Backend Payload (Field Name Corrections)
**File:** `backend/igny8_core/tasks/wordpress_publishing.py`
**Function:** `publish_content_to_wordpress()`
**Lines Modified:** 54-89
**Field Name Fixes:**
| ❌ Old (Wrong) | ✅ New (Correct) | Reason |
|---|---|---|
| `content.brief` | Generate from `content_html` | Content model has no `brief` field |
| `content.author.email` | `None` | Content model has no `author` field |
| `content.published_at` | `None` | Content model has no `published_at` field |
| `getattr(content, 'seo_title', '')` | `content.meta_title or ''` | Correct field is `meta_title` |
| `getattr(content, 'seo_description', '')` | `content.meta_description or ''` | Correct field is `meta_description` |
| `getattr(content, 'focus_keywords', [])` | `content.secondary_keywords or []` | Correct field is `secondary_keywords` |
| `content.featured_image.url` | `None` | Content model has no `featured_image` field |
| `content.sectors.all()` | Empty array | Content has `sector` (ForeignKey), not `sectors` (many-to-many) |
| `content.clusters.all()` | Empty array | Content has `cluster` (ForeignKey), not `clusters` (many-to-many) |
| `getattr(content, 'tags', [])` | Empty array | Content model has no `tags` field |
**New Fields Added:**
-`primary_keyword`: `content.primary_keyword or ''`
-`cluster_id`: `content.cluster.id if content.cluster else None`
-`sector_id`: `content.sector.id if content.sector else None`
**Excerpt Generation:**
```python
# Generate excerpt from content_html (Content model has no 'brief' field)
excerpt = ''
if content.content_html:
from django.utils.html import strip_tags
excerpt = strip_tags(content.content_html)[:150].strip()
if len(content.content_html) > 150:
excerpt += '...'
```
**Impact:** Payload now uses fields that actually exist on Content model, preventing AttributeErrors.
---
## Content Model Structure (Reference)
**File:** `backend/igny8_core/business/content/models.py`
**Model:** `Content(SiteSectorBaseModel)`
### Fields That Exist ✅
- `title` (CharField)
- `content_html` (TextField) ← **The actual content**
- `meta_title` (CharField) ← SEO title
- `meta_description` (TextField) ← SEO description
- `primary_keyword` (CharField)
- `secondary_keywords` (JSONField)
- `cluster` (ForeignKey to Clusters)
- `content_type` (CharField: post/page/product/taxonomy)
- `content_structure` (CharField: article/guide/etc)
- `status` (CharField: draft/review/published)
- `source` (CharField: igny8/wordpress)
- `external_id`, `external_url`, `external_type`, `sync_status`
- `created_at`, `updated_at` (from base model)
- `account`, `site`, `sector` (from SiteSectorBaseModel)
### Fields That Do NOT Exist ❌
-`brief` or `excerpt`
-`author`
-`published_at`
-`featured_image`
-`seo_title` (it's `meta_title`)
-`seo_description` (it's `meta_description`)
-`focus_keywords` (it's `secondary_keywords`)
-`sectors` (many-to-many)
-`clusters` (many-to-many)
-`tags`
---
## WordPress Function Already Handles content_html Correctly
**File:** `sync/igny8-to-wp.php`
**Function:** `igny8_create_wordpress_post_from_task()`
**Lines:** 73-200
This function was already correctly implemented:
```php
// Stage 1 Schema: accept content_html (new) or content (legacy fallback)
$content_html = $content_data['content_html'] ?? $content_data['content'] ?? '';
// ...
$post_data = array(
'post_title' => sanitize_text_field($content_data['title'] ?? 'Untitled'),
'post_content' => wp_kses_post($content_html), // ✅ Uses content_html
'post_excerpt' => sanitize_text_field($excerpt),
// ...
);
$post_id = wp_insert_post($post_data);
```
**No changes needed** - this function properly extracts `content_html` and creates the WordPress post.
---
## Data Flow (Fixed)
### Before Fix ❌
```
IGNY8 Backend
├─ Sends POST with content_html ✓
└─ WordPress receives it ✓
├─ Ignores POST body ❌
├─ Calls /writer/tasks/{id}/ ❌
└─ Gets Tasks model (no content_html) ❌
└─ Creates post with only title ❌
```
### After Fix ✅
```
IGNY8 Backend
├─ Sends POST with content_html ✓
└─ WordPress receives it ✓
├─ Parses POST body ✓
├─ Validates content_html present ✓
└─ Creates post with full content ✓
```
---
## Testing Checklist
To verify the fixes work:
1. ✅ Create a Content object in IGNY8 with full `content_html`
2. ✅ Ensure Content has: `title`, `content_html`, `meta_title`, `meta_description`, `cluster`, `sector`
3. ✅ Trigger `publish_content_to_wordpress` Celery task
4. ✅ Verify WordPress receives full payload with `content_html`
5. ✅ Confirm WordPress post created with:
- Full content body (not just title)
- Correct SEO metadata
- Cluster and sector IDs stored
6. ✅ Check WordPress postmeta for:
- `_igny8_content_id`
- `_igny8_task_id`
- `_igny8_cluster_id`
- `_igny8_sector_id`
---
## Debug Logging
To enable verbose logging, add to WordPress `wp-config.php`:
```php
define('IGNY8_DEBUG', true);
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
```
This will log:
- Content ID received
- Title received
- Content HTML length
- All REST API responses
---
## Summary
**Files Modified:**
1. `includes/class-igny8-rest-api.php` - WordPress REST endpoint
2. `backend/igny8_core/tasks/wordpress_publishing.py` - IGNY8 backend payload
**Core Changes:**
1. WordPress now uses POST body data instead of making redundant API call
2. IGNY8 backend uses correct Content model field names
3. Excerpt generated from content_html automatically
4. Cluster and sector sent as IDs, not arrays
**Result:** Full content (including HTML body) now publishes to WordPress correctly.
---
**Generated:** 2025-11-29
**Status:** FIXES APPLIED - Ready for testing
**Priority:** HIGH - Core functionality restored