Bildirim Şablonları Nasıl Çalışır

1.6k görüntülenme Markdown

Platformun gönderdiği her e-posta ve her kısa mesaj, olay ve dil başına diskteki üç dosyadan üretilir. Bir şablon yazarı bu dosyaların sahibidir, tıpkı bir tema yazarının view'ının sahibi olduğu gibi.

Genel Bakış

Bildirim kodun içinde yazılmaz. Kod bir şeyin olduğuna karar verip olguları teslim eder; sözcükler, işaretleme ve konu satırı templates/notifications altında yaşar. Bir kurulum müşterisinin okuduğu metni geliştiriciye ihtiyaç duymadan değiştirebilir, bir modül de kendi sözcüklerini paketleyebilir.

Birim olaydır ve grup/ad biçiminde yazılır. Her olay, kurulu her dilde üç dosyaya sahiptir: e-posta gövdesi, kısa mesaj gövdesi ve konu satırını taşıyan küçük bir dosya. E-posta gövdesi bir belge değil parçadır.

Şablona iki şey ulaşır. Grubun çözümleyicisi (resolver) çağıranın verdiğini (bir fatura satırı, bir hizmet kimliği, bir talep) adlandırılmış değişkenlere çevirir. Platform da kurulumun kendi değerlerini üstüne ekler: logolar, renkler, şirket bilgileri ve alıcının profili. Şablon yalnızca gösterir.

Yapı

Dosya Düzeni

Üç kök var ve her biri ayrı bir soruyu yanıtlar. Konu satırı ve kısa mesaj, e-posta nasıl görünürse görünsün aynı okunur; tasarımların tamamen dışında yaşarlar. E-posta gövdesi ise onu üreten tasarıma aittir.

düzen
templates/notifications/
├── content/                     # PAYLAŞILAN METİN — tek kopya her tasarıma hizmet eder
│   └── en/invoice/
│       ├── invoice-created.json   # {"subject": "..."}
│       └── invoice-created.txt    # kısa mesaj gövdesi, hiç kabuk yok
├── themes/                      # TASARIM — kurulu tasarım başına bir dizin
│   ├── aurora/                  # ürünle birlikte gelen tasarım
│   │   ├── header.html            # en dıştaki kabuk
│   │   ├── content.html           # gövde yuvası, tek bir {$notifi_body} yer tutucusu
│   │   ├── footer.html            # kapanış kabuğu
│   │   └── en/invoice/
│   │       └── invoice-created.html   # e-posta gövdesi, kabuğun bir PARÇASI
│   └── ledger/                  # ikinci tasarım; olayların yalnız bir kısmını taşıyabilir
├── custom/                      # operatörün kendi düzenlemeleri, tasarım başına bir ağaç
│   └── ledger/en/invoice/invoice-created.html
└── .htaccess                    # bu ağaçtan HTTP ile hiçbir şey sunulmaz

Bu yolları elle kurmayın: sırayı bilen tek yer aşağıdaki yardımcılardır. O olay için dosyası olmayan bir tasarım maili yine gönderir: gövde taban tasarımdan gelir, kabuk kendisinin kalır.

View::notification_file() E-posta gövdesi: custom/{aktif} → themes/{aktif} → themes/aurora. Var olan ilk dosya kazanır.
View::notification_content_file() Konu satırı ve kısa mesaj, content/{dil} altından — tasarım bu işe hiç karışmaz.
View::notification_write_path() Bir düzenlemenin kaydedildiği yer: taban dışındaki her tasarım için custom/{aktif}. O dosyayı silmek varsayılana döndürür.

Kabuk

E-posta gövdesi tek başına gönderilmez. Platform üç dosyayı tek bir kabukta birleştirir, biten olay gövdesini notifi_body değişkenine atar ve kabuğu aynı değişkenlerle üretir. Kabuk da gövdeyle aynı sırayla çözülür; kendi kabuğunu taşımayan bir tasarım maillerini taban kabuğuyla çerçeveler.

header + content + footer Bu sırayla birleştirilir ve süreç boyunca dil başına önbelleklenir. Her dilde gelen content.html tek bir yer tutucudur, yani çerçeve aslında header ile footer'dır.
olay gövdesi bir parçadır Header bir tabloyu açar ve açık bırakır; olay gövdesi onu sürdürür, footer kapatır. Kendi belgesini açan bir olay gövdesi, hiçbir e-posta istemcisinin yerleştiremeyeceği bir işaretleme üretir.
kısa mesaj kabuk almaz Kısa mesaj kanalında birleştirme hiç yapılmaz: .txt gövdesi logo, footer ve iletişim bloğu olmadan, yazıldığı gibi teslim edilir.
konu da render edilir .json dosyasındaki subject aynı motordan ve aynı değişkenlerden geçer, yani yer tutucu taşıyabilir. Yalnızca e-posta kanalında okunur.

