# Blog Migration Troubleshooting Guide

**Last Updated:** 2026-01-14

Comprehensive troubleshooting guide for blog migration issues, common problems, and solutions.

## Common Issues & Solutions

### Issue: Blog Post Content Not Rendering

**Symptoms:**
- Blog post page loads but content area is empty
- Post title and header display, but no content body
- `<article>` tag missing from HTML source
- Browser console shows no errors

**Root Cause:**
- PHP fatal error preventing content section from rendering
- `PostContent.php` component file missing on server
- Include path incorrect
- File permissions issue
- Variable scope issues in included components
- PHP opcache serving stale cached version

**Solution:**
1. **Check PHP error logs** for fatal errors or warnings
2. Verify `v2/components/blog/PostContent.php` exists on server
3. Check file permissions (should be readable by web server)
4. Verify include path in `v2/pages/blog/post.php`:
   ```php
   $post_content_path = __DIR__ . '/../../components/blog/PostContent.php';
   ```
5. **Clear PHP opcache** if changes aren't appearing:
   ```php
   opcache_reset(); // Or restart PHP-FPM/Apache
   ```
6. Comprehensive error handling is implemented - content should render even if component missing

**Debugging Steps:**
1. Check if `<article>` tag appears in HTML source
2. Check PHP error logs for fatal errors
3. Verify post JSON file loads correctly: `load_blog_post($category, $slug)`
4. Verify `$html_content` has value before rendering
5. Test PostContent.php include directly

**Prevention:**
- Ensure all blog component files are committed to git
- Verify deployment includes all files from `v2/components/blog/`
- Test include paths work correctly
- Use comprehensive try-catch error handling
- Always provide fallback content rendering

### Issue: Images Not Loading

**Symptoms:**
- Broken image icons
- 404 errors for image URLs
- Images load from WordPress URL but not local path

**Root Cause:**
- Image files not deployed to server
- `.htaccess` rewrite rule missing or incorrect
- Image path format incorrect

**Solution:**
1. Verify images exist in `v2/img/insights/` directory
2. Check `.htaccess` has rewrite rule:
   ```apache
   RewriteRule ^insights/bilder/(.+)$ v2/img/insights/$1 [L]
   ```
3. Verify image paths in JSON use format: `/insights/bilder/filename.webp`
4. Check file permissions on image directory

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

### Issue: Invalid JSON Files

**Symptoms:**
- Posts return 404 even though file exists
- PHP errors in logs about JSON parsing
- Posts don't display correctly

**Root Cause:**
- JSON syntax errors
- Missing required fields
- Invalid data types

**Solution:**
1. Validate JSON syntax:
   ```bash
   python3 v2/scripts/blog/test-all-posts.py
   ```
2. Check required fields present:
   - `slug`, `title`, `category`, `content`, `publication_date`, `url`
3. Verify `content.html` and `content.text` exist
4. Check featured image path format

**Prevention:**
- Use validation scripts before committing
- Validate JSON structure matches schema
- Test posts load correctly after changes

### Issue: Schema Markup Not Present

**Symptoms:**
- No JSON-LD schema in page source
- Google Rich Results Test fails
- Missing structured data

**Root Cause:**
- Schema generator not called
- Schema output not included in template
- JSON encoding errors

**Solution:**
1. Verify `render_blog_schema()` called in template:
   ```php
   $schema = render_blog_schema('post', $post);
   echo $schema;
   ```
2. Check schema generator file exists: `v2/config/blog-schema-generator.php`
3. Verify JSON encoding succeeds (check PHP error logs)
4. Test schema output manually

**Validation:**
- Use Google Rich Results Test
- Check page source for `<script type="application/ld+json">`
- Validate JSON syntax

### Issue: SEO Meta Tags Missing

**Symptoms:**
- No Open Graph tags
- Missing meta description
- Title tag incorrect

**Root Cause:**
- Meta generator not called
- Meta tags not output in head
- Missing data in JSON files

**Solution:**
1. Verify `generate_blog_meta()` called:
   ```php
   $meta_tags = generate_blog_meta('post', $post);
   echo $meta_tags;
   ```
2. Check meta generator file: `v2/config/blog-meta-generator.php`
3. Verify post JSON has `meta.title` and `meta.description`
4. Check meta tags output in `<head>` section

### Issue: Related Posts Not Displaying

**Symptoms:**
- Related posts section empty
- No related posts shown
- Wrong posts displayed

**Root Cause:**
- Related posts algorithm failing
- No related posts found
- Algorithm scoring issues

**Solution:**
1. Check `load_related_posts_enhanced()` function works
2. Verify post has topics/clusters for matching
3. Check algorithm parameters (limit, scoring)
4. Review error logs for exceptions

**Debugging:**
```php
$related_posts = load_related_posts_enhanced($slug, $category, 12);
var_dump($related_posts); // Debug output
```

### Issue: Pagination Not Working

**Symptoms:**
- Pagination links don't work
- Wrong page numbers displayed
- Infinite scroll issues

**Root Cause:**
- URL parsing incorrect
- Page number calculation wrong
- Client-side filtering conflicts

**Solution:**
1. Verify URL pattern matches `.htaccess` rewrite rules
2. Check pagination calculation:
   ```php
   $current_page = max(1, intval($_GET['page']));
   $offset = ($current_page - 1) * $posts_per_page;
   ```
