WordPress Gizlilik Politikası Sayfasını Programatik Olarak Ayarlama
WordPress kurulumu tamamlandıktan sonra bir çok şeyi elle ayarlamak zorunda kaldığınızı fark etmişsinizdir. Tema aktif etmek, eklenti yüklemek, genel ayarları düzenlemek… Ve bunların arasında en çok unutulan ama GDPR açısından en kritik olanlardan biri: Privacy Policy sayfasını doğru şekilde tanımlamak. Özellikle bir ajans ortamında onlarca WordPress sitesi kuruyorsanız ya da müşteri sitenizi her sıfırladığınızda bu adımı tekrar yapmak zorunda kalıyorsanız, bunu programatik olarak halletmek hem zamandan tasarruf ettirir hem de insan hatasını ortadan kaldırır.
Bu yazıda functions.php üzerinden WordPress Privacy Policy sayfasını nasıl otomatik oluşturabileceğinizi, nasıl atayabileceğinizi ve bu süreçte nelere dikkat etmeniz gerektiğini ele alacağız.
WordPress Privacy Policy Sistemi Nasıl Çalışır?
WordPress 4.9.6 sürümüyle birlikte GDPR uyumluluğunu desteklemek amacıyla yerleşik bir privacy policy yönetimi geldi. Bu sistem temel olarak şu parçalardan oluşur:
wp_page_on_frontvewp_page_for_postsgibi WordPress seçeneklerine benzer şekilde, gizlilik politikası sayfasıwp_page_for_privacy_policyseçeneğiyle saklanır.- WordPress yönetim panelinde Ayarlar > Gizlilik bölümünden bu sayfa elle seçilebilir.
get_privacy_policy_url()fonksiyonu ile sitenin herhangi bir yerinde bu sayfanın URL’si çekilebilir.
Programatik olarak bu sistemi yönetmek demek, ya mevcut bir sayfayı bu seçeneğe atamak ya da yoksa önce sayfayı oluşturup sonra atamak demektir.
Temel Yaklaşım: update_option ile Atama
En basit senaryodan başlayalım. Elimizde zaten oluşturulmuş bir “Gizlilik Politikası” sayfası var ve biz sadece bunu WordPress’e tanıtmak istiyoruz.
<?php
function set_privacy_policy_page() {
// "Gizlilik Politikasi" slug'una sahip sayfayi bul
$privacy_page = get_page_by_path( 'gizlilik-politikasi' );
if ( $privacy_page && 'publish' === $privacy_page->post_status ) {
update_option( 'wp_page_for_privacy_policy', $privacy_page->ID );
}
}
add_action( 'after_setup_theme', 'set_privacy_policy_page' );
Burada get_page_by_path() fonksiyonu sayfa slug’una göre arama yapıyor. Eğer sayfa bulunursa ve yayında durumdaysa, update_option ile ID’sini kaydediyoruz. after_setup_theme hook’u bu işlem için gayet uygun çünkü tema yüklendikten hemen sonra çalışıyor.
Sayfa Yoksa Oluştur, Varsa Atama Yap
Gerçek dünya senaryolarında çoğu zaman sayfanın var olup olmadığından emin olamazsınız. Özellikle tema ya da eklenti aktivasyonunda bu işlemi tetikliyorsanız, önce kontrol edip sonra karar vermeniz gerekir.
<?php
function create_and_set_privacy_policy_page() {
// Mevcut secenegi kontrol et
$existing_id = get_option( 'wp_page_for_privacy_policy' );
if ( $existing_id && get_post( $existing_id ) ) {
// Sayfa zaten atanmis, bir sey yapma
return;
}
// Slug ile sayfayi ara
$existing_page = get_page_by_path( 'gizlilik-politikasi' );
if ( $existing_page ) {
update_option( 'wp_page_for_privacy_policy', $existing_page->ID );
return;
}
// Sayfa yok, olustur
$page_content = '<p>Bu gizlilik politikasi sayfasi otomatik olusturulmustur. Lutfen icerigini duzenleyin.</p>';
$new_page_id = wp_insert_post( array(
'post_title' => 'Gizlilik Politikası',
'post_name' => 'gizlilik-politikasi',
'post_content' => $page_content,
'post_status' => 'publish',
'post_type' => 'page',
'post_author' => 1,
) );
if ( $new_page_id && ! is_wp_error( $new_page_id ) ) {
update_option( 'wp_page_for_privacy_policy', $new_page_id );
}
}
add_action( 'after_setup_theme', 'create_and_set_privacy_policy_page' );
Bu kod önce seçenekte kayıtlı bir ID var mı kontrol ediyor, sonra slug ile mevcut sayfayı arıyor, ikisi de yoksa wp_insert_post() ile yeni bir sayfa oluşturup bunu seçenek olarak kaydediyor. Gereksiz sayfa oluşturma işlemini önlemek için bu sıralama önemli.
Tema Aktivasyonunda Tetiklemek
Yukarıdaki kodu her sayfa yüklendiğinde çalıştırmak performans açısından ideal değil. Özellikle after_setup_theme gibi sık çalışan bir hook kullanıyorsanız, işlemi kontrol altında tutmanız gerekir. Bunu tema aktivasyonuna bağlamak çok daha temiz bir çözüm.
<?php
function theme_activation_setup() {
// Privacy policy sayfasini kontrol et ve olustur
$existing_id = get_option( 'wp_page_for_privacy_policy' );
if ( ! $existing_id || ! get_post( $existing_id ) ) {
$page_id = wp_insert_post( array(
'post_title' => 'Gizlilik Politikası',
'post_name' => 'gizlilik-politikasi',
'post_status' => 'publish',
'post_type' => 'page',
'post_content' => get_default_privacy_policy_content(),
) );
if ( ! is_wp_error( $page_id ) ) {
update_option( 'wp_page_for_privacy_policy', $page_id );
}
}
}
add_action( 'after_switch_theme', 'theme_activation_setup' );
after_switch_theme hook’u tema aktivasyonunda bir kere çalışır. Bu sayede kod her istek sırasında tetiklenmez. get_default_privacy_policy_content() ise WordPress’in kendi varsayılan gizlilik politikası içeriğini döndürür, başlangıç noktası olarak güzel bir seçenek.
WooCommerce ile Uyumlu Genişletilmiş Versiyon
Eğer sitenizde WooCommerce de varsa, sadece privacy policy sayfasıyla kalmak yetmez. WooCommerce’in kendi Hesabım, Sepet, Ödeme gibi sayfalarına ek olarak, KVKK uyumu için aydınlatma metni sayfası da oluşturmanız gerekebilir. Şimdi bunu da dahil eden bir örnek görelim.
<?php
function woocommerce_gdpr_pages_setup() {
$pages_to_create = array(
'privacy-policy' => array(
'title' => 'Gizlilik Politikası',
'content' => '<p>Kişisel verileriniz KVKK kapsamında işlenmektedir.</p>',
'option' => 'wp_page_for_privacy_policy',
),
'aydinlatma-metni' => array(
'title' => 'Aydınlatma Metni',
'content' => '<p>6698 sayılı KVKK uyarınca hazırlanmış aydınlatma metnidir.</p>',
'option' => 'kvkk_aydinlatma_page_id', // ozel secenek
),
'cerez-politikasi' => array(
'title' => 'Çerez Politikası',
'content' => '<p>Sitemizde kullanılan çerezler hakkında bilgi edinebilirsiniz.</p>',
'option' => 'cerez_politikasi_page_id', // ozel secenek
),
);
foreach ( $pages_to_create as $slug => $page_data ) {
$existing_option = get_option( $page_data['option'] );
if ( $existing_option && get_post( $existing_option ) ) {
continue;
}
$found_page = get_page_by_path( $slug );
if ( $found_page ) {
update_option( $page_data['option'], $found_page->ID );
continue;
}
$new_id = wp_insert_post( array(
'post_title' => $page_data['title'],
'post_name' => $slug,
'post_content' => $page_data['content'],
'post_status' => 'publish',
'post_type' => 'page',
) );
if ( ! is_wp_error( $new_id ) ) {
update_option( $page_data['option'], $new_id );
}
}
}
add_action( 'after_switch_theme', 'woocommerce_gdpr_pages_setup' );
Bu yapı ile üç farklı sayfayı tek seferde yönetebiliyorsunuz. Kendi eklentinizi ya da temanızı geliştiriyorsanız bu döngü yaklaşımı çok işe yarıyor.
Privacy Policy URL’sini Temadan Kullanmak
Sayfa oluşturuldu ve atandı. Peki bunu temada nasıl kullanacaksınız? WordPress’in sağladığı yerleşik fonksiyonu kullanmak en doğrusu.
<?php
function display_footer_privacy_links() {
$privacy_url = get_privacy_policy_url();
if ( ! empty( $privacy_url ) ) {
echo '<a href="' . esc_url( $privacy_url ) . '">' . esc_html__( 'Gizlilik Politikası', 'tema-adi' ) . '</a>';
}
// Cerez politikasi icin ozel secenek
$cookie_page_id = get_option( 'cerez_politikasi_page_id' );
if ( $cookie_page_id ) {
$cookie_url = get_permalink( $cookie_page_id );
echo '<a href="' . esc_url( $cookie_url ) . '">' . esc_html__( 'Çerez Politikası', 'tema-adi' ) . '</a>';
}
}
get_privacy_policy_url() fonksiyonu wp_page_for_privacy_policy seçeneğine kaydedilmiş sayfanın permalink’ini döndürür. Eğer sayfa atanmamışsa boş string döner, bu yüzden kontrol etmeyi unutmayın.
Çoklu Dil Desteği ile Kullanmak (WPML / Polylang)
Çok dilli sitelerde her dil için ayrı bir privacy policy sayfası oluşturmak gerekebilir. WPML veya Polylang kullanıyorsanız, dil bazlı sayfa oluşturma işlemi biraz daha karmaşık hale gelir. Temel bir yaklaşım şöyle olabilir.
<?php
function create_multilingual_privacy_pages() {
// Sadece WPML aktifse calis
if ( ! defined( 'ICL_LANGUAGE_CODE' ) ) {
return;
}
$languages = apply_filters( 'wpml_active_languages', null, array( 'skip_missing' => 0 ) );
if ( empty( $languages ) ) {
return;
}
$titles = array(
'tr' => 'Gizlilik Politikası',
'en' => 'Privacy Policy',
'de' => 'Datenschutzrichtlinie',
);
$slugs = array(
'tr' => 'gizlilik-politikasi',
'en' => 'privacy-policy',
'de' => 'datenschutzrichtlinie',
);
foreach ( $languages as $lang_code => $lang_data ) {
$title = isset( $titles[ $lang_code ] ) ? $titles[ $lang_code ] : 'Privacy Policy';
$slug = isset( $slugs[ $lang_code ] ) ? $slugs[ $lang_code ] : 'privacy-policy';
do_action( 'wpml_switch_language', $lang_code );
$existing = get_page_by_path( $slug );
if ( ! $existing ) {
$page_id = wp_insert_post( array(
'post_title' => $title,
'post_name' => $slug,
'post_status' => 'publish',
'post_type' => 'page',
) );
// WPML icin dil ataması
if ( ! is_wp_error( $page_id ) ) {
apply_filters( 'wpml_set_element_language_details', null, array(
'element_id' => $page_id,
'element_type' => 'post_page',
'trid' => false,
'language_code' => $lang_code,
'source_language_code' => null,
) );
}
}
}
// Varsayilan dile geri don
do_action( 'wpml_switch_language', 'tr' );
}
add_action( 'after_switch_theme', 'create_multilingual_privacy_pages' );
Bu kod WPML aktifse dilleri dolaşıp her biri için sayfa oluşturmaya çalışıyor. Gerçek projede dil çevirilerini ve TRID (translation relationship ID) yönetimini daha titiz yapmanız gerekebilir ama bu temel bir başlangıç noktası.
Yönetim Panelinde Bildirim Göstermek
Privacy policy sayfası atanmamışsa yöneticiye admin panelinde bir uyarı göstermek oldukça kullanışlı. Müşteri sitenizi devraldığınızda ya da bir şeyler eksik kaldığında fark etmenizi sağlar.
<?php
function check_privacy_policy_admin_notice() {
// Sadece admin kullanicilara goster
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$privacy_page_id = get_option( 'wp_page_for_privacy_policy' );
if ( ! $privacy_page_id || ! get_post( $privacy_page_id ) ) {
echo '<div class="notice notice-warning is-dismissible">';
echo '<p><strong>Dikkat:</strong> Gizlilik Politikası sayfası tanımlanmamış. ';
echo '<a href="' . esc_url( admin_url( 'options-privacy.php' ) ) . '">Ayarlar > Gizlilik</a> ';
echo 'bölümünden sayfayı atayabilirsiniz.</p>';
echo '</div>';
return;
}
$page = get_post( $privacy_page_id );
if ( 'publish' !== $page->post_status ) {
echo '<div class="notice notice-warning is-dismissible">';
echo '<p><strong>Dikkat:</strong> Gizlilik Politikası sayfası yayında değil. ';
echo '<a href="' . esc_url( get_edit_post_link( $privacy_page_id ) ) . '">Sayfayı düzenle</a></p>';
echo '</div>';
}
}
add_action( 'admin_notices', 'check_privacy_policy_admin_notice' );
Bu bildirim, sayfa tanımlanmamışsa doğrudan Ayarlar > Gizlilik sayfasına link veriyor. Ayrıca sayfa taslak durumundaysa ya da çöp kutusundaysa farklı bir uyarı gösteriyor. Müşteri sitelerinde bu tür kontroller gerçekten hayat kurtarıyor.
WP-CLI ile Komut Satırından Ayarlamak
Sunucu tarafında otomasyonla çalışıyorsanız, WP-CLI üzerinden bu işlemi komut satırından da halledebilirsiniz. Özellikle toplu site kurulumlarında veya deployment script’lerinde kullanışlı.
# Mevcut privacy policy ayarini kontrol et
wp option get wp_page_for_privacy_policy
# Bilinen bir sayfa ID'sini manuel ata
wp option update wp_page_for_privacy_policy 42
# Slug ile sayfa ID'sini bul
wp post list --post_type=page --name=gizlilik-politikasi --field=ID
# Sayfa yoksa olustur ve ata
PAGE_ID=$(wp post create
--post_type=page
--post_title="Gizlilik Politikası"
--post_name="gizlilik-politikasi"
--post_status=publish
--porcelain)
wp option update wp_page_for_privacy_policy $PAGE_ID
echo "Privacy policy sayfasi olusturuldu. ID: $PAGE_ID"
--porcelain flag’i wp post create komutuna eklediğinizde sadece oluşturulan post’un ID’sini döndürür, bu sayede shell değişkenine doğrudan atayabilirsiniz. Bu yaklaşım CI/CD pipeline’larına ya da Ansible playbook’larına kolayca entegre edilebilir.
Dikkat Edilmesi Gereken Noktalar
Bu işlemleri yaparken birkaç konuya özellikle dikkat etmek gerekiyor.
- Çift sayfa oluşturma sorunu:
wp_insert_postçağırmadan önce mutlaka hem seçenek kontrolü hem de slug kontrolü yapın. Yoksa aynı slug ile birden fazla sayfa oluşabilir ya da veritabanında gereksiz kayıtlar birikir.
is_wp_error()kontrolü:wp_insert_post()hata durumundaWP_Errornesnesi döner. Bunu kontrol etmedenupdate_optionçağırırsanız hatalı bir ID veritabanına yazılmış olur.
post_authordeğeri: Sayfayı oluştururkenpost_authorbelirtmezseniz WordPress mevcut kullanıcıyı alır. CLI’dan çalışırken ya da cron bağlamında bu 0 olabilir. Güvenli tarafta kalmak için1(admin) ya da gerçek admin kullanıcısının ID’sini belirtin.
- Önbellekleme: Bazı caching eklentileri veya object cache sistemleri
get_optionsonuçlarını önbellekte tutar. Yoğun önbellek ortamlarındawp_cache_flush()çağırmak gerekebilir ama bunu dikkatli kullanın.
- Multisite kurulumlar: Network aktivasyonlu bir eklenti ya da tema yazıyorsanız, her blog için ayrı ayrı bu işlemi yapmanız gerekir.
switch_to_blog()verestore_current_blog()fonksiyonlarını kullanarak ağdaki tüm siteleri dolaşabilirsiniz.
- İzin kontrolü: Admin paneline yönelik işlemler yapıyorsanız
current_user_can( 'manage_options' )kontrolünü asla atlamayın.functions.phpdoğrudan çalıştığı için güvenlik kontrolleri kritik.
Deployment Workflow’una Entegrasyon
Gerçek bir ajans ortamında bu kodları genellikle starter tema’nın functions.php‘sine ya da bir “site setup” eklentisine koyuyoruz. Tipik bir iş akışı şöyle görünebilir.
- Geliştirme ortamında tema oluşturulur ve
after_switch_themehook’una setup fonksiyonları eklenir. - Sahneye (staging) deploy edildiğinde tema aktif edilerek sayfalar otomatik oluşur.
- QA süreci sonrası production’a geçilir, aynı süreç tekrar işler.
- İçerik girişleri yapılır, sayfa metinleri gerçek KVKK metniyle güncellenir.
Bu iş akışında programatik oluşturma sadece bir başlangıç noktası sağlar, gerçek içerik her zaman manuel olarak girilmeli. Ama en azından sayfa var, URL’si belirli ve WordPress’e tanıtılmış durumda oluyor.
Sonuç
WordPress’te privacy policy sayfasını programatik olarak ayarlamak, göründüğünden çok daha pratik bir çözüm. Hem after_switch_theme hook’u üzerinden tema aktivasyonunda hem de WP-CLI aracılığıyla deployment süreçlerinde bu işlemi otomatize edebilirsiniz. Temel mantık basit: seçeneği kontrol et, sayfa yoksa oluştur, varsa ata.
GDPR ve KVKK uyumu için bu adım tek başına yeterli değil elbette. Çerez yönetimi, veri işleme sözleşmeleri ve form onayları gibi konular ayrıca ele alınmalı. Ama en azından WordPress’in kendi privacy policy sistemi doğru kurulmuş olursa, get_privacy_policy_url() gibi fonksiyonlar beklendiği gibi çalışır, WooCommerce checkout’undaki gizlilik onay kutucuğu doğru sayfaya işaret eder ve arama motorları ile uyumluluk denetimleri bu sayfayı kolayca bulabilir.
Onlarca site yönetiyorsanız, bu tür küçük otomasyon parçaları zamanla ciddi bir birikim sağlıyor.