Gruplar ve Çözümleyiciler

Grup aynı anda hem bir dizin hem de yapılandırma dosyasının bir bölümüdür. Değişkenleri hangi çözümleyicinin kuracağını ve alıcının tercihlerinin hangi bildirim kategorisine karşı denetleneceğini o belirler.

GrupGelen olayÇözümleyiciTercih kategorisi
invoice10resolve_invoice_contextfaturalar
service11resolve_service_contextürün
order4resolve_order_contextürün
domain13resolve_domain_contextalan adı
user36resolve_user_contextgenel
user-tickets8resolve_ticket_contextdestek
admin-tickets4resolve_ticket_contextdestek
admin-messages18resolve_admin_message_contextgenel
sms-intl3resolve_sms_intl_contextürün
newsletter2yokdispatch edilmez, aşağıya bakın
license-transfer3yokkayıtlı değil, aşağıya bakın

Son iki satır, bir olayın normal yoldan geçmeden var olabilmesinin iki biçimidir. newsletter yapılandırma kayıtlarına sahip ama çözümleyicisi yok, yani bir dispatch error döner. Şablonları doğrudan üretilip kuyruğa itilir ve değişkenleri bülten kodu kendisi verir. license-transfer ise tam tersi: üç olay diskte durur ve yapılandırmada hiç bölümü yoktur. Düşük seviyeli giriş noktasından gönderilirler; o giriş noktası ayar bulamadığında e-posta ve kısa mesajı açık kabul eder.

Teslim Yolu

Tek bir çağrıdan gerçek bir mesaja giden zincir sabittir ve her adım zinciri bitirebilir.

tek bir dispatch, adım adım
Notification::dispatch('invoice', 'invoice-created', ['entity' => $invoice])
  1. gate:notification.dispatch          bir dinleyici veto edebilir  -> blocked
  2. notifications/invoice/invoice-created okunur                     -> yoksa/kapalıysa disabled
  3. grubun çözümleyicisi: entity -> değişkenler + user_id            -> boş dönerse error
  4. alıcının tercih bitmask'i kategoriye karşı denetlenir            -> opted_out
  5. alıcı listesi kurulur (sahip, ek adresler, yöneticiler)          -> boşsa no_recipients
  6. alıcı BAŞINA render: o alıcının dili ve kanalıyla
  7. olay sync listesindeyse hemen gönderilir, değilse kuyruğa yazılır -> sent | queued
  8. panel içi satırlar yazılır: alıcının kendi satırı ve yönetici kopyası
  9. action:notification.dispatched

Şablon 6. adımda, dispatch başına değil alıcı başına bir kez okunur: aynı olayın iki alıcısı farklı dillerde ve farklı kanallarda okuyor olabilir. 7. adımdaki eşzamanlı liste kısadır ve güvenlik açısından kritik olayları taşır; geri kalan her şey kuyruğu bekler.

Bir ad 1. adımdan önce değişir. E-posta aktarımıyla açılan talepte ticket-replied-by-admin, ticket-replied-by-admin-pipe olur. Zincirdeki her kanca değişen adı görür; adıyla süzen dinleyici iki adı da tanımalıdır. 8. adımda müşteri için yazılan panel içi satır istenen adı korur.

Referans

İki Giriş Noktası

coremio/helpers/notification.php
public static function dispatch(string $group, string $name, array $context = []): array;
public static function send(array $params): array|string|bool;
public static function get_recipients(string $group, string $name, array $context = []): array;
Notification::dispatch() Kullanılacak olan budur. Açma/kapama anahtarına, alıcının tercihlerine ve kapı kancasına saygı gösterir; ne olduğunu status alanında söyleyen bir dizi döner.
Notification::send() Düşük seviyeli olan. Tek bir dizi alır ve çözümleyiciyi tümüyle atlar, yani değişkenleri siz verirsiniz. Şablonsuz gövde, ham adres listesi ve kuyruk işçisinin hazır bir satırı teslim etmesi meşru kullanımlarıdır.
Notification::get_recipients() Bir dispatch'in ilk yarısını aynı argümanlarla çalıştırıp durur: yazmak yerine kime yazılacağını döner. Yeni bir olay bağlanırken işe yarar.

Bir Dispatch Ne Döner

Asla bir boolean değil, istisna da fırlatmaz. Dizi her zaman status taşır; başarılı olan ayrıca batch_id ve items altında alıcı başına bir kayıt taşır.

