emirhanHCL 1
emirhanHCL
kralhakan2009 1
kralhakan2009
Vahsi Uzman 1
Vahsi Uzman
farkmt2official 1
farkmt2official
Hikaye Ekle

[NODE JS] Express'te Pug Template Engine Kullanımı

Türkiye'de ilk Mobil & PC Aynı Anda Metin2 Oyna. Triarchonline kalıcı ve uzun ömürlü yapısı ile 24 Temmuz'da açılıyor. | 1-99 Mobil Metin2 Triarch HEMEN TIKLA!

nodejs.png


[NODE JS] Express'te Pug Template Engine Kullanımı​


Pug, daha önce Jade olarak bilinen, Express.js ekosisteminin en köklü template engine'lerinden biri. EJS'den farklı olarak tamamen kendine özgü bir syntax kullanıyor. HTML etiketlerini kapatma derdinden kurtaran, indentation tabanlı temiz bir yapıya sahip. Daha az kod yazarak daha okunabilir template'ler oluşturabilirsiniz.

Pug'ın en belirgin özelliği HTML etiketlerini yazmak yerine sadece etiket adını kullanmanız. div yerine sadece div, p yerine sadece p yazarsınız. Kapanış etiketi yok, iç içe yapı indentation ile belirleniyor. Bu yaklaşım Python'un indentation tabanlı yapısına benzer ve kodu çok daha kısa tutar.

İlk başta Pug syntax'ına alışmak biraz zaman alabilir. Ben ilk kullandığımda sürekli indentation hataları yapıyordum ve hata mesajları çok yardımcı olmuyordu. Ama bir kere alıştıktan sonra EJS'den daha hızlı yazabiliyorsunuz. Özellikle karmaşık HTML yapılarında Pug çok daha okunabilir. Ama bu tamamen kişisel tercih meselesi, ekibinizdeki herkesin rahat olduğu engine'i seçmeniz en doğrusu.

Pug'da değişkenler #{{degisken}} syntax'ı ile yazdırılır ve otomatik olarak HTML es#{{degisken}}Escape istemiyorsanız !{{degisken}} kullanırsınız ama bu XSS riski taşır. Attribute'lar parantez içinde yazılır: a(href="/", class="link"). Sınıf ve ID için CSS selector syntax'ı kullanabilirsiniz: div.container#main.

Mixins Pug'ın en güçlü özelliklerinden biri. Mixin'ler reusable template blokları tanımlamanızı sağlar. Parametre alabilir, default değerler tanımlayabilir ve her yerde çağrılabilir. Bu component tabanlı bir yaklaşım sunar ve kod tekrarını minimize eder. Bir kart bileşeni, bir form grubu, bir buton bileşeni gibi yapıları mixin olarak tanımlayıp tekrar tekrar kullanabilirsiniz.

extends ve block anahtar kelimeleri ile layout sistemi kurabilirsiniz. Bir layout dosyası tanımlayıp block content gibi alanlar belirlersiniz. Alt sayfalar bu layout'u extend edip block'ları doldurur. Bu özellik EJS'de built-in olarak yok, ekstra paket gerekiyor. Pug'da doğrudan destekleniyor ve çok pratik.

Conditional rendering için if-else, case-when, each gibi yapılar mevcut. JavaScript ile aynı mantıkta çalışıyorlar. each döngüsü array ve obje üzerinde iterasyon yapar. Ayrıca while döngüsü de desteklenir ama pek kullanılmaz.

Pug'ın dezavantajları da var. HTML bilmeyen birinin Pug kodunu okuması zor olabilir. Editör desteği HTML kadar iyi değil. Ayrıca mevcut HTML şablonlarını Pug'a çevirmek ek iş demek. Online converter'lar var ama mükemmel sonuç vermiyorlar. Özellikle üçüncü parti HTML template'leri kullandığınızda bu bir sorun olabilir.

Performans açısından Pug ve EJS arasında anlamlı bir fark yok. İkisi de template'leri derleyip cache'ler. Pug biraz daha fazla derleme süresi alabilir ama runtime'da aradaki fark ihmal edilebilir düzeyde.

JavaScript:
const express = require('express');
const path = require('path');
const app = express();

// Pug ayarlari
// npm install pug
app.set('view engine', 'pug');
app.set('views', path.join(__dirname, 'views'));

app.use(express.static(path.join(__dirname, 'public')));
app.use(express.urlencoded({{ extended: true }}));
app.use(express.json());

// Ornek veriler
const projeler = [
  {{ id: 1, ad: 'E-Ticaret Sitesi', teknolojiler: ['Node.js', 'Express', 'MongoDB'], durum: 'tamamlandi', aciklama: 'Tam kapsamli e-ticaret platformu' }},
  {{ id: 2, ad: 'Blog Platformu', teknolojiler: ['Node.js', 'Pug', 'PostgreSQL'], durum: 'devam-ediyor', aciklama: 'Cok yazarli blog sistemi' }},
  {{ id: 3, ad: 'API Gateway', teknolojiler: ['Node.js', 'Express', 'Redis'], durum: 'tamamlandi', aciklama: 'Mikroservis API yonetim katmani' }},
  {{ id: 4, ad: 'Chat Uygulamasi', teknolojiler: ['Node.js', 'Socket.io', 'React'], durum: 'planlama', aciklama: 'Gercek zamanli mesajlasma' }},
];

