Sayfa Ekranları

1.8k görüntülenme Markdown

Her genel ve müşteri sayfası temanızın içindeki tek bir view dosyasına çözülür; burada adresten dosyaya tam eşleme var.

Genel Bakış

Bir controller asla şablon dosyası adı vermez. Bir view adı verir, yani uzantısız ve bölü işaretiyle ayrılmış bir yol; motor onu temanızın içindeki dosyaya çevirir: render("account/services") bir Smarty temasında views/account/services.tpl, Twig temasında views/account/services.twig olur. Uzantıyı tema manifestiyle seçer, controller hangi motorun çalıştığını hiç öğrenmez.

Temayı taşınabilir yapan tek kural budur. Tam bir temanın ihtiyaç duyduğu 69 view dosyasını verirseniz her sayfa cevap verir. Eksik verirseniz controller o adresler için 404 döner, çünkü site controller'larının neredeyse hepsi view'ı önceden denetler.

Yapı

Views Ağacı

View'lar alana göre gruplanır, tek klasöre düz yığılmaz. Aşağıdaki sayımlar ürünle gelen temaların dosya dosya ölçümüdür: Basic ve WStyle 69'ar view taşır.

KlasörBasic / WStyleOrada ne yaşar
views/ (kök)6Doğal bir ailesi olmayan bağımsız sayfalar: ana sayfa, alan adı arama, SMS tanıtım sayfası, lisans doğrulama, 404, bakım
views/products/3Katalog: kategori sayfası, yazılım detay sayfası, yazılım mağazası
views/checkout/14Yapılandırma, sepet, ödeme adımı ve bunların paylaştığı parçalar
views/account/25Giriş yapmış müşteri paneli, panodan alt hesaplara kadar
views/auth/6Giriş, kayıt, parola sıfırlama, hesap etkinleştirme, davet
views/content/14Editoryal sayfalar: blog, duyuru, referans, bilgi bankası, CMS sayfaları, iletişim
views/page/1Dosya tabanlı sayfalar: buradaki bir view, controller ve rota olmadan bir adres yayımlar

Layout, Partial ve Component

View'lar yalnız sayfa gövdesini tutar. Etraflarındaki kabuk üç kardeş klasörde yaşar ve tema kökünden referans verilir, view'a göre değil.

layouts/ Bir view'ın genişlettiği tam belgeler. WStyle dört tane taşır: default (genel ve müşteri kabuğu), auth (sahne ve form ikilisi), checkout (odaklı huni kabuğu), invoice (yazdırmaya uygun).
partials/ Layout'un dahil ettiği kabuk parçaları, üç küme hâlinde. Genel: header, topbar, drawer, footer, announcements, cookie-notice. Müşteri paneli: client-topbar, client-sidebar, client-footer. Huni: checkout-header, checkout-footer.
components/ Bir view'ın argümanla dahil ettiği yeniden kullanılabilir bloklar: plan ızgaraları, pano panelleri, ödeme yöntemi listeleri, yapılandırma alt kartları.
tables/ Müşteri liste sayfaları (hizmetler, alan adları, faturalar, talepler) için düz PHP tablo presetleri; şablon değil, liste motoru okur.

Referans

Çözümleme API'si

Bir sayfanın var olup olmadığına ve nasıl gösterileceğine üç metot karar verir. Üçü de Theme::active()'in döndürdüğü tema örneğindedir.

tam imzalar
public static function active(): self;

// views/<view>.<uzantı> gerçek bir dosyaysa true. $view bölü ile ayrılır, uzantı yazılmaz.
// '' ve içinde '..' geçen her yol, diske hiç bakılmadan false döner.
public function viewExists(string $view): bool;

// Tek bir view'ı string'e render eder, istek bağlamından bağımsız (cron, mail, PDF).
public function render(string $view, array $data = []): string;

// Tek bir tema ayarını okur: config.php değeri ya da theme.php'deki şema varsayılanı.
public function setting(string $key): mixed;

// Manifestin meta bloğu, çekirdeğin okuduğu tema bayrakları dahil.
public function meta(): array;

// Temanın assets/ klasörü altında mutlak URL. {asset} şablon fonksiyonunun arkasındaki metot.
public function assetUrl(string $path = ''): string;
Theme::viewExists() Uzantı manifest motorundan gelir: twig için .twig, php için .php, diğer her durumda .tpl. Yalnız website controller'ları 41 kez çağırır ve bunların her biri bir sayfayı korur.
Theme::render() Bağlamdan bağımsız gösterim. Cron, mail ve PDF kodundan bunu kullanın; View::chose("website"), CRON ya da ADMINISTRATOR tanımlıyken temayı sessizce atlar.
View::render() Her controller'ın kullandığı istek içi yol. Adres değişkenlerini ekler, filter:template.variables kancasını koşturur, view'ın içerik scope'unu yükler ve son olarak biten işaretlemeyi filtreler.
TemplateEngine::render_file() İkisinin de altındaki motor dağıtıcısı. Her çağrıda taze bir Smarty ya da Twig örneği kurar ve view yoluna views/ önekini ekler.

