# blog-production Full Instructions

## Production Status

- ✅ Migration complete (2026-01-14)
- ✅ WordPress no longer required or accessed
- ✅ All content managed via JSON files
- ✅ All images stored locally (`/v2/img/insights/`)
- ✅ Zero render-time processing

## Recovery Workflow

**Status:** Recovery in progress (2026-01-14)

After migration, improvements were lost and need to be restored:

- **FAQs:** 38 posts need FAQ recovery (~820+ FAQs total)
- **Content Expansions:** 72 posts need word count expansion
- **Internal Links:** Need verification

**Recovery Process:**

1. **Before Making Changes:**

   ```bash
   php v2/scripts/blog/prevent-improvement-reversion.php --backup --all
   ```

2. **After Making Changes:**

   ```bash
   php v2/scripts/blog/prevent-improvement-reversion.php --validate
   ```

3. **Track Progress:**
   ```bash
   php v2/scripts/blog/track-recovery-progress.php --update --dashboard
   ```

**Recovery Priority:**

- High: Top 20 traffic posts with documented FAQs
- Medium: Remaining Ratgeber/Lexikon posts
- Low: Inside Ordio posts (lower SEO priority)

**Note:** Historical recovery workflow documentation has been deleted and is available in Git history. See `docs/content/blog/PRODUCTION_WORKFLOW_GUIDE.md` for current production workflows.

## Content Writing Best Practices

**See:** `.cursor/rules/content-writing.mdc` for comprehensive content writing guidelines.

### Natural Language Writing

When editing or creating blog content:

- ✅ **Human-first content:** Write for humans first, optimize for search engines second
- ✅ **Natural language:** Use conversational tone, vary sentence structures
- ✅ **AI content avoidance:** Avoid AI content tells (overly formal language, repetitive structures)
- ✅ **Specific examples:** Include concrete examples, data points, and scenarios
- ✅ **E-E-A-T:** Demonstrate Experience, Expertise, Authoritativeness, Trustworthiness

**Key Resources:**

- `docs/content/CONTENT_WRITING_BEST_PRACTICES_2026.md` - Comprehensive content writing guide
- `docs/content/AI_CONTENT_AVOIDANCE_GUIDE.md` - AI content avoidance guide
- `docs/content/CONTENT_CREATION_WORKFLOW_2026.md` - Content creation workflow
- `docs/content/CONTENT_UPDATE_WORKFLOW_2026.md` - Content update workflow

### SISTRIX Integration

When creating or updating content:

- **Review SISTRIX data:** Check competition levels, search intent, PAA questions
- **Use data-driven decisions:** Competition → Content depth, PAA → FAQs
- **Optimize based on data:** SERP features → Optimization opportunities

**See:** `docs/content/SISTRIX_CONTENT_INTEGRATION_GUIDE.md` for complete workflow.

## Content Management

### Editing Posts

**Direct JSON Editing:**

1. Open: `v2/data/blog/posts/{category}/{slug}.json`
2. Edit `content.html` field directly
3. Update `content.text` field (plain text version)
4. Apply content writing best practices (natural language, AI avoidance)
5. Save - changes appear immediately

**No Processing Required:**

- Content is pre-processed at creation time
- No WordPress extraction needed
- No content transformation needed
- Direct editing workflow

### Adding New Posts

**Create JSON File:**

1. Create: `v2/data/blog/posts/{category}/{slug}.json`
2. Use existing post as template
3. Fill required fields:
   - `slug`, `title`, `category`, `url`
   - `content.html` (pre-processed HTML)
   - `content.text` (plain text)
   - `featured_image` (if applicable)
   - `faqs` array (if applicable)
   - `publication_date`, `modified_date`

**No WordPress Required:**

- No extraction from WordPress
- No WordPress CMS access needed
- Direct JSON creation workflow

### Image Management

**Adding Images:**

1. Upload to: `/v2/img/insights/filename.webp`
2. Reference as: `/insights/bilder/filename.webp`
3. Add to `featured_image` object if needed

**Image Requirements:**

- Format: WebP (preferred)
- Storage: `/v2/img/insights/`
- Public URL: `/insights/bilder/`
- Responsive: Include srcset for multiple sizes

## WordPress Status

### WordPress No Longer Used

- ❌ No WordPress extraction scripts
- ❌ No WordPress CMS access
- ❌ No WordPress API calls
- ❌ No WordPress fallback code
- ✅ All content in JSON files
- ✅ All images local

### Deprecated Functions

The following functions are deprecated (kept for backward compatibility):

