16Dec

flight-bangkok0816

In real life we generally have more than one template. Moreover, if we create a website with several pages, it usually happens that a number of them are of the same design. The template systems should consider this aspect. Unfortunately, ejs doesn’t deal very well with this task. That’s why we are going to install a different templating system named ejs-locals(let us add it to app.js):

app.engine('ejs', require('ejs-locals'));
app.set('views', __dirname + '/templates');
app.set('view engine', 'ejs');

This is almost the same as ejsbut with a number of essential opportunities, such as layoutblockpartialsLet us look at them now.

Install the module:

npm i ejs-locals

We’ve used the directive app.engine to inform Express that “files with this extension need to be handled by the template engine  require('ejs-locals') instead of standard ejs.”

Once more we draw your attention to the fact that there are many great temlating systems in Node.js. Here we use ejs just because it really resembles HTML and requires minimum time for studying.

Look for the template in template/index.ejs , now it will look like:

<p class="lead">Hey all!</p>

Further let us create  template/layout/page.ejs with this code:

<!DOCTYPE html>
<html>
<head>
    <title><%=blocks.title%></title>

    <link rel="stylesheet" href="/vendor/bower_components/bootstrap/dist/css/bootstrap.css"/>
    <link rel="stylesheet" href="/css/app.css"/>

    <script src="/vendor/bower_components/jquery/jquery.js"></script>
    <script src="/vendor/bower_components/bootstrap/dist/js/bootstrap.js"></script>
</head>
<body>
<header>
    <%-blocks.header%>
</header>
<section class="container">

    <%-partial('../partials/topNavigation')%>

    <h1><%=blocks.title%></h1>

    <%-body -%>
</section>
<footer>
    <%-blocks.footer%>
</footer>
</body>
</html>

Layout is some formatting that we insert into a separate file and specify, where we should insert body<%-body -%>). In any other template we can indicate this. For example, in template/index.ejs we will write:

<% layout('/layout/page') -%>

<p class="lead">Hey all!</p>

So, while handling this template, ejs will upload layout/page, output it, and the body  template/index.ejs will be put into template/layout/page.ejs:

<%-body -%>

So, if we’ve got a lot of pages of the same design, we can just show layout to them. The path is better to be shown this way for the correct work of Windows

We put a slash, but you can ignore it as well:

<% layout('layout/page') %>

It simply means, the first line feed following the directory needs to be ignored. It is sometimes quite handy in order to avoid extra line feeds that turn into spaces in HTML. But in this case, it is not that vital.

Let us take a look at page.ejs once more. Here we use Bootstrap and jQuery libraries. In order to put them properly, let us globally install the module

npm i –g bower

‘Bower’ is an utility that allows you to install various front-end libraries seamlessly. Вootstrap and jQuery  will be installed in the public directory:

cd public

let us create here a special subdirectory vendor:

mkdir vendor

It won’t contain our JavaScript and CSS, but third-party ones:

cd vendor

and then let us install:

bower i jquery bootstrap

The directory appeared, but IDE is still showing the files are not found. It happens because it doesn’t know where to find them. Let us edit the settings.

root

Everything’s ok with the files now.

Let us create app.css in the directory public/css/app.css

The next thing we need to look at here is the system of blocks.

<title><%=blocks.title%></title>

Let us imagine, we want to create something out of our template index.ejs that we will need, in particular, in layoutFor example, a page header. I want to see a header that is not global for layout within page.ejs , in title , i.e. it can be different and is created strictly in the template. How can I do this? For that task, I’ve got blocks:

<% block('title', 'Hello ≥︺‿︺≤'); -%><br>

Further the template will care about the text, which will be added to a certain variable accessible through: blocks.title.

Here (template/layout/page.ejs) we’ve made it in the way for the whole content of this variable %= is to be shielded, which means the symbols get changed for special HTML elements. And if we want to have the same view, we can put %-blocks….

We will also need to create topNavigation.ejs within the directory templates/partialsj, and we will talk about  partials a little bit later:

<nav class="navbar navbar-default" role="navigation">
    <ul class="nav navbar-nav">
        <li><a href="/">Main</a></li>
    </ul>
    <ul class="nav navbar-nav navbar-right">
        <li><a href="/login">Enter</a></li>
    </ul>
</nav>

Ok, let’s see. Launch it. Follow:

http://localhost:3000/