Kök View'lar

ViewGösterenAdres
homecontrollers/website/index.phphome rotası, sitenin kökü
domaincontrollers/website/domain.phpdomain rotası, /domain
sms-introductioncontrollers/website/sms.phpinternational-sms rotası, /international-sms
license-verificationcontrollers/website/license.phplicense rotası, /license-verify
404Controllers::page_404rota yok: eşleşmeyen her adres ve düşen her view kapısı
maintenancecontrollers/system/maintenance.phprota yok: bakım modu açıkken her adres

Katalog View'ları

ViewGösterenAdres
products/categorycontrollers/website/products.phpproducts ve products-2 rotaları, /{kategori} ve /{tür}/{kategori}
products/softwarecontrollers/website/softwares.phpsoftwares ve softwares_cat rotaları, /softwares ve /softwares/{kategori}
products/detailcontrollers/website/product-detail.phpsoftware_detail rotası, /software/{slug}

Ödeme Akışı View'ları

On dördün dördü bir parçadır: layout taşımaz, başka bir şablon tarafından içeri alınır ya da AJAX yanıtı olarak döner.

ViewGösterenAdres
checkout/configurecontrollers/website/configure.phpconfigure, configure-p rotaları, /configure/{tür}/{id}
checkout/configure-addonconfigure.php, page_addon()aynı yapılandırma adresinin eklenti dalı
checkout/configure-domainconfigure.php, page_edit_item()configure-edit rotası, /configure/edit/{anahtar}
checkout/cartcontrollers/website/cart.phpcart ve basket rotaları, /cart
checkout/checkoutcontrollers/website/checkout.phpcheckout rotası, /checkout
checkout/order-completecheckout.php, page_complete()order-complete rotası, /checkout/complete/{id}
checkout/invoice-completeinvoices.php, page_complete()invoice-complete rotası, /invoices/complete/{id}
checkout/paycontrollers/website/pay.phppay rotası, /pay/{id}
checkout/pay-resultcontrollers/website/payment.phppay-successful ve pay-failed rotaları
checkout/pay-choicesClientCheckout, ClientInvoicePay, BalanceOps operation'larıparça: AJAX yanıtı, üç çağıran paylaşır
checkout/section-accountcheckout/checkout.tplparça: ödeme gövdesi dahil eder
checkout/section-billingcheckout/checkout.tplparça: ödeme gövdesi dahil eder
checkout/section-paymentcheckout/checkout.tplparça: ödeme gövdesi dahil eder
checkout/section-rail-itemscheckout/checkout.tplparça: sipariş özeti rayı dahil eder

Müşteri Paneli View'ları

ViewGösterenAdres
account/dashboard-herocontrollers/website/dashboard.phpmy-account rotası, /dashboard, hero yerleşim varyantı
account/dashboard-standarddashboard.phpaynı adres, standart yerleşim varyantı
account/settingscontrollers/website/account.phpinfo rotası, /account/info
account/servicesservices.php, page_list()services rotası, /services
account/service-detailservices.php, page_detail()service-detail rotası, /services/detail/{id}
account/service-transfer-approveservices.php, page_transfer_approve()service-transfer-approve rotası, yolda jeton taşır
account/domainsdomains.php, page_list()domains rotası, /domains
account/domain-detaildomains.php, page_detail()domain-detail rotası, /domain-detail/{id}
account/invoicesinvoices.php, page_list()invoices rotası, /invoices
account/invoice-detailinvoices.php, page_detail()invoice-detail rotası, /invoices/detail/{id}
account/subscriptionsinvoices.php, page_subscriptions()invoice-subscriptions rotası, /invoices/subscriptions
account/bulk-payinvoices.php, page_bulk_pay()bulk-pay rotası, /invoices/bulk-pay
account/balancecontrollers/website/balance.phpbalance rotası, /balance
account/ticketstickets.php, page_list()tickets rotası, /tickets
account/ticket-detailtickets.php, page_detail() ve page_guest_view()ticket-detail ve ticket-guest rotaları
account/ticket-createtickets.php, page_create()ticket-create rotası, /tickets/create
account/ticket-msgtickets.phpparça: tek bir yanıt, AJAX yoklayıcısına döner
account/smssms.php, page_panel()sms rotası, /sms
account/sub-accountscontrollers/website/sub-accounts.phpsub-accounts rotası, /sub-accounts
account/api-credentialscontrollers/website/api.phpapi rotası, /api-credentials
account/affiliatecontrollers/website/affiliate.phpaffiliate rotası, /affiliate
account/reseller-programreseller.php, page_program()reseller rotası, misafir ve bayi olmayan görünümü
account/resellerreseller.php, page_dashboard()reseller rotası, bayinin kendi paneli
account/license-transfer-verifyverify-license-transfer.phpverify-license-transfer rotası, yolda jeton taşır
account/access-deniedControllers, izin kapısırota yok: alt hesabın açamayacağı her müşteri sayfası

