Sistem Sayfaları
Bazı sayfalar uygulama bozukken, isteği reddederken ya da kapalıyken görünmek zorundadır. Bunların tam ikisi hâlâ sizin temanızdan gelebilir.
Genel Bakış
Bulunamayan sayfa ve kapalı site sıradan durumlardır; ekranda sizin tasarımınız olmalıdır. Ölümcül bir hata ya da engellenmiş adres öyle değil: sayfaları üreten şeyin kendisi arızalı olabilir, o ekranlar kendi kabuklarını taşır.
Temanız 404 ve maintenance ekranlarına sahiptir. İkincisi yazacağınız diğer her view'dan farklı: sayfa gövdesi değil, tam bir belge.
Yapı
| Ekran | Nereden gelir | Ne zaman görünür |
|---|---|---|
| Bulunamadı | Temanız, views/404 | Eşleşmeyen her adres ve düşen her view kapısı |
| Bakım | Temanız, views/maintenance | Bakım modunda her adres; bir yönetici tanınmadıysa |
| Bakım yedeği | Çekirdek, templates/system/maintenance.php | Yalnız aktif tema bakım view'ı taşımıyorsa |
| Uygulama hatası | Çekirdek, templates/system/application-error.php | AJAX olmayan bir istekte ölümcül hata, HTTP 500 ile cevaplanır |
| Engellenen adres | Çekirdek, templates/system/blocked-ip.php | Adres engelleyici isteği yönlendirmeden önce reddetti |
Üç çekirdek sayfası tek bir kabuk paylaşır; bir stil düzeltmesi üçüne birden iner. Her sayfa kabuğun yardımcılarını kullanır, başka hiçbir şeyi değil.
Adım Adım
Bulunamadı Sayfasını Kurun
- Varsayılan layout'u genişletin: bu sayfa normal istek yolundan gelir.
- İki çıkış yolunu anahtarlarının arkasında sunun: açıksa bilgi bankası, talep sistemine göre destek ya da iletişim formu.
- Bulunamayan adresi hiç yazmayın; saldırganın verdiği bir metindir.
- Düşen her view kapısı da buraya iner — yarım kurulmuş bir temanın gösterdiği şey budur.
Bakım Belgesini Kurun
Layout genişletmeyen tek view budur. Bakım anahtarını açın, yoksa sayfayı göremezsiniz.
- Kendi doctype'ınız, kök elemanınız ve head'inizle açın; dili ve yönü şablon değişkenlerinden alın.
- İlk boyama guard'ınızı son yedek değeri dahil birebir kopyalayın.
- Deri token'larınızı tema ayarlarından yazın.
- Yalnız logoyu, mesajı ve dil değiştiriciyi koyun — gezinme, sepet ya da hesap menüsü yok.
- Dört enjeksiyon noktasını koruyun ki bir modül kapalı siteye hâlâ ulaşabilsin.
Çekirdek Sayfalarına Doğru Dokunun
- Paylaşılan kabuğu require edin ve yardımcılarını kullanın; stil bloğunu asla kopyalamayın.
- Metni locale dosyalarından alın: PHP'deki İngilizce dizeler yalnızca çevirici yedekleridir.
Referans
Kabuk Yardımcıları
$sys = require __DIR__ . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'shell.php';
// Değerler
$sys['lang']; // dil paketinden 'en', 'tr', ...
$sys['dir']; // 'ltr' ya da 'rtl'
$sys['app']; // sistemin taban adresi
// Çağrılabilirler
$sys['e']($text); // htmlspecialchars, tırnaklar dahil, UTF-8
$sys['l']($file, $key, $fallback); // system/{file}/{key} ya da erişilemezse $fallback
$sys['head'](); // yerel yazı tipi bağlantısı + paylaşılan stil
$sys['mark']($shape); // gömülü ikon: 'alert', 'shield' ya da 'tools'
$sys['brand'](); // ürün imzası + sürüm dosyası
$sys['mask']($text); // yönetici dizini yer tutucuyla değiştirilir
// Tipik kullanım, sayfa başına locale dosyası bir kez bağlanır:
$e = $sys['e'];
$L = static fn (string $k, string $fallback): string => $sys['l']('error', $k, $fallback);
Hata Sayfası Neyi Gösterebilir
| Durum | Mesaj | Teknik blok |
|---|---|---|
| Motor hatası: tip ya da ayrıştırma arızası | Genel: özgün metin geliştirici için yazılmıştır | Yalnız geliştirmede |
| Bilerek fırlatılan bir istisna | Gösterilir: operatörün okuması gerekir | Yalnız geliştirmede |
| Kapanışta yakalanan ölümcül hata, sınıf bilinmiyor | Genel; motor hatası sayılır | Yalnız geliştirmede |
| Hatalı satırın çevresindeki kaynak parçası | Geçerli değil | Yalnız geliştirmede; okunur, okunamaz ya da şifreli ve çok büyük durumları karşılanır |
| İstek verisi | Geçerli değil | Yalnız geliştirmede, parola ve jetonlar önce temizlenir |
Tema Tarafı Sözleşmesi
// Manifest yüklendiyse VE tema dizini gerçekten oradaysa true.
public function exists(): bool;
// views/<view>.<uzantı> gerçek bir dosyaysa true. Uzantı manifest motorunu izler.
public function viewExists(string $view): bool;
// Bir sistem yüzeyini istek dışında render etmek (CLI sağlık kontrolü, bir probe):
// chose("website") temayı atlar, bu yüzden temayı doğrudan çağırın.
public function render(string $view, array $data = []): string;
$page_title, $meta_robots ve çıkış yollarını seçen $support_enabled ile $kbase_enabled. Tam müşteri veri paketi burada hazırlanır.
Bakım View'ına Ne Ulaşır
Liste bundan ibaret. Tam müşteri veri paketi hazırlanmaz: menü, sepet, duyurular ve hesap değişkenleri eksiktir; birini okuyan view hiçbir şey göstermez ve log'a uyarı yazar.
ltr ya da rtl. Bunları şablon motoru her view'a ekler, veri paketi olmayan sayfada da var olurlar.
key, name, link, selected ve flag-img taşır. Kontrolü yalnız sayı birden büyükken gösterin.
$setting temalı her view'a ulaşır, kapalı site de operatörün renklerini korur.
Örnek
<!DOCTYPE html>
{* layouts/default.tpl DEĞİL: site kapalıdır, yani hiçbir gezinme, sepet ya da
hesap kabuğu oraya geri bağlanamaz. Dil değiştirici tek kontroldür ve BU
sayfayı seçilen dilde yeniden render eder. *}
<html lang="{$ui_lang|default:'en'}" dir="{$ui_dir|default:'ltr'}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, nofollow">
<title>{lang key='system/maintenance/meta'}</title>
{* Guard'ı ana layout'tan BİREBİR kopyalayın. Son yedek değeri tema script'inin
değeriyle eşleşmelidir; yoksa sayfa bir modda boyanır ve bir kare sonra
diğerine döner. Hata yalnız hiç kayıtlı değeri olmayan ziyaretçide görünür;
geliştiricinin kendi tarayıcısının onu hiç üretememesinin sebebi budur. *}
<script>
var t = localStorage.getItem('wstyle-theme') || 'light';
document.documentElement.setAttribute('data-bs-theme', t);
</script>
<link rel="stylesheet" href="{asset path='css/theme.css'}">
<link rel="stylesheet" href="{asset path='css/maintenance.css'}">
{* Kapalı sitede de operatörün renkleri geçerlidir. *}
<style>:root { --brand: {$setting.primary_color}; }</style>
{hook name='ui:client.head.css'}
{hook name='ui:client.head.js'}
</head>
<body class="maintenance-page">
{hook name='ui:client.body.begin'}
<header>
<a href="{link route='home'}"><span>{$company_name}</span></a>
{* Sayfadaki TEK kontrol. *}
{if $lang_count > 1}
{foreach $lang_list as $l}
<a href="{$l.link}">{$l.name}</a>
{/foreach}
{/if}
</header>
<main id="maintenance-content">
<p>{lang key='system/maintenance/text'}</p>
</main>
{hook name='ui:client.body.end'}
</body>
</html>
public function main(): void
{
// Bilerek asgari: kapalı bir sayfanın menüye, sepete ya da duyuruya ihtiyacı yok.
$this->takeDatas(["language", "website_logos", "company_name", "lang_list"]);
$this->addData("current_year", date("Y"));
// İKİ denetim de gerekli. viewExists olmadan, bakım view'ı taşımayan bir tema
// düz PHP yoluna düşer, hiçbir dosya bulamaz ve boş string döner: hiçbir yerde
// hata olmadan boş bir sayfa.
$theme = \Theme::active();
if ($theme->exists() && $theme->viewExists("maintenance"))
$html = $this->view->chose("website")->render("maintenance", $this->data, true);
else
$html = $this->view->chose("system")->render("maintenance", $this->data, true);
// Render sonrası enjekte edilir, böylece hem tema view'ına hem yedeğe ulaşır.
$injection = implode('', \Hook::run('ui:client.maintenance.body', $this->data));
if ($injection) $html = preg_replace('/<\/body>/i', $injection . '</body>', $html, 1);
echo $html;
}
Tuzaklar
İkisi de aynı kayıtlı değeri okur ve aynı son yedeğe ihtiyaç duyar. Ayrıştıklarında sayfa bir modda boyanır, bir kare sonra döner; bunu yalnız hiç tercih kaydetmemiş ziyaretçi görür.
İstek adresinde, dökülen istek verisinde ve tekrar dene butonunun hedefinde görünür; ekran görüntüsü onu da taşır. Her şeyi maskeden geçirin, tekrar dene bağlantısı boş kalsın.
Bu sayfalar sunucu rahatsızken görünür; içerik ağını beklemek boşa zamandır. İkonlar gömülüdür, yazı tipi sistem yedeğiyle yereldir ve hiç çerçeve yoktur.
Motor arızası geliştirici metni taşır, genel bir cümleyle değişir. Bilerek fırlatılan istisna ise gösterilir: operatörün onu okuması gerekir.
Her bölüm açık gelir: okuyan kişi sorunu burada çözer. Gövdeyi otomatik kenar boşluklarıyla ortalayın; ortalama hizalaması içerik uzayınca üst kenarı kırpar.
İlgili Makaleler
Geri bildiriminiz için teşekkürler!
Yukarıda bulamadığınız her şey için destek ekibimiz her zaman yanınızda.