- `extract_slug_and_category()` - deprecated
- `transform_url()` - deprecated
- `extract_title()` - deprecated
- `extract_wordpress_image_url()` - deprecated

These functions are no longer used but preserved for reference.

## Backup Procedures

**Before Making Changes:**

```bash
python3 scripts/blog/backup-blog-content.py --manual
```

**Restore from Backup:**

```bash
python3 scripts/blog/restore-from-snapshot.py docs/backups/blog-snapshots/{timestamp}
```

**Note:** WordPress master backups are historical only. Use snapshot backups for current content.

## Validation

**Validate Post Structure:**

```bash
php v2/scripts/blog/validate-blog-content.php
```

**Validate Images:**

```bash
python3 v2/scripts/blog/validate-images-links.py
```

**Validate Links:**

```bash
php v2/scripts/blog/validate-link-quality.php
```

**Validate Internal Links Exist (CRITICAL - Before Saving):**

```bash
# Validate HTML file before updating post
php v2/scripts/blog/validate-internal-links-exist.php --html=path/to/content.html

# Validate existing post
php v2/scripts/blog/validate-internal-links-exist.php --post=slug --category=lexikon

# Strict mode (exit with error if broken links found)
php v2/scripts/blog/validate-internal-links-exist.php --html=path/to/content.html --strict
```

**CRITICAL:** Always run `validate-internal-links-exist.php` before saving blog post content to prevent broken internal links. This script checks that all internal links point to existing pages (blog posts, product pages, tool pages, template pages, comparison pages, pillar pages).

**Validate Anchor Text Quality:**

```bash
php v2/scripts/blog/validate-anchor-text-quality.php --all
```

**Validate Tier 1 Posts:**

```bash
python3 scripts/blog/validate-tier1-links.py
```

## Internal Link Quality Requirements

### Manual Review Required

**CRITICAL:** All internal links added by scripts must be manually reviewed before deployment.

**Review Checklist:**

- [ ] Anchor text is descriptive and keyword-rich
- [ ] Anchor text fits naturally in the sentence (grammatically correct)
- [ ] Anchor text is not a generic pattern ("mehr zu", "weitere Informationen zu")
- [ ] Link placement is contextually appropriate (not random)
- [ ] Link adds value to the content
- [ ] No awkward spacing or grammar issues

### Browser Testing Required

**CRITICAL:** All posts with internal links must be browser tested to verify visual quality.

**Browser Testing Checklist:**

1. Open post in browser: `localhost:8003/insights/{category}/{slug}/`
2. Verify links appear correctly
3. Check if links fit naturally in content flow
4. Test link destinations work
5. Verify no awkward spacing or visual issues
6. Document any issues found

**Testing Command:**

```bash
# Test specific post
open http://localhost:8003/insights/{category}/{slug}/

# Or use browser automation
python3 scripts/blog/browser-test-links.sh --post={slug} --category={category}
```

### Prevention Measures

**Script Validation:**

- All linking scripts must validate anchor text quality before adding links
- Use `validate-anchor-text-quality.php` to catch problematic patterns
- Never use generic patterns like "mehr zu [word]" or "weitere Informationen zu [word]"

**Documentation:**

- See `docs/content/blog/guides/INTERNAL_LINKING_GUIDE.md` for complete guidelines
- See `docs/content/blog/INTERNAL_LINK_QUALITY_PREVENTION.md` for prevention measures

## Common Patterns

### Pattern: Edit Post Content

```php
// 1. Open JSON file
// 2. Edit content.html field
// 3. Update content.text field
// 4. Update modified_date
// 5. Save file
```

### Pattern: Add FAQ

```json
{
  "faqs": [
    {
      "question": "Question text?",
      "answer": "Answer text (40-80 words)..."
    }
  ]
}
```

### Pattern: Add Featured Image

```json
{
  "featured_image": {
    "src": "/insights/bilder/filename.webp",
    "alt": "Description",
    "width": 800,
    "height": 600,
    "srcset": [
      { "src": "/insights/bilder/filename-640w.webp", "width": 640 },
      { "src": "/insights/bilder/filename-1280w.webp", "width": 1280 }
    ]
  }
}
```

## Performance

- **Render Time:** <0.02ms per post
- **Zero Processing:** All content pre-processed
- **Fast Loading:** Static JSON files
- **Optimized:** Images lazy-loaded, responsive

## Recovery Workflow

**Status:** Recovery in progress (2026-01-14)

After migration, improvements were lost and need to be restored:

- **FAQs:** 38 posts need FAQ recovery (~820+ FAQs total)
- **Content Expansions:** 72 posts need word count expansion
- **Internal Links:** Need verification

**Recovery Process:**

1. **Before Making Changes:**

   ```bash
   php v2/scripts/blog/prevent-improvement-reversion.php --backup --all
   ```

2. **After Making Changes:**

   ```bash
   php v2/scripts/blog/prevent-improvement-reversion.php --validate
   ```

3. **Track Progress:**
   ```bash
   php v2/scripts/blog/track-recovery-progress.php --update --dashboard
   ```

**Recovery Priority:**

- High: Top 20 traffic posts with documented FAQs
- Medium: Remaining Ratgeber/Lexikon posts
- Low: Inside Ordio posts (lower SEO priority)

**Gap Audit:**

```bash
php v2/scripts/blog/audit-improvement-gaps.php
```

## PHP Extension Requirements

**CRITICAL**: Blog system uses PHP extensions that must be checked before use to prevent production failures.

### Required Extensions

- **`mbstring`** - Required for UTF-8 text processing in FAQ schema generation and content handling
- **`iconv`** - Fallback for mbstring encoding operations
- **`json`** - Required for JSON file parsing (PHP 8.0+ includes by default)

### Extension Check Pattern

**Before using mbstring functions:**

```php
// ✅ CORRECT: Check function exists before use
if (function_exists('mb_check_encoding') && function_exists('mb_convert_encoding')) {
    if (!mb_check_encoding($text, 'UTF-8')) {
        $text = mb_convert_encoding($text, 'UTF-8', 'UTF-8');
    }
} else {
    // Fallback: Use iconv if available
    if (function_exists('iconv')) {
        $text = iconv('UTF-8', 'UTF-8//IGNORE', $text);
    }
    // If neither available, continue as-is
}
```

### Pre-Deployment Extension Check

**Before deploying blog changes:**

1. Run extension validator: `php v2/scripts/dev-helpers/check-php-extensions.php`
2. Verify mbstring available: `php -r "echo extension_loaded('mbstring') ? 'OK' : 'MISSING';"`
3. Test H1 highlighting fallback: `php v2/scripts/blog/test-title-highlighting.php --simulate-no-mbstring`
4. Test FAQ schema generation with mbstring disabled (if possible)
5. Check error logs for fallback usage

**Highlighting (PostHeader):** `highlight_title_keywords()` in blog-template-helpers.php must guard all mb_ calls. Use `_has_mbstring()` or `function_exists()` checks. See `docs/content/blog/H1_HIGHLIGHTING_PRODUCTION_FIX.md`.

### Related Files

- `v2/config/blog-schema-generator.php` - Uses mbstring for FAQ schema generation (has fallback)
- `v2/config/blog-template-helpers.php` - Contains `_has_mbstring()`, fallback functions, and `highlight_title_keywords()`
- `v2/components/blog/PostHeader.php` - Renders H1 with keyword highlighting
- `v2/components/blog/BlogFAQ.php` - Uses `function_exists` checks for extension functions

### Fallback Functions Available

The blog system includes fallback functions in `blog-template-helpers.php`:

- `_has_mbstring()` - Check mbstring availability
- `_mb_strlen_fallback()` - Fallback for `mb_strlen()`
- `_mb_substr_fallback()` - Fallback for `mb_substr()`
- `_mb_strtolower_fallback()` - Fallback for `mb_strtolower()`

**Usage pattern:**

```php
$length = _has_mbstring() ? mb_strlen($text, 'UTF-8') : _mb_strlen_fallback($text, 'UTF-8');
```

### Related Documentation

- `.cursor/rules/php-extensions.mdc` - Complete PHP extension dependency patterns
- `docs/development/PHP_EXTENSION_DEPENDENCIES.md` - Comprehensive guide
- `docs/development/PHP_EXTENSION_FALLBACK_PATTERNS.md` - Fallback patterns

```

**Note:** Historical recovery documentation has been deleted and is available in Git history. See `docs/content/blog/PRODUCTION_WORKFLOW_GUIDE.md` for current production workflows.

## Related Documentation

- `docs/content/blog/PRODUCTION_WORKFLOW_GUIDE.md` - Complete production workflow
- `docs/content/blog/MIGRATION_COMPLETION_REPORT_2026-01-14.md` - Migration status
- `docs/content/blog/BLOG_QUICK_REFERENCE.md` - Quick reference
- `docs/content/blog/TROUBLESHOOTING_GUIDE.md` - Troubleshooting
```
