İçeriğe geç
Muhammet Şafak
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=...
MAIL_FROM_ADDRESS=noreply@example.com
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ş:

İlgili Yazılar

Sitede Ara

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

Esc ile kapat Pagefind ile güçlendirildi