WISECP tema geliştirme, templates/website/{Tema}/ altında bir dizin açıp içine theme.php manifesti, bir sayfa kabuğu (layouts/default.*) ve bir ana sayfa view'ı (views/home.*) koymakla başlar. Tema, ziyaretçinin gördüğü her sayfanın işaretlemesine, biçimine ve metnine sahiptir; Smarty, Twig ya da düz PHP motorlarından biriyle yazılır. Yönetim paneli temalı değildir, yalnızca müşteri tarafındaki site temalanır.

Bu rehberde tema anatomisini, ilk temanızı adım adım, sayfa ekranlarını (view'ları), şablon değişkenlerini, temanın kendi kanca dosyasını, menüleri, çevirileri, tema ayarlarını ve kalite kurallarını anlatıyoruz. Kanca sistemi hakkında genel bilgi için WISECP kanca (hook) kullanımı, platformun genel tanıtımı için WISECP nedir yazılarına bakabilirsiniz.

Tema anatomisi

Tema anatomisi: engine, status, update-url, meta

Tema bir dizin ve bir manifesttir. Belgenin temel ayrımı şudur: theme.php şemadır ve yazar tarafından yazılır; config.php kaydedilmiş değerlerdir ve panel tarafından yazılır. Güncelleme birincisini değiştirir, ikincisine dokunmaz.

text
templates/website/Acme/
├── theme.php     # manifest: motor, meta, durum, ayar şeması (zorunlu)
├── config.php    # kaydedilmiş ayar değerleri; panel yazar, elle yazılmaz
├── hooks.php     # temanın dinleyicileri: değişkenler, çıktı filtreleri
├── cover.png     # meta['image'] ile gösterilen katalog görseli
├── layouts/      # sayfa kabukları: default, auth, checkout, invoice
├── partials/     # kabuğun birleştirdiği parçalar: header, footer, drawer...
├── components/   # birden çok view'ın paylaştığı bloklar
├── views/        # sayfalar: account/ auth/ checkout/ content/ page/ products/
├── tables/       # müşteri paneli listelerinin kolon ön ayarları (düz PHP)
├── assets/       # css, js, görseller, favicon
├── locale/       # temanın kendi metinleri
└── content/      # operatörün metin düzenlemeleri, panel yazar
theme.php anahtarıNe belirler
enginesmarty, twig ya da php; view uzantısını belirler, yazılmazsa php
statusready ya da development; development önizlenir ama etkinleştirilemez
update-urlSürüm kontrolü adresi; boşsa kontrol yapılmaz
metaname, version, author, website, image, description ve davranış işaretleri
settingsgroups ve fields: yönetim formu bu şemadan üretilir

meta içindeki disabled_routes temanın sunmadığı rota anahtarlarını listeler; o adresler 404 döner ve site haritasından düşer. signup_minimal ve dashboard_due_soon_alert çekirdeğin okuduğu diğer davranış işaretleridir. meta['image'] tema dizinine göre çözülür, assets/ dizinine göre değil.

İlk temanız: adım adım

Belgeye göre etkinleştirme dört koşula bakar: theme.php var olmalı, status değeri development olmamalı, layouts/default.* ve views/home.* bulunmalı. Geliştirme sırasında coremio/configuration/debug.php içinde developer anahtarını açın; aksi halde şablon hatası yutulur ve boş sayfa görürsünüz.

  • templates/website/Acme/ dizinini, içinde layouts/, views/, locale/ ve assets/css/ ile oluşturun. Klasör adı temanın kimliğidir.
  • theme.php dosyasını yazın; engine anahtarını bilerek seçin ve geliştirirken update-url değerini boş bırakın.
  • layouts/default.tpl ile sayfa kabuğunu ekleyin; dağıtılan temalar title, head, content, scripts, body_end bloklarını kullanır.
  • views/home.tpl ile kabuğu genişleten ana sayfayı ekleyin.
  • locale/en.php (ve locale/tr.php) ile metinleri ekleyin; buradaki name ve description manifestinkileri ezer.
  • status değerini ready yapın ve panelde Ayarlar > Tema Ayarları > Tema Yönetimi ({admin}/settings/theme?group=theme) ekranında temanın kartındaki Aktifleştir butonuna tıklayın.
php
<?php
// templates/website/Acme/theme.php
return [
    'meta' => [
        'name'    => 'Acme',
        'version' => '1.0.0',
        'author'  => 'Acme Ltd',
        'website' => 'https://acme.example',
        'image'   => 'cover.png',   // bu dosyanın yanında, assets/ altında değil
    ],
    'update-url' => '',
    'engine'     => 'smarty',
    'status'     => 'development',  // etkinleştirmeden önce 'ready' yapın
    'settings'   => ['groups' => [], 'fields' => []],
];
smarty
{* layouts/default.tpl *}
<!doctype html>
<html lang="{$ui_lang}" dir="{$ui_dir}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>{block name=title}{$page_title|default:$company_name}{/block}</title>
    <link rel="stylesheet" href="{asset path='css/default.css'}">
    {block name=head}{/block}
    {hook name='ui:client.head.css'}
</head>
<body>
    {hook name='ui:client.body.begin'}
    <header><a href="{link route='home'}">{$company_name}</a></header>
    <main>{block name=content}{/block}</main>
    <footer>&copy; {$current_year} {$company_name}</footer>
    {block name=scripts}{/block}
    {block name=body_end}{/block}
    {hook name='ui:client.body.end'}
</body>
</html>
smarty
{* views/home.tpl *}
{extends file='layouts/default.tpl'}

{block name=title}{lang key='home_title'} | {$company_name}{/block}

{block name=content}
    <section class="hero">
        <h1>{lang key='home_headline' brand=$company_name}</h1>
        <a class="btn" href="{link route='sign-in'}">{lang key='home_cta'}</a>
    </section>
{/block}

Yüzeyler: view dosyaları ve sayfalar

Controller'lar şablon dosyası adı değil uzantısız bir view adı verir: render("account/services") Smarty temasında views/account/services.tpl, Twig temasında .twig olur. Belgeye göre Basic ve WStyle temaları 69 view taşır; eksik view'larda site controller'larının çoğu 404 döner.

KlasörNe yaşar
views/ (kök)home, domain, 404, maintenance ve birkaç bağımsız sayfa
views/products/Katalog: kategori, yazılım detay, yazılım mağazası
views/checkout/Yapılandırma, sepet, ödeme ve parçaları
views/account/Giriş yapmış müşteri paneli: pano, hizmetler, faturalar, talepler
views/auth/Giriş, kayıt, parola sıfırlama, aktivasyon, davet
views/content/Blog, duyuru, bilgi bankası, CMS sayfaları, iletişim
views/page/Dosya tabanlı sayfalar: views/page/about.tpl, /about adresinde yayımlanır

views/page/ altındaki bir dosya controller, rota kaydı ya da çekirdek düzenlemesi olmadan bir adres yayımlar ve kayıtlı bir rotayı asla gölgelemez. Tam bir temaya geçmeden önce hangi view'ların gerektiğini belgenin sayfa ekranları listesinden kontrol edin.

Şablon değişkenleri

Şablon değişkenleri: $setting, $ui_lang, $ui_dir, $company_name, $current_year, $header_menu, $footer_menu, $mobile_menu

Tema veritabanını sorgulamaz; veriyi platform hazırlar. Değişkenleri üç katman yazar: motor (her sayfada), müşteri sayfa paketi ve temanın hooks.php dosyası.

DeğişkenKaynakNot
$settingMotorTema ayarları; renk alanlarının _rgb ikizi de gelir
$ui_lang, $ui_dirMotorhtml etiketine basılır; yönü sabit yazmayın
$company_name, $current_yearMüşteri sayfasıHer müşteri sayfasında var
$header_menu, $footer_menu, $mobile_menuMüşteri sayfasıOperatörün yönettiği menü ağaçları
$is_logged_in, $client_idMüşteri sayfasıOturum dalları bu işarete bakar
$account_info, $client_badgesGiriş yapılmış sayfaÖnce $is_logged_in ile koruyun
$privacy_contract_linkMüşteri sayfasıEşlenmemişse boş; boşken bağlantıyı gizleyin

Belgede listelenmeyen bir değeri göstermeden önce |default: ile kontrol edin. $template_dir bir dosya sistemi yoludur; işaretlemede göstermek sunucu yolunu sızdırır.

Tema kancaları: hooks.php

Temanın hooks.php dosyası ilk sayfa oluşmadan önce istek başına bir kez dahil edilir ve yalnızca website isteklerinde çalışır. İki aile vardır: veri dinleyicileri (Hook::add() ile) ve şablonda {hook name='...'} ile açılan işaretleme noktaları.

php
<?php
// templates/website/Acme/hooks.php
// Tema başına TEK değişken dinleyicisi: yalnızca son dönen dizi yaşar.
Hook::add("filter:template.variables", 1, function ($template, $data) {

    $data["route_off"] = array_fill_keys(Theme::active()->meta()["disabled_routes"] ?? [], true);

    // Her sayfada çalışır: sorgu içeren işi önbellekten geçirin, anahtara dili ve para birimini katın
    $data["footer_groups"] = Cache::remember('website',
        'acme_footer_' . Money::getUCID() . '_' . Language::selected(), 3600,
        fn (): array => Products::groups());

    return $data;   // gelen diziyi döndürmezseniz platformun topladığı anahtarlar düşer
});

// İşaretleme noktası: yerleşim dosyası düzenlemeden ek stil
Hook::add("ui:client.head.css", 1, fn (): string =>
    '<link rel="stylesheet" href="' . Theme::active()->assetUrl('css/extra.css') . '">');

Diğer önemli noktalar: filter:client.page.output bitmiş HTML'i referansla değiştirir (yalnızca etiket motorlarında), filter:client.menu menü ağacına düğüm ekler, filter:client.routes temanın sayfasına kısa adres verir, filter:routing.match ise hiçbir rotanın sahiplenmediği bir slug'ı cevaplar. İşaretleme noktaları kaçış yapmaz; bu noktalara ziyaretçi girdisi eklemeyin. Dinleyicideki ölümcül hata yutulur, bu yüzden bir dinleyici hiçbir şey yapmıyorsa hata günlüğüne bakın.

Çeviri

Görünür hiçbir metin şablona sabit yazılmaz. Ortak metinler locale/{dil}.php, sayfaya özgü metinler locale/{dil}/{scope}.php dosyasında durur. Scope sayfanın genel kimliğidir: views/account/settings.tpl için account/settings, views/page/about.tpl için yalnızca about. Operatörün panelden yaptığı düzenlemeler content/ ağacına yazılır ve tema güncellemesi bunları ezmez.

Çözüm sırası şöyledir: operatör ezmesi, temanın aktif dildeki locale'i, temanın İngilizce locale'i, platformun kendi dil dosyaları ve en son anahtarın kendisi. Değer geçirmek için {lang key='count' n=$adet} yazılır; dizedeki {n} yer tutucusu değiştirilir. Platformun ortak metinlerini (website/index/logo-alt gibi yol biçimli anahtarlar) temaya kopyalamayın.

Tema ayarları

Operatörün değiştirebileceği ayarlar theme.php içindeki settings şemasında bildirilir; panel formu bu şemadan üretir, değerleri config.php'ye yazar ve view'lar sonucu $setting değişkeninden okur. Alan tipleri switch, checkbox, color, number, select ve textarea'dır; başka her şey metin alanı olur. label, desc ve placeholder düz metin değil, temanın locale dosyasındaki anahtarlardır.

php
<?php
// theme.php içinde
'settings' => [
    'groups' => [
        'topbar' => ['label' => 'grp_topbar', 'icon' => 'bi-megaphone'],
    ],
    'fields' => [
        'topbar_enabled' => [
            'type' => 'switch', 'group' => 'topbar',
            'label' => 'set_topbar_enabled', 'default' => false,
        ],
        'topbar_text' => [
            'type' => 'textarea', 'group' => 'topbar', 'label' => 'set_topbar_text',
            'default' => '', 'rows' => 3, 'multilang' => true, 'html' => true,
            'depends' => ['topbar_enabled' => true],
        ],
    ],
],
smarty
{if $setting.topbar_enabled}
    <div class="topbar">{$setting.topbar_text nofilter}</div>
{/if}

Şemada bildirilmeyen bir değer hiçbir view'a ulaşmaz. Alan anahtarı aynı anda POST adı, config anahtarı ve view'daki addır; yeniden adlandırmak kayıtlı değeri öksüz bırakır. multilang alanı view'a aktif dilin dizesi olarak gelir; html => true olmadan metindeki etiketler kayıtta temizlenir.

Kalite: güvenlik, performans ve parite

Kalite: güvenlik, performans ve parite: Formlar, Kaçış, Kum havuzu, Performans
  • Formlar: tema formlarını bir ara katman korumaz. Şablonda {csrf form='contact-form'} ve {captcha area='contact-form'} basılır, sunucu tarafında aynı anahtarla sırasıyla jeton, işlem kısıtlama, doğrulama (captcha ya da BotShield) ve spam kapısı denetlenir. Ayrıntılar için WISECP güvenlik ayarları yazısına bakın.
  • Kaçış: iki motor da varsayılan olarak kaçış yapar; Smarty'de nofilter, Twig'de raw yalnızca güvendiğiniz işaretleme için kullanılmalıdır.
  • Kum havuzu: view'lar dokuz fonksiyona (link, lang, asset, config, money, hook, captcha, csrf, content) erişir; platform sınıflarına erişemez. Smarty ayrıca sınırlı bir PHP fonksiyon listesine izin verir.
  • Performans: her dinleyici her sayfa görüntülemesinde çalışır; sorgu içeren işi Cache::remember ile önbelleğe alın ve anahtara dili ve para birimini katın.
  • Parite: birden çok tema yayınlıyorsanız davranış, güvenlik ve erişilebilirlik düzeltmeleri aynı dosyayı taşıyan her temaya uygulanır; renk ve boşluk gibi görsel kimlik ise yalnızca o temaya aittir.
  • Sırlar: etiket motorları view'ları diske düz PHP olarak derler; şablon sır saklanacak yer değildir.

Sık Sorulan Sorular

WISECP teması hangi klasöre konur?

templates/website/{Tema}/ altına. Zorunlu tek dosya theme.php'dir; etkinleştirme için ayrıca layouts/default.* ve views/home.* gerekir.

Temam panelde görünüyor ama Aktifleştir reddediliyor, neden?

En sık sebep status değerinin hâlâ development olmasıdır; etkinleştirme bunu ilk sırada kontrol eder. Ardından layouts/default.* ve views/home.* dosyalarının varlığı kontrol edilir.

Smarty mi, Twig mi, PHP mi seçmeliyim?

Üçüne de aynı veri ulaşır. Smarty ve Twig kum havuzunda çalışır ve varsayılan olarak kaçış yapar; düz PHP dile tam erişim verir ama kaçış sorumluluğu tamamen sizdedir. Belge, dilin tamamına ihtiyacı olan temanın engine => 'php' bildirmesini söyler.

Yönetim panelinin görünümünü tema ile değiştirebilir miyim?

Hayır. Belgeye göre tema yalnızca website'i kapsar; yönetim paneli düz PHP şablonlarıdır ve ona yalnızca yayımlanmış ui: kancalarıyla ulaşılabilir.

Boş sayfa görüyorum, hata yok. Ne yapmalıyım?

Platform şablon motorunun fırlattığı hataları yakalayıp boş dize döndürür. coremio/configuration/debug.php içinde developer anahtarını açın ve eksik view, yazım hatası ya da kapatılmamış blok arayın.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: WISECP nedir · WISECP hook kullanımı · WISECP modül geliştirme · WISECP güvenlik ayarları · WISECP API kullanımı · PHP nedir