Kimlik View'ları

Altısı da sign controller'ındaki tek bir özel yardımcıdan geçer; kapıyı, canonical bağlantısını ve sayfa başlığı konvansiyonunu bu yüzden paylaşırlar.

ViewGösterenAdres
auth/loginsign.php, page_in()sign-in rotası, /login
auth/registersign.php, page_up()sign-up rotası, /register
auth/forget-passwordsign.php, page_forget()sign-forget rotası, /forget-password
auth/reset-passwordsign.php, page_reset()sign-reset rotası, /reset-password
auth/activatesign.php, page_activate()account-activation rotası, /account-activation
auth/accept-invitesign.php, page_invite()accept-invite rotası, /invitation/{jeton}

İçerik View'ları

ViewGösterenAdres
content/blogcontrollers/website/articles.phparticles rotası, /articles
content/blog-detailpage-detail.phparticles_detail rotası, çıplak slug
content/blog-comment-listClientBlogComments operation'ıparça: yorum listesi, AJAX ile yeniden yüklenir
content/newscontrollers/website/news.phpnews rotası, /news
content/news-detailpage-detail.phpnews_detail rotası, çıplak slug
content/referencescontrollers/website/references.phpreferences rotası, /references
content/references-detailpage-detail.phpreferences_detail rotası, çıplak slug
content/page-detailpage-detail.phpnormal_detail ve contract_detail rotaları, her CMS sayfası ve sözleşme
content/knowledgebaseknowledgebase.phpkbase rotası, /knowledgebase
content/knowledgebase-categoryknowledgebase.phpkbase_category rotası, /knowledgebase/category/{slug}
content/knowledgebase-articleknowledgebase.php ve knowledgebase_detail.phpkbase_detail rotası, /knowledgebase/article/{slug}
content/contactcontrollers/website/contact.phpcontact rotası, /contact
content/newsletter-unsubscribecontrollers/website/newsletter.phprota anahtarı yok: ilk URL parçası controller'a çözülür
content/addoncontrollers/website/addon.phprota anahtarı yok: /addon/{ModulAdi}, eklenti modülünün kendi sayfası

Dosya Tabanlı Sayfalar

views/page/ altındaki bir view kendi başına bir adres yayımlar. Controller yok, rota kaydı yok, çekirdek düzenlemesi yok. Kayıtlı her rota eşleşmekte başarısız olduktan sonra en sonda bir yönlendirme filtresi çalışır ve dosya oradaysa isteği jenerik bir controller'a verir.

views/page/about.tpl /about adresinde yayımlanır. Slug a-z 0-9 / _ - ile sınırlıdır ve her .. reddedilir; iki kez denetlenir: bir kez yönlendirme filtresinde, bir kez controller'da.
filter:routing.match Router'ın son yedeği. Kayıtlı bir rotayı asla gölgelemez, yani dosya tabanlı sayfa eklemek mevcut bir adresi hiçbir zaman bozamaz.
locale scope page/ öneki locale'e yansımaz: views/page/about.tpl dosyası locale/{dil}/about.php'yi okur, çünkü scope klasörü değil genel URL'yi yansıtır.

View Eksik Olduğunda Ne Olur

Kimin sorduğuna göre üç ayrı şey. Hangisine baktığınızı bilmek, hiç fırlatılmamış bir şablon hatasını aramakla geçecek bir saati kurtarır.

ÇağıranDavranışGördüğünüz
viewExists() ile koruyan controllerOnun yerine 404 sayfasını dönerTemanızın 404 view'ıyla HTTP 404, hiç hata yok
Kapısız bir viewMotor fırlatır, dağıtıcı yakalar ve boş string dönerBoş sayfa. Loga bir uyarı yazılır, geliştirme modunda mesaj biçimli bir blok içinde görünür
İsteğe bağlı bir özellik view'ıÖzellik kendini kapatırHata yok, farklı bir kod yolu çalışır (aşağıdaki PDF tuzağına bakın)

Örnek

Baştan sona tek bir sayfa: view'ı adlandıran controller satırı ve ona cevap veren view dosyası. İkisi birlikte gösteriliyor çünkü aralarındaki tek sözleşme view yoludur.

controller tarafı
// controllers/website/services.php, page_list()

// Önce kapı: hizmet listesi taşımayan bir tema boş sayfa yerine 404 döner.
if (!Theme::active()->viewExists("account/services")) return $this->page_404("website");

$this->addData("page_title", Language::gc("website/services/meta/title"));
$this->addData("canonical_link", LinkGenerator::client("services"));
$this->addData("meta_robots", "noindex, nofollow");

// Müşteri kabuğunu (kenar çubuğu, alt menü, bildirim zili) açar ve aktif sekmeyi işaretler.
$this->addData("show_client_subnav", true);
$this->addData("subnav_active", "services");

// Logo, şirket adı, sözleşme bağlantıları, para birimi listesi: müşteri kabuğu verisi.
$this->set_predefined_data("client");

// Uzantı yok, motor yok: "account/services" AKTİF temaya karşı çözülür.
return $this->view->chose("website")->render("account/services", $this->data, true);
views/account/services.tpl, cevap veren view
{extends file='layouts/default.tpl'}

{* Çekirdek JS'in KENDİSİNİN tükettiği stil ve kütüphaneler head'e girer. *}
{block name=head}
    <script src="{asset path='js/list.js'}" defer></script>
{/block}

{* Sayfa script'leri scripts'e, çekirdek paketten SONRA girer; yoksa window.WStyle hazır değildir. *}
{block name=scripts}
    <script src="{asset path='js/services.js'}" defer></script>
{/block}

{block name=content}
<section class="pt-4 pb-4">
    <div class="container list-page" data-services-page>
        {csrf form='services'}

        <nav aria-label="{lang key='website/services/breadcrumb-aria'}">
            <ol class="breadcrumb mb-1">
                <li class="breadcrumb-item"><a href="{link route='my-account'}">{lang key='website/index/subnav-dashboard'}</a></li>
                <li class="breadcrumb-item active" aria-current="page">{lang key='website/services/title'}</li>
            </ol>
        </nav>
    </div>
</section>
{/block}

Tuzaklar

Eksik view bir istisna değil, boş sayfadır

Motor dağıtıcısı her throwable'ı yakalar ve üretimde boş string döner. Bir sayfa hiç görünmüyorsa verinize bakmadan önce view dosyasını arayın. Geliştirme modunda yakalanan mesaj sayfada görünür; bunu doğrulamanın en hızlı yolu odur.

Arka plan çıktısı istek yolundan geçmemeli

View::chose("website") temayı yalnız CRON ve ADMINISTRATOR tanımsızken çözer. Zamanlanmış bir görevden çağrıldığında sessizce düz PHP şablonlarına düşer, şablon dosyanızı bulamaz ve boş string döner. Cron, mail eki ve PDF üretiminde Theme::active()->render() kullanın.

Pano tek view'dır ya da iki, kararı tema verir

Controller önce account/dashboard'u sorar. O dosya varsa temanın tek panosu vardır ve yerleşim ayarı tümüyle yok sayılır. Yalnız yokken controller tema ayarına göre account/dashboard-hero ya da account/dashboard-standard'a düşer. Basic ve WStyle ikiliyi taşır; bir tema bunun yerine tek view'ı da taşıyabilir.

İsteğe bağlı bir view koca bir motoru açabilir

Fatura PDF üretimi başsız Chrome'u yalnız bir Chrome ikilisi çözülüyor ve tema account/invoice-pdf taşıyorsa seçer. Ürünle gelen üç temanın hiçbiri onu taşımıyor, yani bugün gerçekte gömülü üretici koşuyor. O tek dosyayı eklemek her faturanın çıktı motorunu değiştirir.

Bakım view'ı bir sayfa gövdesi değil, tam belgedir

Layout genişletmeyen tek view odur: site kapalıdır, dolayısıyla hiçbir gezinme, sepet ya da hesap kabuğu oraya geri bağlanamaz. Kendi doctype'ı, kendi head'i ve kendi ilk boyama guard'ıyla açılır. Bakım view'ı taşımayan tema, giydirilmemiş olan miras sistem şablonuna düşer.

Faydalı oldu mu?

Geri bildiriminiz için teşekkürler!

Hâlâ Yardıma mı İhtiyacınız Var?

Yukarıda bulamadığınız her şey için destek ekibimiz her zaman yanınızda.