# Post Migration Guide This guide explains how to migrate posts between WordPress sites using the SEO automation tool. ## Overview The migration feature allows you to move posts from one WordPress site to another while preserving: - Post content (title, body, excerpt) - Categories (automatically created if they don't exist) - Tags (automatically created if they don't exist) - SEO metadata (RankMath, Yoast SEO) - Post slug ## Migration Modes There are two ways to migrate posts: ### 1. CSV-Based Migration Migrate specific posts listed in a CSV file. **Requirements:** - CSV file with at least two columns: `site` and `post_id` **Usage:** ```bash # Basic migration (posts deleted from source after migration) ./seo migrate posts_to_migrate.csv --destination mistergeek.net # Keep posts on source site ./seo migrate posts_to_migrate.csv --destination mistergeek.net --keep-source # Publish immediately instead of draft ./seo migrate posts_to_migrate.csv --destination mistergeek.net --post-status publish # Custom output file for migration report ./seo migrate posts_to_migrate.csv --destination mistergeek.net --output custom_report.csv ``` ### 2. Filtered Migration Migrate posts based on filters (category, date, etc.). **Usage:** ```bash # Migrate all posts from source to destination ./seo migrate --source webscroll.fr --destination mistergeek.net # Migrate posts from specific categories ./seo migrate --source webscroll.fr --destination mistergeek.net --category-filter VPN "Torrent Clients" # Migrate posts with specific tags ./seo migrate --source webscroll.fr --destination mistergeek.net --tag-filter "guide" "tutorial" # Migrate posts by date range ./seo migrate --source webscroll.fr --destination mistergeek.net --date-after 2024-01-01 --date-before 2024-12-31 # Limit number of posts ./seo migrate --source webscroll.fr --destination mistergeek.net --limit 10 # Combine filters ./seo migrate --source webscroll.fr --destination mistergeek.net \ --category-filter VPN \ --date-after 2024-01-01 \ --limit 5 \ --keep-source ``` ## Command Options ### Required Options - `--destination`, `--to`: Destination site (mistergeek.net, webscroll.fr, hellogeek.net) - `--source`, `--from`: Source site (for filtered migration only) - CSV file: Path to CSV with posts (for CSV-based migration) ### Optional Options | Option | Description | Default | |--------|-------------|---------| | `--keep-source` | Keep posts on source site after migration | Delete after migration | | `--post-status` | Status for migrated posts (draft, publish, pending) | draft | | `--no-categories` | Don't create categories automatically | Create categories | | `--no-tags` | Don't create tags automatically | Create tags | | `--category-filter` | Filter by category names (filtered migration) | All categories | | `--tag-filter` | Filter by tag names (filtered migration) | All tags | | `--date-after` | Migrate posts after this date (YYYY-MM-DD) | No limit | | `--date-before` | Migrate posts before this date (YYYY-MM-DD) | No limit | | `--limit` | Maximum number of posts to migrate | No limit | | `--output`, `-o` | Custom output file for migration report | Auto-generated | | `--dry-run` | Preview what would be done without doing it | Execute | | `--verbose`, `-v` | Enable verbose logging | Normal logging | ## Migration Process ### What Gets Migrated 1. **Post Content** - Title - Body content (HTML preserved) - Excerpt - Slug 2. **Categories** - Mapped from source to destination - Created automatically if they don't exist on destination - Hierarchical structure preserved (parent-child relationships) 3. **Tags** - Mapped from source to destination - Created automatically if they don't exist on destination 4. **SEO Metadata** - RankMath title and description - Yoast SEO title and description - Focus keywords ### What Doesn't Get Migrated - Featured images (must be re-uploaded manually) - Post author (uses destination site's default) - Comments (not transferred) - Custom fields (except SEO metadata) - Post revisions ## Migration Report After migration, a CSV report is generated in `output/` with the following information: ```csv source_site,source_post_id,destination_site,destination_post_id,title,status,categories_migrated,tags_migrated,deleted_from_source webscroll.fr,123,mistergeek.net,456,"VPN Guide",draft,3,5,True ``` ## Examples ### Example 1: Migrate Specific Posts from CSV 1. Create a CSV file with posts to migrate: ```csv site,post_id,title webscroll.fr,123,VPN Guide webscroll.fr,456,Torrent Tutorial ``` 2. Run migration: ```bash ./seo migrate my_posts.csv --destination mistergeek.net ``` ### Example 2: Migrate All VPN Content ```bash ./seo migrate --source webscroll.fr --destination mistergeek.net \ --category-filter VPN "VPN Reviews" \ --post-status draft \ --keep-source ``` ### Example 3: Migrate Recent Content ```bash ./seo migrate --source webscroll.fr --destination mistergeek.net \ --date-after 2024-06-01 \ --limit 20 ``` ### Example 4: Preview Migration ```bash ./seo migrate --source webscroll.fr --destination mistergeek.net \ --category-filter VPN \ --dry-run ``` ## Best Practices ### Before Migration 1. **Backup both sites** - Always backup before bulk operations 2. **Test with a few posts** - Migrate 1-2 posts first to verify 3. **Check category structure** - Review destination site's categories 4. **Plan URL redirects** - If deleting from source, set up redirects ### During Migration 1. **Use dry-run first** - Preview what will be migrated 2. **Start with drafts** - Review before publishing 3. **Monitor logs** - Watch for errors or warnings 4. **Limit batch size** - Migrate in batches of 10-20 posts ### After Migration 1. **Review migrated posts** - Check formatting and categories 2. **Add featured images** - Manually upload if needed 3. **Set up redirects** - From old URLs to new URLs 4. **Update internal links** - Fix cross-site links 5. **Monitor SEO** - Track rankings after migration ## Troubleshooting ### Common Issues **1. "Site not found" error** - Check site name is correct (mistergeek.net, webscroll.fr, hellogeek.net) - Verify credentials in config.yaml or .env **2. "Category already exists" warning** - This is normal - the migrator found a matching category - The existing category will be used **3. "Failed to create post" error** - Check WordPress REST API is enabled - Verify user has post creation permissions - Check authentication credentials **4. Posts missing featured images** - Featured images are not migrated automatically - Upload images manually to destination site - Update featured image on migrated posts **5. Categories not matching** - Categories are matched by name (case-insensitive) - "VPN" and "vpn" will match - "VPN Guide" and "VPN" will NOT match - new category created ## API Usage You can also use the migration feature programmatically: ```python from seo.app import SEOApp app = SEOApp() # CSV-based migration app.migrate( csv_file='output/posts_to_migrate.csv', destination_site='mistergeek.net', create_categories=True, create_tags=True, delete_after=False, status='draft' ) # Filtered migration app.migrate_by_filter( source_site='webscroll.fr', destination_site='mistergeek.net', category_filter=['VPN', 'Software'], date_after='2024-01-01', limit=10, create_categories=True, delete_after=False, status='draft' ) ``` ## Related Commands - `seo export` - Export posts from all sites - `seo editorial_strategy` - Analyze and get migration recommendations - `seo category_propose` - Get AI category recommendations ## See Also - [README.md](README.md) - Main documentation - [ARCHITECTURE.md](ARCHITECTURE.md) - System architecture - [CATEGORY_MANAGEMENT_GUIDE.md](CATEGORY_MANAGEMENT_GUIDE.md) - Category management