3. Test pagination URLs manually
4. Check client-side filtering doesn't interfere

### Issue: Category Filtering Not Working

**Symptoms:**
- All posts show regardless of category
- Category navigation doesn't filter
- Wrong posts in category archive

**Root Cause:**
- Category filtering logic incorrect
- Client-side filtering JavaScript error
- Category slug mismatch

**Solution:**
1. Verify category filtering in `load_blog_posts_by_category()`
2. Check category slugs match JSON files
3. Test category archive pages directly
4. Check browser console for JavaScript errors

### Issue: Performance Issues

**Symptoms:**
- Slow page load times
- High LCP (Largest Contentful Paint)
- Poor PageSpeed score

**Root Cause:**
- Images not optimized
- CSS/JS not minified
- No lazy loading
- Large JSON files

**Solution:**
1. Optimize images (WebP format, proper sizing)
2. Minify CSS/JS: `npm run minify`
3. Implement lazy loading for images
4. Check Core Web Vitals scores
5. Review PageSpeed Insights recommendations

**Optimization Checklist:**
- [ ] Images converted to WebP
- [ ] CSS minified (`blog.min.css`)
- [ ] JS minified and deferred
- [ ] Lazy loading implemented
- [ ] Caching headers set
- [ ] Gzip compression enabled

## Error Handling Patterns

### PostContent Component Include

**Pattern:**
```php
try {
    $html_content = $post['content']['html'] ?? '';
    if (empty($html_content)) {
        error_log("WARNING: Empty html_content for {$category}/{$slug}");
    }
    
    $post_content_path = __DIR__ . '/../../components/blog/PostContent.php';
    if (file_exists($post_content_path)) {
        include $post_content_path;
    } else {
        // Fallback: output content directly
        error_log("PostContent.php not found at: {$post_content_path}");
        echo '<div class="post-content"><div class="post-content-inner">';
        echo $html_content ?: '<p>Content not available.</p>';
        echo '</div></div>';
    }
} catch (Exception $e) {
    error_log("FATAL: Error rendering content: " . $e->getMessage());
    echo '<div class="post-content"><div class="post-content-inner">';
    echo '<p>Error loading content. Please try again later.</p>';
    echo '</div></div>';
} catch (Error $e) {
    error_log("FATAL PHP Error: " . $e->getMessage());
    echo '<div class="post-content"><div class="post-content-inner">';
    echo '<p>Error loading content. Please try again later.</p>';
    echo '</div></div>';
}
```

**Why:** 
- Ensures content always renders even if component file missing
- Catches both Exception and Error (PHP 7+ fatal errors)
- Provides fallback content if rendering fails
- Logs errors for debugging

### Post Loading with Try-Catch

**Pattern:**
```php
try {
    $post = load_blog_post($category, $slug);
} catch (Exception $e) {
    error_log("Error loading blog post {$category}/{$slug}: " . $e->getMessage());
    $post = null;
}

if (!$post) {
    // Show 404 page
    http_response_code(404);
    // ... 404 template
}
```

**Why:** Prevents fatal errors, logs issues, shows user-friendly 404

### Input Sanitization

**Pattern:**
```php
$category = htmlspecialchars(trim($category), ENT_QUOTES, 'UTF-8');
$slug = htmlspecialchars(trim($slug), ENT_QUOTES, 'UTF-8');

// Validate against whitelist
$valid_categories = ['lexikon', 'ratgeber', 'inside-ordio'];
if (!in_array($category, $valid_categories)) {
    // Invalid category - show 404
}
```

**Why:** Prevents XSS attacks, validates input against expected values

## Validation Scripts

### Test All Posts
```bash
python3 v2/scripts/blog/test-all-posts.py
```
Validates JSON structure, required fields, content integrity

### Validate Images and Links
```bash
python3 v2/scripts/blog/validate-images-links.py
```
Checks image files exist, link URLs valid

### Validate Link Quality
```bash
php v2/scripts/blog/validate-link-quality.php
```
Checks link placement, grammar, duplication

### Validate Content
```bash
php v2/scripts/blog/validate-blog-content.php --type=all
```
Comprehensive content validation

## Deployment Checklist

Before deploying blog migration:

- [ ] All 99 post JSON files validated
- [ ] All images exist in `v2/img/insights/`
- [ ] `.htaccess` rewrite rule present
- [ ] All component files present (`v2/components/blog/`)
- [ ] All template files present (`v2/pages/blog/`)
- [ ] Helper files present (`v2/config/blog-*.php`)
- [ ] CSS minified (`blog.min.css`)
- [ ] No PHP errors in logs
- [ ] Test sample posts from each category
- [ ] Verify schema markup present
- [ ] Check SEO meta tags
- [ ] Test pagination
- [ ] Verify related posts work

## Server Requirements

- PHP 7.4+ (for JSON handling, null coalescing)
- Apache with mod_rewrite enabled
- File permissions: 644 for files, 755 for directories
- `.htaccess` file readable

## Related Documentation

- [Testing Checklist](TESTING_CHECKLIST.md)
- [Template Development Guide](guides/TEMPLATE_DEVELOPMENT_GUIDE.md)
- [Component API](reference/COMPONENT_API.md)
- [Image Storage Guide](IMAGE_STORAGE_GUIDE.md)