const ekipUyeleri = [
  {{ ad: 'Ahmet Yilmaz', rol: 'Backend Developer', avatar: 'AY' }},
  {{ ad: 'Zeynep Kaya', rol: 'Frontend Developer', avatar: 'ZK' }},
  {{ ad: 'Mehmet Demir', rol: 'Full Stack Developer', avatar: 'MD' }},
];

// Global template degiskenleri
app.use((req, res, next) => {{
  res.locals.siteAdi = 'DevPortfolio';
  res.locals.menuItems = [
    {{ url: '/', text: 'Ana Sayfa' }},
    {{ url: '/projeler', text: 'Projeler' }},
    {{ url: '/ekip', text: 'Ekip' }},
    {{ url: '/iletisim', text: 'Iletisim' }},
  ];
  res.locals.currentPath = req.path;
  next();
}});

// Route'lar
app.get('/', (req, res) => {{
  res.render('anasayfa', {{
    baslik: 'Ana Sayfa',
    oneCikanProjeler: projeler.filter(p => p.durum === 'tamamlandi'),
  }});
}});

app.get('/projeler', (req, res) => {{
  const durum = req.query.durum;
  let filtrelenmis = projeler;
  if (durum) {{
    filtrelenmis = projeler.filter(p => p.durum === durum);
  }}
  res.render('projeler', {{
    baslik: 'Projeler',
    projeler: filtrelenmis,
    seciliDurum: durum || 'hepsi',
  }});
}});

app.get('/projeler/:id', (req, res) => {{
  const proje = projeler.find(p => p.id === parseInt(req.params.id));
  if (!proje) return res.status(404).render('404');
  res.render('proje-detay', {{ baslik: proje.ad, proje }});
}});

app.get('/ekip', (req, res) => {{
  res.render('ekip', {{ baslik: 'Ekibimiz', ekip: ekipUyeleri }});
}});

app.get('/iletisim', (req, res) => {{
  res.render('iletisim', {{
    baslik: 'Iletisim',
    gonderildi: req.query.ok === '1',
  }});
}});

app.post('/iletisim', (req, res) => {{
  console.log('Form:', req.body);
  res.redirect('/iletisim?ok=1');
}});

app.use((req, res) => {{
  res.status(404).render('404', {{ baslik: 'Sayfa Bulunamadi' }});
}});

app.listen(3000, () => {{
  console.log('Pug sunucusu http://localhost:3000');
}});

// ===== PUG TEMPLATE ORNEKLERI =====
// views/ klasorune .pug uzantisiyla kaydedin

// --- views/layout.pug ---
/*
doctype html
html(lang="tr")
  head
    meta(charset="UTF-8")
    meta(name="viewport" content="width=device-width, initial-scale=1.0")
    title #{{baslik}} | #{{siteAdi}}
    style.
      * {{ margin: 0; padding: 0; box-sizing: border-box; }}
      body {{ font-family: system-ui, sans-serif; background: #f5f5f5; }}
      nav {{ background: #1a1a2e; padding: 16px 32px; display: flex; gap: 24px; }}
      nav a {{ color: #ccc; text-decoration: none; }}
      nav a.active {{ color: #fff; border-bottom: 2px solid #e94560; }}
      .container {{ max-width: 1100px; margin: 32px auto; padding: 0 20px; }}
      footer {{ text-align: center; padding: 32px; color: #999; }}
  body
    nav
      each item in menuItems
        a(href=item.url class=(currentPath === item.url ? 'active' : ''))= item.text
    .container
      block content
    footer
      p © #{new Date().getFullYear()} #{siteAdi}
*/

// --- views/anasayfa.pug ---
/*
extends layout

block content
  h1 Hosgeldiniz
  p Web gelistirme projelerimize goz atin.

  h2 Tamamlanan Projeler
  .grid
    each proje in oneCikanProjeler
      .kart
        h3= proje.ad
        p= proje.aciklama
        .etiketler
          each tek in proje.teknolojiler
            span.etiket= tek
        a(href=`/projeler/${{proje.id}}`) Detay
*/

Pug template engine güçlü ve etkili bir araç. EJS ile aynı işi yapıyor ama farklı bir yaklaşımla. Hangisini seçeceğiniz tamamen size ve ekibinize bağlı. İkisini de deneyin ve hangisinde daha rahat hissediyorsanız onu kullanın. Önemli olan template engine'in sizin önünüze engel çıkarmaması ve verimli çalışmanızı sağlamasıdır.
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst