[Из песочницы] Расширенный HTML
В этой статье хотел бы рассказать немного про библиотеку, первую версию которой я создал еще в конце прошлого года. Суть очень простая — расширить возможности языка HTML, чтобы можно было без JavaScript’а писать простые и рутинные вещи: отправка формы в json формате, загрузка HTML тимплейтов на определенную страницу (по сути модульная система для HTML через http/s запросы), турболинки (привет пользователям RoR), простая шаблонизация на основе ответов ajax запросов и немного еще.
Библиотека называется EHTML или Extended HTML. Основана она на небезызвестной идее веб компонентов. Она доступна на гитхабе, там довольно таки структурированная документация с примерами. В этой статье я просто опишу основные идеи, возможно кому-то это зайдет.
Начнем с того, что для использования либы не нужен ни npm, ни cli тула для создания проекта, все что требуется — это HTML странички, где вы включаете скрипт библиотеки:
Начнем с простого — составление HTML странички из множества других:
Для этого мы используем кастомный элемент e-html
, который имеет единственный атрибут data-src
, где мы указываем где раздается HTML часть страницы. То есть если например first.html
выглядит как-то так:
то в конечном счете, наша страница будет зарендерена следующим образом:
То есть теги e-html
будут заменены контентом из HTML файла, который мы указывали в data-src
атрибуте.
В библиотеке широко применяются элементы с тегом template
. Тут вы можете найти информацию про этот элемент. Одним из примеров использования этого элемента является e-wrapper
, который появился в последней версии либы. По сути это элемент с атрибутом
is="e-wrapper"
и он позволяет заврапить динамический контент каким-нибудь статическим шаблоном. То есть скажем у вас есть статический шаблон следующего вида:
Header content
Default content
Footer content
И скажем у вас есть динамический контент, который вы хотите заврапить им:
Variation of content
Когда вы откроете страничку с кодом выше, он зарендериться следующим образом:
Header content
Variation of content
Footer content
С помощью атрибута data-src
вы указываете HTML файл, от куда вы хотите взять статический шаблон. В атрибуте data-where-to-place
вы указываете селектор элемента в статическом шаблоне куда вы хотите поместить динамический контент, который как раз находится внутри e-wrapper
тимплейта. Ну и с помощью data-how-to-place
вы описываете как именно вы хотите заврапить. Есть три возможные опции: instead
(контент просто заменит элемент с селектором, который указан в data-where-to-place
), before
(контент будет помещен до указанного элемента) и соответсвенно after
(контент будет помещен после элемента). Таким образом, элементы e-html
и e-wrapper
тимплейт позволяют комбинировать html шаблоны для составления страниц. Конечно при рендеринге делаются дополнительные http запросы, чтобы загрузить страницы, однако если использовать кэш запросов — то это проблема полностью нивелируется.
Скажем у вас есть эндпоинт, который отдает информацию о музыкальном альбоме в json формте:
/../album/{title}
title = 'Humbug'
{
"title": "Humbug",
"artist": "Arctic Monkeys",
"type": "studio album",
"releaseDate": "19 August 2009",
"genre": "psychedelic rock, hard rock, stoner rock, desert rock",
"length": "39:20",
"label": "Domino",
"producer": "James Ford, Joshua Homme"
}
Тогда используя тимплейный элемент с атрибутом is="e-json"
, вы можете загрузить и замапить ответ на HTML:
Атрибут data-src
указывает, от куда вы загружаете информацию в json формате, data-object-name
— это имя объекта ответа, который содержит основные компоненты http ответа: body
, headers
и statusCode
. Атрибут data-text
позволяет вам использовать значения объекта в качестве текста, который будет помещен в шаблон внутри e-json
тимплейта.
Также есть возможность использовать циклы и условия при маппинге. Допустим, у нас есть следующий эндпоинт с информацией о музыкальном альбоме со списком песен:
title = 'Humbug'
{
"title": "Humbug",
"artist": "Arctic Monkeys",
"songs": [
{ "title": "My Propeller", "length": "3:27" },
{ "title": "Crying Lightning", "length": "3:43" },
{ "title": "Dangerous Animals", "length": "3:30" },
{ "title": "Secret Door", "length": "3:43" },
{ "title": "Potion Approaching", "length": "3:32" },
{ "title": "Fire and the Thud", "length": "3:57" },
{ "title": "Cornerstone", "length": "3:18" },
{ "title": "Dance Little Liar", "length": "4:43" },
{ "title": "Pretty Visitors", "length": "3:40" },
{ "title": "The Jeweller's Hands", "length": "5:42" }
]
}
Тогда с помощью тимплейта e-for-each
можно показать весь список песен:
В атрибуте data-list-to-iterate
мы указываем список из ответа, который мы хотим итерировать. А в атрибуте data-item-name
мы декларируем имя переменной для каждого айтема, которое мы будем использовать внутри e-for-each
тимплейта.
Также можно например использовать в комбинации тимплейты e-for-each
и e-if
для отображения лишь определенных песен:
В атрибуте data-condition-to-display
тимплейта e-if
мы указываем условие, при котором тот или иной айтем отображается.
Последнее что хочется показать в этой статье — это отправка форм. Очень частно хочется отправлять данные из формы в json формате, поэтому был создан элемент e-form
, который предоставляет такую возможность.
Допустим у нас есть следующий эндпоинт, который позволяет создавать/сохранять новые альбомы:
/artist/{name}/albums/add
name = 'Arctic Monkeys'
POST
Example of expected request body: {
"title": "Humbug",
"type": "studio album",
"releaseDate": "19 August 2009",
"genre": ["psychedelic rock", "hard rock", "stoner rock", "desert rock"],
"length": "39:20",
"label": "Domino",
"producer": "James Ford, Joshua Homme"
}
Тогда форма, которая может посылать такие запросы будет выглядеть примерно так:
Title:
Type:
Release date:
Genre:
Total length:
Producer:
Ключевое отличие от обычной формы в том, что мы декларируем детали эндпоинта в элементе, на который действует пользователь, в данном случае это кнопка. С помощью соответствующих атрибутов мы указываем метод, хедеры, путь для эндопинта. Также можно даже указать ajax иконку, которая будет активирована во время запроса. Также мы должны естественно указать действие, на которое будет отправляться форма — в данном случае это клик. И также мы указываем действие, которое мы можем делаем когда ответ получен. Полный список поддерживаемых таких действий вы можете найти здесь.
Если вы заинтересовались идеей и даже хотите попробовать библиотеку в деле или просто что-то узнать побольше, то в README библиотеки есть исчерпывающая информация о поддерживаемых элементах. Также можете посмотреть видео, где я пишу простое блог приложение исключительно используя EHTML.
Буду рад ответить на вопросы, если такие возникнут. И спасибо за внимание!
Ссылка на репу.