## Szerver oldali JavaScript **6. hét** Templating: EJS, nézetek, a middleware-lánc adatai -- PAGE -- ### Hogyhogy diák? Így lehet a legegyszerűbben általános elmesélni, aztán megnézzük a gyakorlatban is. -- PAGE -- ### Templating Vannak **változók**, van **HTML**, öntsük össze úgy a kettőt, hogy ne törjön össze semmi (html megfelelő maradjon, karakterek jól jelenjenek meg, sortörések, speciális karakterek, stb). Sok motor van, mi most az ejs-t nézzük meg. -- PAGE -- ### Telepítés ```js npm i ejs --save ``` Package: https://www.npmjs.com/package/ejs -- PAGE -- ### Nézzük meg express nélkül! ```js var ejs = require('ejs'); var fs = require('fs'); var html = ejs.render(fs.readFileSync('valami.ejs','utf8'), { nev:'Lorem ipsum', ertek: 2 }); console.log(html); ``` A valami.ejs: ``` <% if (ertek >= 2) { %>
<%= nev %>
<% } %> ``` Az eredmény: ```html
Lorem ipsum
``` -- PAGE -- ### Expressben Betöltés: ```js app.set('view engine', 'ejs'); //se require, se semmi ``` Renderelés: ```js function (req, res, next) { res.render('valami',{ // nem kell .ejs nev:'Lorem ipsum', ertek: 2 }); ``` Ugye hogy egyszerű... -- PAGE -- ### Hol keresi a fájlt?
gyakori hiba
A `res.render('valami')` a **`views/` könyvtárban** keresi a `valami.ejs`-t. Nem ott, ahol az `index.js` van, nem a `public/`-ban. ``` projekt/ ├── index.js ├── views/ <- ide, és csak ide │ ├── torpelista.ejs │ └── torpeedit.ejs └── public/ <- ez a statikus fájloké (css, kép) ``` -- PAGE -- ### Hol keresi a fájlt? Ha `Failed to lookup view "valami"` hibát kapsz, akkor 99%-ban vagy nem a `views/`-ban van, vagy elgépelted, vagy lemaradt az `s` a végéről.
Az `npm i ejs` sem maradhat ki - a package.json-ben szerepelnie kell.
-- PAGE -- ### A nézet a `res.locals`-ból olvas Az előző előadás lánca ide fut ki. A middleware-ek a `res.locals`-ba pakolnak, a `renderMW` **paraméter nélkül** rendereli a nézetet: ```js // middleware/torpe/getTorpekMW.js res.locals.torpek = await TorpeModel.find({}); return next(); ``` ```js // middleware/renderMW.js return res.render(viewName); // nincs második paraméter ``` -- PAGE -- ### A nézet a `res.locals`-ból olvas A nézetben pedig a `res.locals` kulcsai **közvetlenül változóként** látszanak: ```html
Törpék (<%= torpek.length %> db)
``` Nem `locals.torpek`, nem `res.locals.torpek` - egyszerűen `torpek`. -- PAGE -- ### Két út, ugyanoda ```js // 1) mindent egy helyen - kis dolgokra jó res.render('torpelista', { torpek }); // 2) amit a tárgyban használunk - a lánc gyűjti össze res.locals.torpek = torpek; // az egyik middleware-ben res.render('torpelista'); // a renderMW-ben, a lánc végén ``` A kettő **ugyanazt** csinálja. A második azért kell, mert így a betöltés és a renderelés külön middleware, külön fájlban, külön tesztelhetően.
Ha a házi feladatban `res.render(nezet, adat)`-ot látok mindenhol, akkor a lánc valójában nem lánc, hanem egy nagy függvény.
-- PAGE -- ### Használható tagek Control flow ```js <% valami.javascript.code(); %> ez is htm <% if (valami) { %> ez html <% } %> <% for (key in array) { var item = array[key]; %>
<%= item.valami %>
<% } %> ``` **NE** legyen itt a logika, itt **CSAK** ifeket és forokat, foreacheket szeretnék látni... -- PAGE -- ### Használható tagek ```js Escapelt html (<> karakterek, stb) <%= valtozo %> Escape nélküli érték <%- valtozo %> Comment <%# ide barmi johet nem csak kod %> ``` -- PAGE -- ### Strukturálisan Include!!! Ez működik, csak át kell adni az értékeket értelmesen. ```html
<% users.forEach(function(user){ %> <%- include('user/show', {user: user}) %> <% }); %>
``` user/show.ejs -ben a user értelmezett változó, más nem kerül átadásra. Ha minden kell, akkor a második paraméter elhagyásával minden utazik. -- PAGE -- ### Strukturálisan Egy jó ejs layout: ```html <%- include('header') -%>
Title
My page
<%- include('footer') -%> ``` -- PAGE -- ### Minden más [https://github.com/mde/ejs](https://github.com/mde/ejs) De **csak ésszel!**