İçeriğe geç
Muhammet Şafak
en
Web Geliştirme 3 dk okuma

Laravel ile e-posta gönderimi ve şablonları

Laravel Mailable sınıfı ve Blade e-posta şablonları ile işlemsel e-postaları güvenilir ve bakımı kolay şekilde kurmak.


İşlemsel e-posta (transactional email) — yani “kayıt oldunuz”, “siparişiniz alındı”, “şifrenizi sıfırlayın” gibi tetikleyiciye bağlı mesajlar — her web uygulamasının bir noktada ihtiyaç duyduğu şey. Ama “sadece bir e-posta gönder” diye başlayan iş, birkaç hafta sonra içinden çıkılmaz bir PHP mail() yığınına dönüşebiliyor.

Laravel 5.3’te tanıtılan Mailable sınıfları bu karmaşayı önemli ölçüde azalttı. E-posta gönderme mantığını ayrı bir sınıfa taşımak, hem testi kolaylaştırıyor hem de şablonları düzenli tutuyor.

Mailable sınıfı oluşturmak

Artisan komutu işi hızlandırıyor:

php artisan make:mail OrderConfirmed

Bu komut app/Mail/OrderConfirmed.php dosyasını oluşturuyor. Temel yapı şöyle:

namespace App\Mail;

use App\Order;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class OrderConfirmed extends Mailable
{
    use SerializesModels;

    public $order;

    public function __construct(Order $order)
    {
        $this->order = $order;
    }

    public function build()
    {
        return $this->subject('Siparişiniz Alındı')
                    ->view('emails.orders.confirmed');
    }
}

$order public olarak tanımlandığında şablon tarafında otomatik olarak erişilebilir oluyor — ekstra with() çağrısı gerekmiyor. Bu küçük konvansiyonu sevdim; veriyi sınıfın içine gömmek yerine açıkça görmek işlemi daha takip edilebilir kılıyor.

SerializesModels trait’i ise queue’ya alınan e-postalarda devreye giriyor: modelin tamamını serileştirmek yerine yalnızca kimliğini (ID) queue’ya yazıyor ve gönderim sırasında tazeliyor. Büyük model nesnelerini queue’da taşımanın neden sorun çıkardığını bu trait sayesinde erken fark ettim.

Blade e-posta şablonu

resources/views/emails/orders/confirmed.blade.php şablonu normal Blade şablonları gibi yazılıyor:

<!DOCTYPE html>
<html>
<body>
    <h1>Siparişiniz Alındı</h1>
    <p>Sayın {{ $order->user->name }},</p>
    <p>
        #{{ $order->id }} numaralı siparişiniz alınmıştır.
        Toplam tutar: {{ number_format($order->total, 2) }} TL
    </p>
    <p>Siparişinizin detaylarını hesabınızdan takip edebilirsiniz.</p>
</body>
</html>

E-posta şablonlarında @extends ve @section kullanmak mümkün, dolayısıyla ortak bir e-posta layout’u oluşturup tüm mesajlarda paylaşabilirsiniz. Başlık, altbilgi ve marka renklerini tek bir yerde tutmak büyük kolaylık.

Bir detay: e-posta istemcileri (özellikle eski Outlook sürümleri) harici CSS dosyalarını görmezden gelebiliyor. Bu yüzden e-posta şablonlarında stilleri satır içi (style="...") yazmak ya da premailer gibi bir araçla derleme aşamasında satır içine çevirmek gerekiyor. Markdown Mailable bunu kısmen çözüyor; yerleşik şablonlar zaten inline stil kullanıyor.

Gönderme

Controller’dan göndermek tek satır:

Mail::to($order->user)->send(new OrderConfirmed($order));

Queue’ya ekleyerek göndermek içinse:

Mail::to($order->user)->queue(new OrderConfirmed($order));

Queue ile gönderim kullanıcıya anında yanıt dönmesi için önemli; e-posta sunucusu yavaş yanıt verdiğinde HTTP isteğini bekletmiyor. Özellikle SMTP üzerinden gönderilen e-postalarda sunucu bağlantısı bazen birkaç saniyeye uzayabiliyor — bu gecikmeyi kullanıcı hissettirmemek için queue neredeyse zorunlu hale geliyor.

Mail::to() dışında cc() ve bcc() zincirlenebiliyor; birden fazla alıcıya ya da gizli kopyayla göndermek için ayrı bir yöntem aramak gerekmiyor.

Yapılandırma ve ortam farkı

.env dosyasından sürücü seçmek mümkün: smtp, mailgun, sendmail, log… Geliştirme ortamında log sürücüsünü kullanıyorum; e-postalar storage/logs/laravel.log dosyasına yazılıyor, gerçek bir e-posta gönderilmiyor. Üretim ortamında ise SMTP yapılandırması geçerli.

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=...
MAIL_PASSWORD=...
[email protected]
MAIL_FROM_NAME="Uygulama Adı"

Mailtrap gibi bir test aracını geliştirme sürecine erken eklemek, gerçek kullanıcılara yanlışlıkla e-posta atmayı önlüyor. Bunu bir kez yaşadım: yerel geliştirme ortamında gerçek SMTP ayarları kalınca, bir test sırasında gerçek kullanıcılara sipariş onay e-postası gönderildi. O günden beri log sürücüsü geliştirme ortamının standart parçası.

Markdown Mailable

Laravel 5.4 ile gelen Markdown Mailable özelliği, HTML ve düz metin sürümlerini aynı anda oluşturuyor. Yerleşik şablonlar var; mail::message, mail::button gibi bileşenler. Her şirkete özel tasarım gerekmiyorsa bu şablonlar temiz ve hızlı bir başlangıç noktası sunuyor.

return $this->subject('Siparişiniz Alındı')
            ->markdown('emails.orders.confirmed-markdown');

Markdown Mailable’ın bir avantajı daha var: vendor:publish komutuyla yerleşik şablonları projeye kopyalayabiliyorsunuz ve yalnızca HTML/CSS’i değiştirerek markaya uygun hale getiriyorsunuz. Tüm şablonları sıfırdan yazmak yerine var olan temeli özelleştirmek zaman kazandırıyor.

Birden fazla e-posta türü yönetmek

Proje büyüdükçe e-posta türleri çoğalıyor: kayıt onayı, şifre sıfırlama, sipariş bildirimi, fatura… Her biri için ayrı bir Mailable sınıfı ve ayrı bir Blade şablonu olduğunda app/Mail/ klasörü hızla şekilleniyor. Bu yapı dağınık görünse de her e-posta türünü bağımsız olarak değiştirebilmek büyük esneklik sağlıyor. Tek bir sendEmail($type, $data) fonksiyonu yerine her türün kendi sınıfı olması, ileride bir e-postanın şablonunu ya da konu satırını değiştirirken diğerlerini etkilemeden yapabilmenizi sağlıyor.

E-posta gönderimini Mailable sınıflarıyla yapılandırmak, projenin büyümesiyle birlikte gerçekten ödemesini yapıyor. Dağınık mail() çağrıları yerine her mesaj türü için bir sınıf, gönderilen e-postaların neyin ne zaman gittiğini takip etmeyi kolaylaştırıyor.

Etiketler: #Laravel
Paylaş:

Yorumlar

Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.

İlgili Yazılar

Sitede Ara

Yazı, proje ve sayfalarda arama yapmak için yazmaya başlayın.

Esc ile kapat Pagefind ile güçlendirildi