\section{Templating}

\begin{frame}{Miért használjunk email template-eket? (1/2)}
  \begin{block}{Problémák template nélkül}
    \begin{itemize}
      \item HTML string-ek a kódban $\rightarrow$ nehéz karbantartani
      \item Duplikált kód különböző email típusokhoz
      \item Nehéz változtatni a design-t
      \item Frontend és backend keveredik
      \item Nincs újrafelhasználhatóság
    \end{itemize}
  \end{block}
\end{frame}

\begin{frame}{Miért használjunk email template-eket? (2/2)}  
  \begin{exampleblock}{Template-ekkel}
    \begin{itemize}
      \item Szeparált template fájlok
      \item Dinamikus adatok injektálása
      \item Újrafelhasználható komponensek (header, footer)
      \item Könnyű módosítás és tesztelés
      \item Designer-ek is módosíthatják
      \item Verziókövetés
    \end{itemize}
  \end{exampleblock}
\end{frame}

\begin{frame}{Template Engine-ek}
  \begin{block}{Népszerű template engine-ek Node.js-hez}
    \begin{description}
      \item[Handlebars] Logika-mentes, egyszerű szintaxis, blokk helper-ek
      \item[EJS] Embedded JavaScript, ismerős szintaxis
      \item[Pug (Jade)] Tömör, whitespace-based szintaxis
      \item[Nunjucks] Jinja2-szerű, gazdag funkciók
      \item[Mustache] Minimális, logika-mentes
    \end{description}
  \end{block}
  
  \begin{block}{Email-specifikus eszközök}
    \begin{description}
      \item[MJML] Responsive email framework - JSON/XML-szerű szintaxis
      \item[Foundation for Emails] Responsive email framework
      \item[Email-templates] Nodemailer integráció többféle engine-hez
    \end{description}
  \end{block}
\end{frame}

\begin{frame}[fragile]{Handlebars alapok}
  \begin{block}{Telepítés}
\small
\begin{lstlisting}[language=bash]
npm install handlebars
\end{lstlisting}
  \end{block}
  
  \begin{exampleblock}{Template szintaxis (1/2)}
\small
\begin{lstlisting}[language=HTML]
<!DOCTYPE html>
<html>
<head>
  <title>{{subject}}</title>
</head>
<body>
  <h1>Hello {{username}}!</h1>
  <p>Your email is: {{email}}</p>
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Handlebars alapok (2/3)}
  \begin{exampleblock}{Template szintaxis - Conditionals}
\small
\begin{lstlisting}[language=HTML]
  {{#if isPremium}}
    <p>Thanks for being a premium member!</p>
  {{else}}
    <p>Upgrade to premium for more features.</p>
  {{/if}}
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Handlebars alapok (3/3)}
  \begin{exampleblock}{Template szintaxis - Loops}
\small
\begin{lstlisting}[language=HTML]
  <ul>
  {{#each items}}
    <li>{{this.name}} - ${{this.price}}</li>
  {{/each}}
  </ul>
</body>
</html>
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Handlebars használata Node.js-ben (1/3)}
  \begin{exampleblock}{Setup és template beolvasás}
\small
\begin{lstlisting}[language=JavaScript]
const handlebars = require('handlebars');
const fs = require('fs').promises;

async function renderTemplate(templateName, data) {
  // Template fájl beolvasása
  const templatePath = `./templates/${templateName}.hbs`;
  const templateSource = await fs.readFile(templatePath, 'utf-8');
  
  // Template compile
  const template = handlebars.compile(templateSource);
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Handlebars használata Node.js-ben (2/3)}
  \begin{exampleblock}{Render adatokkal}
\small
\begin{lstlisting}[language=JavaScript]
async function renderTemplate(templateName, data) {
  // ... template beolvasás és compile
  
  // Render adatokkal
  const html = template(data);
  
  return html;
}
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Handlebars használata Node.js-ben (3/4)}
  \begin{exampleblock}{Használat példa - Data}
\small
\begin{lstlisting}[language=JavaScript]
const data = {
  username: 'John Doe',
  email: 'john@example.com',
  isPremium: true,
  items: [
    { name: 'Product 1', price: 29.99 },
    { name: 'Product 2', price: 49.99 }
  ]
};
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Handlebars használata Node.js-ben (4/4)}
  \begin{exampleblock}{Használat példa - Render}
\small
\begin{lstlisting}[language=JavaScript]
const html = await renderTemplate('welcome', data);
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Handlebars custom helper-ek (1/3)}
  \begin{exampleblock}{Dátum helper}