It’s perfect!

So, the blocks are used where we need to insert some content into templates just because it would be unnecessary in JavaScript.

The last component of the templating system we will study is partialsIt is contained in our  page.ejs . It is a sub-template put into a separate file:

<%-partial('../partials/topNavigation')%>

Here you can find various options that may be transferred to this template. If it is interesting for you, you can find them in our supporting materials. There you can find a more detailed description of these features. In our case, you can treat partials as a simple addition, connection of one template to another.

Further we will add various components to the template structure. The only thing we need to change right now is a variable body:

<%-body -%>

Here we use the templating mechanism, so you cannot put it here (app.js):

app.get('/', function(req, res, next) {
  res.render("index", {
  });
});

If you leave it here, it won’t work correctly and our message won’t be outputted (templates/index.ejs):

<p class="lead">Hey all!</p>

To make everything work well, just move it from there. So, that’s it. Next time we will talk about MongoDB.

The lesson code can be found here.
sunset-palms-wallpaper-1

The materials of this article were borrowed from the following screencast.

We are looking forward to meeting you on our website soshace.com

2 Replies to “3. Express.js Lessons. Templating with EJS: Layout, Block, Partials”

  1. Michael LaFirenza 8 years ago

    Great summary – best I’ve found on ejs-locals. Thank you!

  2. NOTE: It says in the github repo that “[ejs-locals] is unmaintained, sorry. I recommend a fully-featured and actively-maintained alternative such as …”[*]. That statement was actually made 4 years ago, mind you…

    [*] https://github.com/RandomEtc/ejs-locals

Leave a Reply

16Dec

flight-bangkok0816

В реальной жизни у нас обычно больше, чем один шаблон. Более того, если уж так получилось, что мы делаем сайт со страницами, то, как правило, бывает так, что у нас множество страниц есть в одинаковом оформлении. Шаблонная система должна это предусматривать. К сожалению, ejs не очень хорошо с этим справляется. Поэтому, мы сейчас поставим немного другую систему для шаблонизации , которая называется ejs-locals(добавим в app.js):

app.engine('ejs', require('ejs-locals'));
app.set('views', __dirname + '/templates');
app.set('view engine', 'ejs');

Это почти то же самое, что и ejs, но в ней есть важные возможности, а именно, layout, block, partials. Мы сейчас их посмотрим.

Устанавливаем модуль:

npm i ejs-locals

Мы использовал директиву app.engine, чтобы сказать Express – “файлы с таким расширением нужно обрабатывать таким шаблонным движком  require('ejs-locals') , а не стандартным  ejs“.

Еще раз обращаем ваше внимание, есть множество отличных систем для шаблонизации  в Node.js. Мы здесь ejs используем просто потому, что она очень похожа на HTML и требует минимального времени на изучение.

Смотрим шаблон в template/index.ejs , теперь он будет выглядеть так:

<p class="lead">Hey all!</p>

Далее создадим  template/layout/page.ejs c таким кодом:

<!DOCTYPE html>
<html>
<head>
    <title><%=blocks.title%></title>

    <link rel="stylesheet" href="/vendor/bower_components/bootstrap/dist/css/bootstrap.css"/>
    <link rel="stylesheet" href="/css/app.css"/>

    <script src="/vendor/bower_components/jquery/jquery.js"></script>
    <script src="/vendor/bower_components/bootstrap/dist/js/bootstrap.js"></script>
</head>
<body>
<header>
    <%-blocks.header%>
</header>
<section class="container">

    <%-partial('../partials/topNavigation')%>

    <h1><%=blocks.title%></h1>

    <%-body -%>
</section>
<footer>
    <%-blocks.footer%>
</footer>
</body>
</html>

Layout это некоторое оформление, которое мы пишем в отдельный файл и указываем, куда вставлять body ( <%-body -%>). В любом другом шаблоне мы  можем указать, например в template/index.ejs напишем:

<% layout('/layout/page') -%>

<p class="lead">Hey all!</p>

Тогда при обработке этого шаблона ejs загрузит layout/page, выведет ее, а тело template/index.ejs поместит template/layout/page.ejs:

<%-body -%>

Таким образом, если у нас есть много страниц  с одинаковым оформлением, то мы можем просто им указать layout. Путь лучше указать таким образом, для корректной работы в Windows

Мы поставили черточку, но можно и без нее:

