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
rsyncya dascp - İç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.