\small
\begin{lstlisting}[language=JavaScript]
const handlebars = require('handlebars');
// Egyszerű helper - dátum formázás
handlebars.registerHelper('formatDate', (date) => {
  return new Date(date).toLocaleDateString('hu-HU');});
\end{lstlisting}
  \end{exampleblock}
  \begin{exampleblock}{Currency helper}
\small
\begin{lstlisting}[language=JavaScript]
// Helper paraméterekkel
handlebars.registerHelper('formatCurrency', 
  (amount, currency = 'USD') => {
  return new Intl.NumberFormat('en-US', {
    style: 'currency', currency: currency}).format(amount);});
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Handlebars custom helper-ek (2/3)}
   \begin{exampleblock}{Block helper - feltételes logika}
        \small
        \begin{lstlisting}[language=JavaScript]
        // Block helper - feltételes logika
        handlebars.registerHelper('ifEquals', 
        function(arg1, arg2, options) {
        return (arg1 === arg2) 
            ? options.fn(this) 
            : options.inverse(this);
        });
        \end{lstlisting}
        \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Handlebars custom helper-ek (3/3)}  
  \begin{exampleblock}{Template használat}
\small
\begin{lstlisting}[language=HTML]
<p>Order date: {{formatDate orderDate}}</p>
<p>Total: {{formatCurrency total 'EUR'}}</p>

{{#ifEquals status 'completed'}}
  <p>Order is completed!</p>
{{else}}
  <p>Order is pending.</p>
{{/ifEquals}}
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Handlebars partials - újrafelhasználható részek (1/3)}
  \begin{exampleblock}{Setup}
\small
\begin{lstlisting}[language=JavaScript]
const handlebars = require('handlebars');
const fs = require('fs').promises;

// Partial-ok betöltése
async function registerPartials() {
  const header = await fs.readFile(
    './templates/partials/header.hbs', 'utf-8');
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Handlebars partials - újrafelhasználható részek (2/3)}
  \begin{exampleblock}{Partial fájlok beolvasása}
\small
\begin{lstlisting}[language=JavaScript]
  const footer = await fs.readFile(
    './templates/partials/footer.hbs', 'utf-8');
  const button = await fs.readFile(
    './templates/partials/button.hbs', 'utf-8');
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Handlebars partials - újrafelhasználható részek (3/3)}
  \begin{exampleblock}{Partial regisztráció}
\small
\begin{lstlisting}[language=JavaScript]
  // Partials regisztrálása
  handlebars.registerPartial('header', header);
  handlebars.registerPartial('footer', footer);
  handlebars.registerPartial('button', button);
}

await registerPartials();
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Partial példák (1/2)}
  \begin{columns}[T]
    \begin{column}{0.48\textwidth}
      \textbf{header.hbs}
\begin{lstlisting}[language=HTML]
<div style="background: #333; 
            color: white; 
            padding: 20px;">
  <img src="{{logoUrl}}" 
       alt="Logo"/>
  <h1>{{companyName}}</h1>
</div>
\end{lstlisting}
    \end{column}
    \begin{column}{0.48\textwidth}
      \textbf{footer.hbs}
\begin{lstlisting}[language=HTML]
<div style="text-align: center;">
  <p>© {{year}}</p>
</div>
\end{lstlisting}
    \end{column}
  \end{columns}
\end{frame}

\begin{frame}[fragile]{Partial példák (2/2)}
  \begin{exampleblock}{main.hbs - Partials használata}
\small
\begin{lstlisting}[language=HTML]
<!DOCTYPE html>
<html>
<body>
  {{> header}}
  <div class="content">
    {{body}}
  </div>
  {{> footer}}
</body>
</html>
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email-templates csomag - All-in-one megoldás}
  \begin{block}{Telep\u00edt\u00e9s}
\small
\begin{lstlisting}[language=bash]
npm install email-templates
\end{lstlisting}
  \end{block}
  
  \begin{block}{Jellemz\u0151k}
    \begin{itemize}
      \item Automatikus HTML \u00e9s text verzi\u00f3 gener\u00e1l\u00e1s
      \item CSS inlining (email client compatibility)
      \item Template engine v\u00e1laszt\u00e9k (Pug, Handlebars, EJS, etc.)
      \item Preview server fejleszt\u00e9shez
      \item Nodemailer integr\u00e1ci\u00f3
    \end{itemize}
  \end{block}
\end{frame}

\begin{frame}[fragile]{Email-templates haszn\u00e1lata (1/3)}
  \begin{exampleblock}{Transporter setup}
\small
\begin{lstlisting}[language=JavaScript]
const Email = require('email-templates');
const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransport({
  host: process.env.SMTP_HOST,
  port: process.env.SMTP_PORT,
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS
  }
});\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email-templates haszn\u00e1lata (2/3)}
  \begin{exampleblock}{Email konfigur\u00e1ci\u00f3}
\small
\begin{lstlisting}[language=JavaScript]
const email = new Email({
  message: { from: 'noreply@example.com' },
  transport: transporter,
  views: {
    root: './emails',  // Template könyvtár
    options: {
      extension: 'hbs'  // Handlebars
    }
  },
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email-templates haszn\u00e1lata (3/3)}
  \begin{exampleblock}{CSS inlining config}
\small
\begin{lstlisting}[language=JavaScript]
  // ... folytat\u00e1s
  juice: true,  // CSS inlining
  juiceResources: {
    preserveImportant: true,
    webResources: {
      relativeTo: './emails'
    }
  }
});
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email-templates - Email küldés (1/2)}
  \begin{exampleblock}{Welcome email példa}
\small
\begin{lstlisting}[language=JavaScript]
// Email küldés template-tel
await email.send({
  template: 'welcome',  // ./emails/welcome könyvtár
  message: { to: 'user@example.com' },
  locals: {
    username: 'John Doe',
    verifyUrl: 'https://example.com/verify?token=abc123',
    year: new Date().getFullYear()
  }
});
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Email-templates - Email küldés (2/2)}
  \begin{exampleblock}{Order confirmation példa}
\small
\begin{lstlisting}[language=JavaScript]
// Több template eset
await email.send({
  template: 'order-confirmation',
  message: { to: order.customerEmail },
  locals: {
    orderNumber: order.id, items: order.items,
    total: order.total, shippingAddress: order.address
  }
});
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Template könyvtár struktúra (1/2)}
  \begin{exampleblock}{Fájl struktúra - Layouts és Partials}
\small
\begin{lstlisting}[language=bash]
emails/
  ├── _layouts/
  │   └── default.hbs          # Alap layout
  ├── _partials/
  │   ├── header.hbs
  │   ├── footer.hbs
  │   └── button.hbs
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Template könyvtár struktúra (2/3)}
  \begin{exampleblock}{Fájl struktúra - Welcome template}
\small
\begin{lstlisting}[language=bash]
  ├── welcome/
  │   ├── html.hbs    # HTML verzió
  │   ├── text.hbs    # Plain text
  │   ├── subject.hbs # Subject
  │   └── style.css   # CSS (inline-olva lesz)
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Template könyvtár struktúra (3/3)}
  \begin{exampleblock}{Fájl struktúra - További templates}
\small
\begin{lstlisting}[language=bash]
  ├── password-reset/
  │   ├── html.hbs
  │   ├── text.hbs
  │   └── subject.hbs
  └── order-confirmation/
      ├── html.hbs
      ├── text.hbs
      └── subject.hbs
\end{lstlisting}
  \end{exampleblock}
  
  \begin{alertblock}{Fontos}
    Minden template-hez készíts \texttt{text.hbs} verziót is (accessibility)!
  \end{alertblock}
\end{frame}

\begin{frame}[fragile]{Welcome template példa - HTML (1/3)}
  \begin{exampleblock}{emails/welcome/html.hbs - Head}
\small
\begin{lstlisting}[language=HTML]
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  {{> header companyName="MyApp" logoUrl="/logo.png"}}
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Welcome template példa - HTML (2/3)}
  \begin{exampleblock}{emails/welcome/html.hbs - Content}
\small
\begin{lstlisting}[language=HTML]
  <div class="container">
    <h1>Welcome, {{username}}!</h1>
    <p>Thank you for joining MyApp. 
       We're excited to have you on board!</p>
    
    <p>To get started, please verify your email address 
       by clicking the button below:</p>
    
    {{> button text="Verify Email" url=verifyUrl color="#4CAF50"}}
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Welcome template példa - HTML (3/3)}
  \begin{exampleblock}{emails/welcome/html.hbs - Footer}
\small
\begin{lstlisting}[language=HTML]
    <p>If you didn't create an account, 
       please ignore this email.</p>
  </div>
  
  {{> footer year=year}}
</body>
</html>
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Welcome template példa - Text (1/2)}
  \begin{exampleblock}{emails/welcome/text.hbs - Content}
\small
\begin{lstlisting}[language=plaintext]
Welcome, {{username}}!
Thank you for joining MyApp. 
We're excited to have you on board!

To get started, please verify your email address 
by visiting:
{{verifyUrl}}

If you didn't create an account, 
please ignore this email.
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Welcome template példa - Text (2/2)}
  \begin{exampleblock}{emails/welcome/text.hbs - Signature}
\small
\begin{lstlisting}[language=plaintext]
Best regards,
The MyApp Team

© {{year}} MyApp. All rights reserved.
\end{lstlisting}
  \end{exampleblock}
  
  \begin{exampleblock}{emails/welcome/subject.hbs}
\small
\begin{lstlisting}[language=plaintext]
Welcome to MyApp, {{username}}!
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}{Template subject - Megjegyzés}
  \begin{alertblock}{Megjegyzés}
    A \texttt{subject.hbs} is lehet dinamikus template!
  \end{alertblock}
\end{frame}

\begin{frame}[fragile]{Reusable button partial (1/2)}
  \begin{exampleblock}{emails/\_partials/button.hbs - Table structure}
\small
\begin{lstlisting}[language=HTML]
<table role="presentation" cellspacing="0" cellpadding="0" 
       border="0" align="center" style="margin: 20px 0;">
  <tr>
    <td style="border-radius: 4px; background: {{color}};">
      <a href="{{url}}" 
         style="border: none; 
                color: white; 
                padding: 12px 24px; 
                text-decoration: none; 
                display: inline-block; 
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]{Reusable button partial (2/2)}
  \begin{exampleblock}{emails/\_partials/button.hbs - Link styling}
\small
\begin{lstlisting}[language=HTML]
         style="...
                font-size: 16px; 
                font-weight: bold;">
        {{text}}
      </a>
    </td>
  </tr>
</table>
\end{lstlisting}
  \end{exampleblock}
  \begin{alertblock}{Miért table layout?}
    Email client-ek (Outlook, Gmail) rosszul támogatják a modern CSS-t. 
    Table-based layout a legkompatibilisebb megoldás.
  \end{alertblock}
\end{frame}

\begin{frame}[fragile]{CSS inlining}
  \begin{block}{Miért kell CSS inlining?}
    \begin{itemize}
      \item Gmail és sok email client eltávolítja a \texttt{<style>} tag-et
      \item Biztonságos megoldás: inline style attribute-ok
      \item Automatikus: \texttt{juice} library végzi
    \end{itemize}
  \end{block}
  
  \begin{columns}[T]
    \begin{column}{0.48\textwidth}
      \textbf{Előtte (style.css)}
\begin{lstlisting}[language=CSS]
.button {
  background: #4CAF50;
  color: white;
  padding: 12px 24px;
}
\end{lstlisting}
    \end{column}
    \begin{column}{0.48\textwidth}
      \textbf{Utána (inline)}
\begin{lstlisting}[language=HTML]
<a style="background: #4CAF50; 
          color: white; 
          padding: 12px 24px;">
  Button
</a>
\end{lstlisting}
    \end{column}
  \end{columns}
\end{frame}

\begin{frame}[fragile]{CSS inlining - Fontos beállítások}
  \begin{exampleblock}{Email-templates automatikusan végzi}
\small
\begin{lstlisting}[language=JavaScript]
const email = new Email({
  // ...
  juice: true,  // CSS inlining engedélyezése
  juiceResources: {
    preserveImportant: true
  }
});
\end{lstlisting}
  \end{exampleblock}
\end{frame}

\begin{frame}{Összefoglalás (1/2)}
  \begin{block}{Email templating lényege}
    \begin{itemize}
      \item Szeparált, karbantartható email template-ek
      \item Dinamikus adatok injektálása
      \item Újrafelhasználható komponensek (partials)
      \item HTML és plain text verziók
    \end{itemize}
  \end{block}
  
  \begin{block}{Eszközök}
    \begin{itemize}
      \item Template engine-ek: Handlebars, EJS, Pug
      \item Email-specific: MJML, Foundation for Emails
      \item Node.js library: email-templates csomag
      \item CSS inlining: juice library
    \end{itemize}
  \end{block}
\end{frame}

\begin{frame}{Összefoglalás (2/2)}
  \begin{block}{Kulcsfontosságú szempontok}
    \begin{itemize}
      \item Email client kompatibilitás (table layout, inline CSS)
      \item Responsive design mobil eszközökre
      \item Tesztelés és preview development-ben
      \item Clean architecture: EmailService osztály
    \end{itemize}
  \end{block}
\end{frame}

