WP CLI ile WordPress İçerik Taşıma: wp import ve wp export Kullanımı

WordPress sitenizi taşımak, klonlamak ya da yedekten geri yüklemek söz konusu olduğunda, çoğu sistem yöneticisinin aklına ilk olarak FTP ve veritabanı dışa aktarımı gelir. Oysa WP-CLI’nin wp import ve wp export komutları, bu süreci terminal üzerinden hızlı, tekrarlanabilir ve scriptlenebilir hale getirir. Özellikle birden fazla siteyi yöneten ya da otomatik yedekleme/taşıma pipeline’ları kurmak isteyen sysadminler için bu komutlar gerçek bir zaman tasarrufu sağlar.

WP Export ve Import Nedir, Ne Değildir?

Önce bir şeyi netleştirelim: wp export ve wp import, WordPress’in kendi XML tabanlı WXR (WordPress eXtended RSS) formatını kullanır. Bu format yazıları, sayfaları, yorumları, kategorileri, etiketleri ve özel yazı tiplerini taşır. Ancak tema ayarlarını, eklenti konfigürasyonlarını, medya dosyalarını (binary olarak) ve veritabanı tablolarının tamamını taşımaz.

Tam site taşıması için genellikle şu kombinasyonu kullanırsınız:

  • Veritabanı için wp db export / wp db import
  • Dosyalar için rsync ya da scp
  • İçerik için wp export / wp import

Bu yazıda özellikle içerik taşıma senaryolarına, yani wp export ve wp import komutlarına odaklanacağız. Ancak gerçek dünya örneklerinde diğer araçlarla nasıl birleştirileceğini de göreceğiz.

Ortamın Hazırlanması

WP-CLI’nin sisteminizde kurulu olduğunu varsayıyorum. Değilse birkaç komutla kurabilirsiniz:

curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
wp --info

wp import komutunun çalışması için WordPress sitenizde WordPress Importer eklentisinin kurulu ve aktif olması gerekir. Bunu WP-CLI ile şöyle yapabilirsiniz:

wp plugin install wordpress-importer --activate --path=/var/www/html/hedef-site

Bu adımı atlamak, en sık karşılaşılan hatalardan birinin kaynağıdır. Import komutunu çalıştırdığınızda Error: 'import' is not a registered wp command benzeri bir hata alıyorsanız, büyük ihtimalle eklenti aktif değildir.

wp export Komutunu Anlamak

wp export, sitenizin içeriğini WXR formatında XML dosyasına döker. En basit kullanımı şudur:

wp export --path=/var/www/html/kaynak-site --dir=/tmp/wp-exports/

Bu komut, /tmp/wp-exports/ dizinine bir ya da birden fazla XML dosyası oluşturur. Dosya adı otomatik olarak wordpress.sitename.2024-01-15.000.xml gibi bir format alır.

Filtreleme Seçenekleri

wp export komutunun en güçlü yanı, ne kadar granüler filtreleme yapabildiğinizdir.

–post_type: Hangi yazı tiplerini dışa aktaracağınızı belirtir.

# Sadece yazıları ve sayfaları dışa aktar
wp export --post_type=post,page --dir=/tmp/exports/

# Sadece WooCommerce ürünlerini dışa aktar
wp export --post_type=product --dir=/tmp/exports/

# Tüm içeriği dışa aktar (varsayılan davranış)
wp export --post_type=all --dir=/tmp/exports/

–post_status: Belirli statüdeki yazıları filtreler.

# Sadece yayınlanmış yazıları al
wp export --post_status=publish --dir=/tmp/exports/

# Taslakları da dahil et
wp export --post_status=publish,draft --dir=/tmp/exports/

–start_date ve –end_date: Tarih aralığına göre filtreleme yapar.

# 2023 yılına ait yazıları dışa aktar
wp export --start_date=2023-01-01 --end_date=2023-12-31 --dir=/tmp/exports/

–author: Belirli bir yazara ait içerikleri alır.

# ID'si 3 olan yazara ait içerikleri dışa aktar
wp export --author=3 --dir=/tmp/exports/

–category: Belirli kategori slug’ına göre filtreler.

wp export --category=teknoloji --dir=/tmp/exports/

–max_num_posts: Dışa aktarılacak maksimum yazı sayısını sınırlar. Büyük sitelerde test amaçlı kullanışlıdır.

wp export --max_num_posts=100 --dir=/tmp/exports/

–with_attachments: Ek dosya bilgilerini de dahil eder. Dikkat: Bu seçenek medya URL’lerini XML’e yazar, binary dosyaları taşımaz.

wp export --with_attachments=true --dir=/tmp/exports/

Büyük Sitelerde Export Stratejisi

Yüz binlerce yazısı olan bir sitede tek seferde export yapmak hem bellek hem de zaman sorunlarına yol açabilir. WP-CLI bu durumu --max_num_posts ve --start_date/--end_date kombinasyonuyla çözmenize olanak tanır. Ancak daha pratik bir yaklaşım, yıl bazlı parçalara bölmektir:

#!/bin/bash
# Yıllara göre parçalı export scripti

SITE_PATH="/var/www/html/buyuk-site"
EXPORT_DIR="/backup/wp-exports/$(date +%Y%m%d)"
mkdir -p $EXPORT_DIR

for YEAR in 2019 2020 2021 2022 2023 2024; do
    echo "Exporting year: $YEAR"
    wp export 
        --path=$SITE_PATH 
        --start_date="${YEAR}-01-01" 
        --end_date="${YEAR}-12-31" 
        --dir=$EXPORT_DIR 
        --filename_format="${YEAR}-export.{n}.xml"
done

echo "Export tamamlandi. Dosyalar: $EXPORT_DIR"
ls -lh $EXPORT_DIR

Bu scripti çalıştırarak her yıl için ayrı XML dosyaları elde edersiniz. Daha sonra bu dosyaları sırayla import edebilirsiniz.

wp import Komutunu Anlamak

Import süreci, export’tan biraz daha dikkat ister. Yazarlar, kategoriler ve medya URL’leri gibi konular başlı başına birer karar noktasıdır.

Temel kullanım:

wp import /tmp/exports/wordpress.sitename.2024-01-15.000.xml 
    --authors=create 
    --path=/var/www/html/hedef-site

–authors Parametresi

Bu parametre, import sırasında yazarlara ne yapılacağını belirler ve üç değer alabilir:

–authors=create: XML’deki yazar bilgileriyle yeni kullanıcılar oluşturur. Farklı bir siteye geçiyorsanız ve tüm yazarları taşımak istiyorsanız bunu kullanın.

–authors=mapping.csv: Kaynak sitedeki yazarları hedef sitedeki mevcut kullanıcılarla eşleştirir. En kontrollü yaklaşım budur.

–authors=skip: Yazar oluşturmaz, mevcut kullanıcıları değiştirmez. Yazılar admin’e atanır.

Mapping dosyası hazırlamak için önce hedef sitedeki kullanıcıları listeleyin:

wp user list --path=/var/www/html/hedef-site --fields=ID,user_login,display_name

Sonra mapping.csv dosyasını şu formatta oluşturun:

old_user_login,new_user_login
ahmet_yazar,ahmet
mehmet_editör,mehmet.kaya
admin,superadmin

Ve import sırasında kullanın:

wp import /tmp/exports/export.xml 
    --authors=/tmp/mapping.csv 
    --path=/var/www/html/hedef-site

Birden Fazla XML Dosyasını Import Etmek

Parçalı export yaptıysanız, tüm dosyaları sırayla import etmeniz gerekir. Bunu otomatize etmek için:

#!/bin/bash
# Dizindeki tüm XML dosyalarını sırayla import et

IMPORT_DIR="/backup/wp-exports/20240115"
SITE_PATH="/var/www/html/hedef-site"
LOG_FILE="/var/log/wp-import-$(date +%Y%m%d-%H%M%S).log"

echo "Import basliyor: $(date)" | tee -a $LOG_FILE

for XML_FILE in $IMPORT_DIR/*.xml; do
    echo "Import ediliyor: $XML_FILE" | tee -a $LOG_FILE
    wp import "$XML_FILE" 
        --authors=create 
        --path=$SITE_PATH 2>&1 | tee -a $LOG_FILE
    
    if [ $? -eq 0 ]; then
        echo "Basarili: $XML_FILE" | tee -a $LOG_FILE
    else
        echo "HATA: $XML_FILE import basarisiz!" | tee -a $LOG_FILE
    fi
done

echo "Import tamamlandi: $(date)" | tee -a $LOG_FILE
echo "Log dosyasi: $LOG_FILE"

Gerçek Dünya Senaryosu 1: Staging’den Production’a İçerik Taşıma

Diyelim ki bir editör ekibi staging ortamında yeni makaleler hazırladı ve bunları production’a almanız gerekiyor. Staging ve production aynı sunucuda, farklı dizinlerde:

#!/bin/bash
# Staging'den production'a yeni yazıları taşı

STAGING_PATH="/var/www/staging"
PROD_PATH="/var/www/production"
EXPORT_DIR="/tmp/staging-export-$(date +%Y%m%d)"
LAST_SYNC_DATE="2024-01-01"  # Son senkronizasyon tarihi

mkdir -p $EXPORT_DIR

# Sadece son sync'ten sonraki yayınlanmış yazıları al
wp export 
    --path=$STAGING_PATH 
    --post_type=post 
    --post_status=publish 
    --start_date=$LAST_SYNC_DATE 
    --dir=$EXPORT_DIR

# Maintenance mode'u aktif et
wp maintenance-mode activate --path=$PROD_PATH

# Import et
for XML in $EXPORT_DIR/*.xml; do
    wp import "$XML" 
        --authors=mapping.csv 
        --path=$PROD_PATH
done

# Cache temizle
wp cache flush --path=$PROD_PATH
wp rewrite flush --path=$PROD_PATH

# Maintenance mode kapat
wp maintenance-mode deactivate --path=$PROD_PATH

echo "Staging -> Production sync tamamlandi"

Gerçek Dünya Senaryosu 2: Multisite’dan Tekil Siteye Göç

WordPress Multisite’dan bir alt siteyi bağımsız bir WordPress kurulumuna taşımak, sysadminlerin sıkça karşılaştığı bir senaryodur. Örneğin multisite ağındaki blog.siteadi.com adresini www.yeniblog.com olarak bağımsız kuruluma almak:

# Multisite'daki hedef blog ID'sini bul
wp site list --path=/var/www/multisite

# blog ID 3 olan sitenin içeriğini dışa aktar
wp export 
    --path=/var/www/multisite 
    --url=https://blog.siteadi.com 
    --dir=/tmp/multisite-export/ 
    --post_type=post,page,attachment

# Yeni bağımsız kuruluma kur
wp core download --path=/var/www/yeniblog
wp config create 
    --path=/var/www/yeniblog 
    --dbname=yeniblog_db 
    --dbuser=db_user 
    --dbpass=guvenli_sifre 
    --dbhost=localhost

wp core install 
    --path=/var/www/yeniblog 
    --url=https://www.yeniblog.com 
    --title="Yeni Blog" 
    --admin_user=admin 
    [email protected] 
    --admin_password=guvenli_admin_sifre

# Importer eklentisini kur
wp plugin install wordpress-importer --activate --path=/var/www/yeniblog

# Import et
wp import /tmp/multisite-export/*.xml 
    --authors=create 
    --path=/var/www/yeniblog

Medya Dosyalarını Taşımak

wp export ve wp import, medya dosyalarını binary olarak taşımaz; sadece URL referanslarını XML’e yazar. Görseller kaynak sitedeki URL’lere bağlı kalır. Bu sorunu çözmenin birkaç yolu vardır.

Yöntem 1: WP-CLI ile otomatik medya indir

Import sonrası wp media import ile bozuk medya URL’lerini düzeltebilirsiniz. Ancak bunun için önce dosyaları taşımanız gerekir.

Yöntem 2: rsync ile uploads klasörünü taşı

# Kaynak siteden medyaları hedef siteye rsync ile kopyala
rsync -avz --progress 
    /var/www/kaynak-site/wp-content/uploads/ 
    /var/www/hedef-site/wp-content/uploads/

# Dosya izinlerini düzelt
chown -R www-data:www-data /var/www/hedef-site/wp-content/uploads/
find /var/www/hedef-site/wp-content/uploads/ -type f -exec chmod 644 {} ;
find /var/www/hedef-site/wp-content/uploads/ -type d -exec chmod 755 {} ;

Yöntem 3: URL’leri import sonrası değiştir

Eğer domain değiştiyse, import sonrası tüm medya URL’lerini güncellemek için wp search-replace kullanın:

wp search-replace 
    'https://eskisite.com' 
    'https://yenisite.com' 
    --path=/var/www/hedef-site 
    --skip-columns=guid 
    --all-tables

WooCommerce İçeriğini Taşımak

WooCommerce ürünleri product post type olarak saklanır ve wp export ile taşınabilir. Ancak ürün varyantları, stok bilgileri ve fiyatlar WooCommerce’e özgü meta veriler içerir; bunların düzgün taşınması için dikkatli olmak gerekir:

# WooCommerce ürünlerini ve ilgili tüm post type'ları dışa aktar
wp export 
    --path=/var/www/woo-kaynak 
    --post_type=product,product_variation 
    --post_status=publish,private,draft 
    --dir=/tmp/woo-export/

# Hedef sitede WooCommerce kurulu ve aktif olduğundan emin ol
wp plugin is-active woocommerce --path=/var/www/woo-hedef
if [ $? -ne 0 ]; then
    echo "WooCommerce aktif degil! Once WooCommerce'i aktif edin."
    exit 1
fi

# Import et
wp import /tmp/woo-export/*.xml 
    --authors=skip 
    --path=/var/www/woo-hedef

# Ürün URL'lerini yenile
wp rewrite flush --path=/var/www/woo-hedef

echo "WooCommerce urun aktarimi tamamlandi"

WooCommerce taşımasında ürün görselleri, kategori hiyerarşisi ve özellikler XML’e dahil olur. Ancak siparişleri, müşteri verilerini ve kupon kodlarını wp export taşımaz; bunlar için veritabanı seviyesinde çalışmanız ya da WooCommerce’in kendi araçlarını kullanmanız gerekir.

Sık Karşılaşılan Hatalar ve Çözümleri

“Error: ‘import’ is not a registered wp command”

WordPress Importer eklentisi aktif değildir. Çözüm:

wp plugin install wordpress-importer --activate --path=/var/www/hedef

PHP memory_limit hatası büyük XML dosyalarında

Import sırasında bellek hatası alıyorsanız, PHP limitini geçici olarak artırın:

wp import buyuk-dosya.xml 
    --authors=create 
    --path=/var/www/hedef 
    --exec='ini_set("memory_limit","512M");'

Ya da php.ini‘yi geçici olarak düzenleyin:

php -d memory_limit=512M /usr/local/bin/wp import dosya.xml 
    --authors=create 
    --path=/var/www/hedef

Duplicate post sorunu

Aynı XML’i iki kez import ederseniz içerikler çoğalabilir. Import etmeden önce hedef sitedeki mevcut içeriği kontrol edin:

# Hedef sitedeki yazı sayısını kontrol et
wp post list 
    --path=/var/www/hedef 
    --post_type=post 
    --post_status=publish 
    --format=count

Timeout sorunları uzak sunucularda

SSH üzerinden uzun süren import işlemlerinde screen ya da nohup kullanın:

# Screen ile çalıştır
screen -S wp-import
wp import /tmp/export/*.xml --authors=create --path=/var/www/hedef

# Ctrl+A, D ile screen'den ayrıl
# Sonra tekrar bağlanmak için:
screen -r wp-import

Otomatik Yedek ve Export Pipeline’ı

Cron ile düzenli içerik yedeklemesi için şu yapıyı kullanabilirsiniz:

#!/bin/bash
# /usr/local/bin/wp-content-backup.sh

SITE_PATH="/var/www/html"
BACKUP_BASE="/backup/wordpress"
DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_DIR="$BACKUP_BASE/$DATE"
RETENTION_DAYS=30

mkdir -p $BACKUP_DIR

# İçerik export
wp export 
    --path=$SITE_PATH 
    --dir=$BACKUP_DIR 
    --filename_format="content-{date}-{n}.xml"

# Gzip ile sıkıştır
gzip $BACKUP_DIR/*.xml

# Eski yedekleri temizle
find $BACKUP_BASE -type d -mtime +$RETENTION_DAYS -exec rm -rf {} +

echo "Backup tamamlandi: $BACKUP_DIR"
ls -lh $BACKUP_DIR

Crontab’a ekleyin:

# Her gece 02:00'de çalıştır
0 2 * * * /usr/local/bin/wp-content-backup.sh >> /var/log/wp-backup.log 2>&1

Export/Import Sürecini Doğrulamak

Import sonrası içeriğin düzgün geçip geçmediğini kontrol etmek için:

# Yazı sayısını karşılaştır
echo "Kaynak site yazı sayısı:"
wp post list --path=/var/www/kaynak --post_status=publish --format=count

echo "Hedef site yazı sayısı:"
wp post list --path=/var/www/hedef --post_status=publish --format=count

# Kategori sayısını kontrol et
echo "Kategori sayısı:"
wp term list category --path=/var/www/hedef --format=count

# Son 5 import edilen yazıyı göster
wp post list 
    --path=/var/www/hedef 
    --post_type=post 
    --orderby=date 
    --order=DESC 
    --posts_per_page=5 
    --fields=ID,post_title,post_date,post_status

Sonuç

wp export ve wp import, doğru kullanıldığında içerik taşıma sürecini dramatik biçimde hızlandıran ve otomatize etmeyi mümkün kılan güçlü araçlardır. Özellikle staging/production senkronizasyonu, multisite göçleri ve düzenli içerik yedekleme senaryolarında vazgeçilmez birer terminal komutu haline gelirler.

Ancak şunu her zaman aklınızda tutun: bu araçlar içerik katmanını taşır, altyapı katmanını değil. Tam bir site taşıması için wp db export/import, rsync ve sağlam bir wp search-replace rutiniyle birlikte kullanmanız gerekir. Bu kombinasyonu bir kez scriptlediğinizde, saatler süren manuel taşıma işlemlerini dakikalara indirdiğinizi göreceksiniz.

Her yeni taşıma senaryosu için önce küçük ölçekte test edin, logları inceleyin ve ancak sonra production’da uygulayın. WP-CLI’nin sunduğu --dry-run benzeri kontrol adımlarını ve --debug flagini bolca kullanmaktan çekinmeyin. Terminal size her şeyi söyler, yeter ki doğru soruyu sormasını bilin.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir