İçeriğe geç

Şablonlar ve Twig yardımcıları

Tema şablonları Twig ile yazılır. Bu sayfa ana şablonun anatomisini, kullanabileceğiniz yardımcıları ve sık yapılan hataları anlatır.

Ana şablon: layout.html.twig

Her sayfa layout.html.twig'i genişletir. Aşağıdaki iskelet, varsayılan temadan sadeleştirilmiş, çalışan bir ana şablondur:

<!DOCTYPE html>
<html lang="{{ app.request.locale }}">
<head>
    <meta charset="UTF-8">
    {{ cp_consent_mode() }}
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    {% block seo %}
        {% set seo_title %}{% block title %}{% endblock %}{% endset %}
        {% set seo_description %}{% block meta_description %}{% endblock %}{% endset %}
        {% set seo_robots %}{% block meta_robots %}index, follow{% endblock %}{% endset %}
        {{ cp_seo_head({ title: seo_title, description: seo_description, robots: seo_robots }) }}
    {% endblock %}

    <link rel="icon" type="image/png" href="{{ cp_appearance().favicon }}">
    <link rel="stylesheet" href="{{ cp_theme_url('dist/style.css') }}">

    {% set cpFonts = cp_font_stylesheet() %}
    {% if cpFonts %}<link rel="stylesheet" href="{{ cpFonts }}">{% endif %}

    <style{{ csp_nonce_attr() }}>{{ cp_appearance_css() }}</style>
    {% block stylesheets %}{% endblock %}
    {{ cp_hook('theme.head.end', {}) }}
</head>
<body class="{% block body_class %}{% endblock %}">
    <a class="skip-link" href="#main">{{ 'website.skip_to_content'|trans }}</a>
    {% include '@Theme/partials/header.html.twig' %}

    <main id="main">
        {% block content %}{% endblock %}
    </main>

    {{ cp_hook('theme.footer.before', {}) }}
    {% include '@Theme/partials/footer.html.twig' %}

    {{ cp_cookie_consent() }}
    <script{{ csp_nonce_attr() }} src="{{ cp_theme_url('dist/main.js') }}"></script>
    {% block javascripts %}{% endblock %}
</body>
</html>

Modüllerin doldurduğu bloklar

Modül şablonları {% extends '@Theme/layout.html.twig' %} ile bu ana şablonu genişletir ve şu blokları doldurur. Ana şablonunuz bu blokları tanımlamak zorundadır, yoksa modüller içeriğini yerleştiremez:

Blok Modülün koyduğu
title, meta_description, meta_robots, meta_keywords SEO başlığı, açıklaması, robots değeri
stylesheets Sayfaya özel CSS
body_class <body> sınıfı
content Sayfanın asıl içeriği
javascripts Sayfaya özel betik

Temanın sunması gereken iki kanca

{{ cp_hook('theme.head.end', {}) }}       {# </head> öncesi: analitik sayaçları vb. #}
{{ cp_hook('theme.footer.before', {}) }}  {# alt bilgi öncesi: modüllerin kartları #}

Bu iki satır yoksa istatistik modülleri ve forum özet kartları gibi katkılar görünmez. Başka tema kancaları: theme.header.alerts, theme.header.user_badge.

Şablonları geçersiz kılmak

Modül sayfaları @Theme/... yoluyla çağrılır. Bir sayfanın görünümünü değiştirmek için temanıza aynı yoldaki şablonu koyun:

Resources/views/blog/show.html.twig       blog yazısı
Resources/views/blog/archive.html.twig    blog arşivi
Resources/views/page/show.html.twig       sayfa
Resources/views/forum/topics.html.twig    forum konuları
Resources/views/search/index.html.twig    arama sonuçları
Resources/views/partials/header.html.twig
Resources/views/partials/footer.html.twig

Yol, varsayılan temadaki yolla birebir aynı olmalıdır. Şablonlarınızı varsayılan temanın aynı dosyasını kopyalayıp değiştirerek başlatın: değişken adlarını ve blokları ondan görürsünüz.

Oturumu başlatmayan yardımcılar

Ön yüzde `app.user` kullanmayın

Twig'in standart app.user, is_granted() ve app.flashes ifadeleri anonim ziyaretçide bile oturum başlatır. Oturumlu yanıt herkese ortak önbelleğe alınamaz; sitenin önbelleği çöker. CPalius bunlar için oturum güvenli karşılıklar sunar:

Standart Ön yüzde kullanın Davranış
app.user cp_user() Oturum çerezi yoksa null
is_granted('x') cp_is_granted('x') Oturum çerezi yoksa false
app.flashes cp_flashes() Oturum çerezi yoksa boş
{% set me = cp_user() %}
{% if me %}
    <a href="/hesap">{{ me.username }}</a>
{% else %}
    <a href="/login">{{ 'website.login'|trans }}</a>
{% endif %}

Yönetim ekranlarında (Studio, AACP) oturum her zaman vardır; standart ifadeler orada serbesttir.

Yardımcı referansı

Adres ve varlık

Yardımcı Ne yapar
cp_theme_url('dist/style.css') Temanın bir dosyasının sürümlü adresi (önbellek kırma); dosya public/themes/<tema>/ altına ilk kullanımda kopyalanır
cp_asset('yol') AssetMapper ile derlenmiş çekirdek varlığının adresi
cp_path_if_exists('rota_adı', {…}) Rota yoksa boş dize döner; modül kapalıyken menü bağlantısını kırmaz
csp_nonce_attr() Satır içi <script>/<style> için nonce özniteliği
asset|cp_thumb(400, 300) Yüklenmiş görselin küçük resmi (ikinci ve üçüncü parametre boyut; 'fit' sığdırma)

Menü ve alanlar

Yardımcı Ne yapar
cp_menu_location('main_header') Konuma atanan menüyü hazır işaretlemeyle yazdırır
cp_menu_location_items('main_header') Kendi işaretlemeniz için öğe ağacını verir
cp_menu('ad') Adlandırılmış menünün öğe ağacını (label, url, openInNewTab, children) dizi olarak verir
cp_widget_area('sidebar') Bir widget alanını çizer
cp_field(node, 'alan') Bir alanı biçimlendirerek yazdırır
cp_field_value(node, 'alan') Alanın ham değeri
cp_fields(node, 'grup') Bir alan grubunu yazdırır
cp_has_field(node, 'alan') Alan dolu mu
cp_fields_preload(nodes) Listedeki referansları toplu yükler
cp_entity_view(node, 'teaser') Varlığı bir görüntüleme modunda çizer

Dil

Yardımcı Ne yapar
cp_locales() Etkin diller listesi
cp_locale_switcher('buttons') ya da 'dropdown' Hazır dil değiştirici
cp_locale_links() Mevcut sayfanın diğer dillerdeki adresleri
cp_locale_url('en') Mevcut sayfanın belirli dildeki adresi
cp_hreflang_links() <link rel="alternate" hreflang> etiketleri (<head> içine)
'anahtar'|trans Çeviri

SEO

Yardımcı Ne yapar
cp_seo_head({…}) Başlık, açıklama, canonical, Open Graph etiketleri (Seo modülü yoksa temel etiketler)
cp_schema_org(node) schema.org JSON-LD

Görünüm ve tercihler

Yardımcı Ne yapar
cp_appearance() Yöneticinin seçtiği marka verisi (logo, favicon, renkler)
cp_appearance_css() Seçilen renk/ölçülerin :root CSS değişkenleri
cp_font_stylesheet() Yazı tipi ayarlarından üretilen CSS adresi (yoksa boş)
cp_consent_mode() Google Consent Mode v2 varsayılanları (<head> içinde)
cp_cookie_consent() Çerez onayı çubuğu (gövde sonunda)

Kullanıcı ve yetki

Yardımcı Ne yapar
cp_user(), cp_is_granted('x'), cp_flashes() Oturum güvenli kullanıcı, yetki ve flash mesajlar
cp_current_user_avatar_url() Oturumdaki kullanıcının avatar adresi
cp_notification_unread_count(), cp_recent_notifications() Bildirim sayacı ve son bildirimler

Metin

Yardımcı Ne yapar
text|text_format('basic_html') Metni bir metin biçiminden geçirip güvenli HTML verir
text|reading_time Tahmini okuma süresi
date|cp_date / date|cp_date(true) Dile uygun tarih (ikinci biçim saatle birlikte)

Sistem

Yardımcı Ne yapar
cp_version() Çekirdek sürümü
cp_hook('nokta', {…}) Hook noktasını çizer

Modüller kendi yardımcılarını da ekler (ör. Vitrin: cp_showcase_items; Mesajlar: cp_messages_unread). Bunlar yalnızca modül etkinken vardır; temanızda kullanıyorsanız cp_path_if_exists gibi korumalarla ya da modülün etkinliğini kontrol ederek yazın.

Sık yapılan hatalar

  • for ... if söz dizimi Twig 3'te yoktur. Süzgeç kullanın: {% for x in items|filter(i => i.active) %}.
  • Makro görünürlüğü: bir alt şablonun üstünde içe aktarılan makro, o şablonun block içinde görünmez. Makroyu bloğun içinde içe aktarın.
  • Kaçışlama: kullanıcı verisini |raw ile basmayın. Zengin metin için text_format süzgecini kullanın.
  • Dış kaynak: <script src="https://cdn..."> CSP tarafından engellenir. Kütüphaneyi temanın dist/ klasörüne alın.
  • Satır içi betik: nonce yoksa çalışmaz: <script{{ csp_nonce_attr() }}>.
  • Çeviri anahtarı yok: 'anahtar'|trans anahtarı olduğu gibi yazar. TR ve EN dosyalarına ekleyin.
Son güncelleme: 13.10.2026