<% layout('layout/page') %>

Она всего лишь означает, что первый перевод строки после директивы нужно проигнорировать. Это иногда бывает удобно, чтобы избежать лишних переводов строки, которые становятся пробелами в получившимся HTML. Но в данном случае это здесь не очень важно.

Посмотрим еще раз на page.ejs. Здесь мы используем библиотеки Bootstrap и jQuery. Для того чтобы их удобно поставить, установим глобально модуль

npm i –g bower

Bower – это утилита, которая позволяет удобно устанавливать всякие библиотеки для front-end. Вootstrap и jQuery  будем ставить в директорию public:

cd public

создам здесь специальную поддиректорию vendor:

mkdir vendor

В ней будет не наш JavaScript и CSS, а сторонний:

cd vendor

а затем установим:

bower i jquery bootstrap

Появилась директория, но все равно IDE подсвечивает, что файлы не найдены. Это потому, что он не знает, где их искать. Редактируем настройки.

root

Теперь с файлами все нормально.

Создадим app.css в директории public/css/app.css

Следующее, что здесь необходимо посмотреть – это система блоков:

<title><%=blocks.title%></title>

Допустим, мы хотим создать из нашего шаблона index.ejs нечто, что понадобится нам, в частности, в layout. Например, заголовок страницы. Я хочу, чтобы в page.ejs в title выводился заголовок, который не является каким-то глобальным для layout, то есть, он может быть разным, и задается конкретно в шаблоне. Как это сделать? Для этого существуют блоки:

<% block('title', 'Hello ≥︺‿︺≤'); -%><br>

Дальше шаблон уже позаботится о том, чтобы этот текст прибавился к специальной переменной, доступ которой организуется вот так: blocks.title.

Здесь (template/layout/page.ejs) мы  позаботились  о том, чтобы все содержимое этой переменной %= экранировалось, то есть, символы будут заменятся на специальные  HTML сущности. А если мы  хотим, чтобы сохранялось, как есть, то  можно поставить %-blocks….

Также нам понадобиться создать topNavigation.ejs в дирректории templates/partialsjо  partials поговорим немного позже:

<nav class="navbar navbar-default" role="navigation">
    <ul class="nav navbar-nav">
        <li><a href="/">Main</a></li>
    </ul>
    <ul class="nav navbar-nav navbar-right">
        <li><a href="/login">Enter</a></li>
    </ul>
</nav>

Что ж, посмотрим. Запускаем. Переходим на:

http://localhost:3000/

Все отлично!

Итак, блоки используются там, где нужно задавать какое-то содержимое в шаблонах, просто потому, что в JavaScript оно было бы явно лишним.

Последний компонент системы шаблонизации, который мы рассмотрим, это partials. Он содержиться в нашей page.ejs . Это подшаблон, который находится в отдельном файле:

<%-partial('../partials/topNavigation')%>

Здесь есть различные опции, которые можно передать в этот шаблон. Если интересно, то посмотрите в документации. Там есть более подробное описание этих различных фишек. В данном случае partials можно рассматривать просто как дополнение, простое подключение одного шаблона к другому.

Далее мы будем добавлять различные компоненты в структуру template. Единственное, что сейчас еще нужно поменять, это переменную body:

<%-body -%>

Здесь мы используем механизм шаблонизации, поэтому вот сюда ее ставить нельзя (app.js):

app.get('/', function(req, res, next) {
  res.render("index", {
  });
});

Если я ее здесь оставить, то корректно работать не будет и наше сообщение не выведется (templates/index.ejs):

<p class="lead">Hey all!</p>

Чтобы корректно все работало, надо просто ее оттуда убрать. На этом все, совсем скоро поговорим о MongoDB.

Код урока можно скачать здесь.
sunset-palms-wallpaper-1

Материалы для статьи взяты из следующего скринкаста.

We are looking forward to meeting you on our website soshace.com

20. Уроки Node.js. Потоки данных в Node.JS, fs.ReadStream

Всем привет! Тема этого занятия: Потоки данных в Node.js. Мы постараемся разобраться в этой теме более подробно, поскольку, с одной стороны, так получается, что потоки в обычной браузерной JavaScript разработке отсутствуют, а с другой стороны, уверенное владение потоками необходимо для грамотной серверной разработки, поскольку поток является универсальным способом работы с источниками данных, которые используются повсеместно.

Leave a Reply