statusAnlamıNerede kararlaşır
queuedKuyruğa satır yazıldı, teslim bir dakika içinde gelir.normal yol
sentYerinde teslim edildi; olay senkron listesinde ya da çağıran zorladı.normal yol
blockedBir dinleyici olayı veto etti.dispatch kapı kancası
disabledOlayın yapılandırma kaydı yok ya da anahtarı kapalı. Kayıtsız bir olayın verdiği yanıt budur.yapılandırma dosyası
errorGrubun çözümleyicisi yok, çözümleyici boş döndü (bulunmayan fatura, silinmiş müşteri) ya da dispatch içinde bir adım hata verdi. Hata, hata kaydına yazılır ve fırlatılmaz; yanıt message ile partial taşır.çözümleyici haritası ya da dispatch'in içi
opted_outAlıcının tercih bitmask'i grubun kategorisini dışarıda bırakıyor.alıcının profili
no_recipientsKanal anahtarları ve kanal-bazlı tercihler uygulandıktan sonra kimse kalmadı.alıcı listesi kurucusu

partial, yeniden deneyen bir çağırana denemenin güvenli olup olmadığını söyler. false: hatadan önce hiçbir şey çıkmadı, yeniden dispatch bildirimi bir kez gönderir. true: bir mesaj ya da panel içi satır zaten çıktı, yeniden dispatch o kısmı tekrarlar.

Şablon Motoru

Dosyaları hangi motorun ayrıştıracağı kurulum geneli bir ayardır ve options/notification-template-engine anahtarından okunur. Smarty olarak gelir ve ağaçtaki her şablon ona göre yazılmıştır. İki değer daha vardır: Twig ve yalnızca {ad} biçimini anlayan düz dize değiştirme kipi.

Bu motor tema kum havuzu değildir ve onun gibi davranmaz:

otomatik kaçış yok Değerler geldikleri gibi, işaretleme dahil yazılır. Tema varsayılan olarak kaçış uygular; bu motor uygulamaz. Müşterinin yazdığı her şeyde escape değiştiricisini kullanın.
kısıtlı bir politika Şablondan on üç platform sınıfı çağrılabilir ve otuz dokuz dil fonksiyonuna izin verilir. Bunun dışındaki her şey derleme hatasıdır; derleme hatasının sonuçları için tuzaklara bakın.

Kuyruk

NotificationQueue::add() Hazır tek bir satır alır: kanal, alıcı, konu, gövde, ekler, öncelik, toplu iş kimliği, isteğe bağlı zamanlama. Kimliğini döner. Dispatch alıcı başına bir satır yazar.
NotificationQueue::process() Tek bir satırı e-posta ya da kısa mesaj modülü üzerinden teslim eder. Panelin elle yeniden deneme butonu da aynı kod yolunu kullanır. Elle başarısız olan bir satır arka planda da aynı şekilde başarısız olur.
zamanlanmış boşaltma Her dakika çalışır, bir çökmeyle askıda kalan satırları geri alır ve tur başına en çok iki yüz satır dağıtır. Gövde dispatch anında üretildiği için, bir şablonu düzenlemek kuyrukta bekleyen mesajı değiştirmez.

Tuzaklar

Eksik dil dosyası hata değil sessizliktir

Yol alıcının dilinden kurulur ve geri düşme yoktur. Dosya yoksa hiçbir şey üretilmez ve alıcı atlanır. Dispatch geri kalan herkes için yine başarı bildirir. Gelen ağaçta ölçüldü: sekiz olay İngilizcede var, Almancada yok. Almanca okuyan bir müşteri o olaylar için hiçbir şey almaz.

Tek bir bozuk etiket dosyanın tamamını işlenmemiş bırakır

Derleme ya hep ya hiçtir ve hata yakalanıp ham kaynakla yanıtlanır. Yoldan çıkmış tek bir yer tutucu kendi satırında kalmaz: aynı dosyadaki diğer bütün yer tutucular da işlenmeden gider ve müşteri görünür süslü parantezlerle dolu bir mesaj alır. Uyarı operatöre değil loga düşer.

Taban tasarımda ayrı bir bindirme katmanı yoktur

Taban tasarım ürünle birlikte gelir; o etkinken yapılan bir düzenleme doğrudan paketlenmiş dosyanın üzerine yazılır ve sonraki güncelleme onu değiştirir. Başka her tasarım custom/ altına kaydeder, oraya güncelleme dokunamaz.

Yalnız dosyalar bir olay etmez

Üç dosya eklemek size hiçbir şey vermez. Yapılandırma kaydı olmadan anahtar bulunamaz ve dispatch disabled döner. Çözümleyici kaydı olmadan değişkenler hiç var olmaz, etiket olmadan panel ham anahtarı listeler. Üçlü, birbiriyle uyuşması gereken birkaç yerden yalnızca biridir.

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.