Skip to content

Latest commit

 

History

History
236 lines (174 loc) · 10.8 KB

16. Шаблонизаторы.md

File metadata and controls

236 lines (174 loc) · 10.8 KB

Шаблонизаторы

Продолжаем облегчать себе ежедневную жизнь через одномоментную боль

В описании урока я написал про одномоментную боль — и это, к сожалению, фраза почти про любой инструмент разработчика: все эти шутки про настройки Вебпака не совсем лживы.

Тем не менее, не нужно расстраиваться! Нужно просто знать об этом и внимательно читать документации, гуглить и спрашивать в тематических чатах.

И помните про ошибки: они нужны, чтобы помочь вам, а не чтобы выбесить из себя. Если возникла ошибка — читайте её, гуглите и спрашивайте в чатах.

Окей, погнали! Сегодня будем прикручивать шаблонизатор.

Шаблоны и компоненты

Шаблон это интерфейс, который можно переиспользовать с разными данными.

Например, карточка ресторана, это один компонент, просто с разными данными: изображением, названием, категориями, средней ценой и временем доставки.

Было бы здорово, если бы у нас был отдельный компонент (или шаблон), который мы могли бы использовать несколько раз. Что-то типа

<template name="card">
  <img src={imgSrc} />
  <h3>{title}</h3>
  <p>{priceCategory} • {category}</p>
  <time>{deliveryTimeFrom} - {deliveryTimeTo} min</time>
</template>

<div class="container">
  <div class="row">
    <div class="col-md-3">
      <card
        imgSrc="https://i.imgur.com/v2lJHlY.png"
        title="Кофемания на Трубной"
        priceCategory="₽"
        category="Европейская"
        deliveryTimeFrom="30"
        deliveryTimeTo="50"
      >
    </div>
  </div>
</div>

Согласитесь, выглядит красиво? Поздравляю, мы написали шаблон (в теге template) и его использовали. Конечно, это не заработает — это псевдокод.

Я бы даже сказал, что это близко к компонентам Реакта (седьмой урок курса по Реакту, но первые шесть нужно сначала пройти) — там тоже используются ХТМЛ-атрибуты для компонентов.

Окей, а как сделать так, чтобы заработало?

Шаблонизаторы

Шаблонизатор — это специальная утилита, которая компилирует шаблоны (например, из своего формата в тот же ХТМЛ). Самый популярный в вёрстке — это Паг (pug).

В базовом понимании шаблонизатор во время компиляции заменяет данные в шаблоне, но некоторые дают ещё дополнительные возможности.

Другой синтаксис

Кому-то кажется. что ХТМЛ не очень удобен, поэтому они вводят свой синтаксис:

doctype html  
html(lang='en')  
 head
   title Pug
 body
   h1 Pug Examples
   div.container
     p Cool Pug example!
     a(href='google.com') Google

Выглядит странновато, но кому-то нравится.

Импорты

Как раз тот пример, с которого начался урок. Нам понадобятся миксины и импорты.

Миксины

mixin article(title)
  .article
    .article-wrapper
      h1= title // через = работаем с аргументами
      if block // если есть ребёнок (он называется блоком) — отобразить
        block
      else // если нет, то отобразить заглушку
        p No content provided

+article('Hello world') // вызываем через +
+article('Hello world')
  p This is my
  p Amazing article
<div class="article">
  <div class="article-wrapper">
    <h1>Hello world</h1>
    <p>No content provided</p>
  </div>
</div>
<div class="article">
  <div class="article-wrapper">
    <h1>Hello world</h1>
    <p>This is my</p>
    <p>Amazing article</p>
  </div>
</div>

Инклюды

Но миксины работают если они находятся в одном файле. Как быть, если хочется держать миксин в отдельном? Например, в Card.pug.

Официальная документация не очень помогает, поэтому пришлось гуглить «pug include with variables» и найти ответ на Стэковерфлоу.

Схема проста: в одном файле мы объявляем миксин, в другом — подключаем через include и используем.

// Card.pug
mixin Card(title, imgSrc, priceCategory, category, deliveryTimeFrom, deliveryTimeTo)
  .card
    img(src=imgSrc)
    h3= title
    p #{priceCategory}#{category} // со значениями можно работать и через #{}
    time #{deliveryTimeFrom} - #{deliveryTimeTo}
// List.pug
include Card.pug

.list
  +Card("Кофемания на Трубной", "https://i.imgur.com/v2lJHlY.png", "₽", "Европейская", 30, 50)

Подобие нормального программирования

Во многих шаблонизаторах (кстати, ещё один популярный — Хэндлбарс) есть поддержка кейсов, циклов и условий. Здесь документация уже справляется.

Компиляция шаблонов в ХТМЛ

Окей, мы написали эти шаблоны, но браузер же не поддерживает .pug или .hjs, нам нужно их перевести в ХТМЛ. Этот процесс называется компиляцией.

На главной странице Пага вторым параграфом идёт описание этого процесса:

The general rendering process of Pug is simple. pug.compile() will compile the Pug source code into a JavaScript function that takes a data object (called “locals”) as an argument. Call that resultant function with your data, and voilà!, it will return a string of HTML rendered with your data.

Нам тут понадобится создать файл compile-templates.js и написать небольшой Джс.

// src/index.pug

doctype html
  html
    head
      title UberEats
      ...
// compile-templates.js
const pug = require("pug");

// скомпилируем
const compiled = pug.compileFile("src/index.pug");

// отрендерим и выведем в консоль
// через метод `console.log()`
console.log(compiled());
// "<!doctype html><html><head><title>UberEats</title>...</head></html>"

Задание

Это задание добровольное — не всем нужны шаблонизаторы

Переведите свою вёрстку на Паг и не забудьте воспользоваться gulp-pug: держать файл compile-pug.js не очень удобно.

Итог

Сегодня мы познакомились с шаблонизаторами — утилитами, которые оптимизируют наш код, приводя его к шаблонам.

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

Заметка про Реакт

Как вы могли заметить, здесь у нас пропаганда Реакта — что уж поделать, он стал стандартом во фронтэнде.

Не в последнюю очередь благодаря своему Джсх — чисто технически, это не совсем шаблонизатор, но можно назвать и так.

Пока у остальных библиотек и фреймворков типа Ангулара или Вью свой птичий язык уровня Пага или Хэндлбарс, у Реакта — Джсх, который очень красиво интегрирует обычный Джаваскрипт с ХТМЛ.

Посмотрите на это:

// src/index.js

// в props — объект со всеми атрибутами
function Card(props) {
  return (
    <a href={props.href}>
      <img src={imgSrc} />
      <h3>{title}</h3>
      <p>{priceCategory}{category}</p>
      <time>{deliveryTimeFrom} - {deliveryTimeTo} min</time>
    </a>
  )
}

function List() {
  return (
    <div class="container">
      <div class="row">
        <div class="col-md-3">
          <Card
            imgSrc="https://i.imgur.com/v2lJHlY.png"
            title="Кофемания на Трубной"
            priceCategory="₽"
            category="Европейская"
            deliveryTimeFrom={15+15}
            deliveryTimeTo={25*2}
          >
        </div>
      </div>
    </div>
  )
}

Весь секрет в том, что в Джсх в {} можно выполнять любой Джаваскрипт-код. Обратите внимание на атрибуты (здесь они называются пропами, props) deliveryTimeFrom и deliveryTimeTo — там обычный Джаваскрипт.

Подробнее, как вы понимаете, в первом этапе курса по Реакту. Велкам!