Всякий раз, когда мы говорим о создании веб-приложения, нам нужно говорить о языковых препроцессорах (преобразование исходного кода, написанного на определенном языке, в целевой код на родном языке). Часто вы обнаружите, что используете языки, которые изначально не поддерживаются веб-браузерами, потому что они помогают вам свернуть повторяющуюся работу, предоставляя функции, недоступные в простом HTML (например, Jade), CSS (например, Sass) и JavaScript (например, CoffeeScript).
Механизм шаблонов HTML — это препроцессор, который дает нам возможность создавать динамические и повторно используемые документы HTML, которые следуют ( DRY ) принципу разработки приложений.
Jade — это язык шаблонов HTML с открытым исходным кодом для Node.js (серверный JavaScript). Jade полностью бесплатен в использовании и предоставляет быстрый, простой и интересный HTML. На него сильно повлиял Haml , и он изначально был создан в Node как модуль. Обычно он включает функции, общие для большинства языков программирования высокого уровня, с упором на обработку простого текста.
При использовании современных CSS-фреймворков, таких как Bootstrap и Foundation, большая часть разработки полностью сводится к созданию HTML, который раскрывает всю мощь Jade. Как только вы начнете использовать его, он станет для вас незаменимым инструментом.
В этом уроке я собираюсь рассказать о том, как ускорить производство HTML и внедрить простые данные с помощью функций Jade в сочетании с Grunt .
Наш набор инструментов для этого урока будет включать:
- нефрит
- хрюкать
- NodeJS
Подготовка среды: установка
Вот шаги для установки Node.js, Jade и интерфейса командной строки Grunt (CLI). Если они у вас уже установлены, вы можете перейти к следующему разделу руководства.
-
Перейдите на nodejs.org и нажмите кнопку «Установить», чтобы загрузить последнюю версию узла. Запустите загруженный файл и следуйте инструкциям по установке.
-
npm (Node Package Manager) будет поставляться в комплекте с Node и может использоваться через терминал. Откройте свой терминал и выполните
npm init
в каталоге проекта. Затем следуйте инструкциям для созданияpackage.json
. - Чтобы установить Grunt, введите
npm install --save-dev grunt
- Установите Grunt CLI (интерфейс командной строки).
npm install -g grunt-cli
для выполнения задач прямо из командной строки. - Чтобы установить плагин Grunt для задач Jade, введите
npm install --save-dev grunt-contrib-jade
- Чтобы установить Jade, введите
npm install --save-dev jade
ПРИМЕЧАНИЕ: есть три флага для установки пакетов npm:
-
--save
означает, что эти пакеты требуются локально для проекта и перечислены в свойстве зависимостей. -
--save-dev
добавляет пакеты локально, но в качестве зависимостей разработки. Они перечислены под devDependencies вpackage.json
. -
-g
указывает, что пакет должен быть установлен глобально; это позволяет вам выполнять grunt в вашем терминале независимо от текущего рабочего каталога.
Будет создан файл манифеста package.json
, в котором указан список пакетов, от которых зависит проект, и он включает некоторые метаданные, такие как имя проекта, версия и описание.
После установки ваш манифест package.json
будет выглядеть следующим образом:
{ "name": "jadeTutorial", "version": "1.0.0", "description": "Jade with Grunt tutorial", "main": "index.js", "author": , "license": "ISC", "devDependencies": { "grunt": "^0.4.5", "grunt-contrib-jade": "^0.14.1", "jade": "^1.9.2", } }
Кроме того, будет создан каталог node_modules
который будет включать в себя модули npm, установленные ранее как grunt
и jade
.
Что такое Грант?
Я познакомлю вас с Grunt, популярным исполнителем задач, мы будем использовать его для автоматизации и выполнения трудоемких задач командной строки в вашем рабочем процессе разработки. Задача — это действие, которое создает цель, например компиляцию Jade для генерации HTML. Используя Grunt, мы сможем запускать Jade, наблюдать за задачами и выполнять любые другие задачи только с одной командной строкой. Это нормально, если вы никогда не слышали о бегущем задании раньше; это не сложная концепция, чтобы обернуть голову вокруг.
Grunt — не самый лучший инструмент для этой работы. Если вам интересно использовать другие инструменты сборки, вы можете проверить следующие ресурсы: Как использовать npm в качестве инструмента сборки или Введение в Gulp.js.
Создание Gruntfile.js
Grunt использует gruntfile.js
для загрузки любой задачи и настройки ее с любыми необходимыми параметрами, как я покажу вам в дальнейшем.
Задачи Grunt настраиваются путем передачи объекта в метод grunt.initConfig
, определения затронутых файлов в задаче и передачи нескольких других параметров. Узнайте больше о Grunt .
Метод grunt.registerTask
определяет задачу, которая будет выполняться при запуске grunt build
через командную строку. Массив [jade, watch]
указывает задачи, которые будут выполняться соответственно для выполнения процесса сборки.
Начнем с того, что это минимальный код Gruntfile.js
:
module.exports = function (grunt) { grunt.initConfig({}); grunt.registerTask('default', []); };
Настройка Grunt Jade Task
Мы создадим наш основной Gruntfile и поместим в него следующий код:
module.exports = function(grunt) { // Project configuration. grunt.initConfig({ jade: { compile: { options: { pretty: true, }, files: { 'build/index.html': 'app/views/jobs.jade' } } } }); // These plugins provide necessary tasks. grunt.loadNpmTasks('grunt-contrib-jade'); // Default task. grunt.registerTask('build', 'Convert Jade templates into html templates', ['jade']); };
Для настройки задачи grunt необходимо извлечь плагин из реестра npm
и загрузить пакет плагинов, который содержит задачу через метод grunt.loadNpmTasks
, так что вы можете настроить и выполнить их.
Предыдущая конфигурация задачи скомпилирует каждый файл Jade индивидуально и поместит результаты в каталог сборки в один файл index.html
.
Настройка задачи Grunt Watch
Задача Watch — один из самых полезных плагинов. Это будет следить за вашими изменениями, перестраивать и сразу же начинать автоматически без необходимости запуска задачи jade
каждый раз, когда мы вносим изменения.
Чтобы добавить задачу наблюдения , установите плагин с помощью этой команды:
npm install --save-dev grunt-contrib-watch
Затем добавьте его конфигурацию в Gruntfile.js
:
watch: { grunt: { files: ['Gruntfile.js'] }, jade: { files: 'app/views/**/*.jade', tasks: ['jade'] } }
Это создаст задачу «watch» для файлов Jade и файла Grunt. Для этого вам также нужно загрузить задачу Grunt и зарегистрировать задачу:
grunt.registerTask('default','Convert Jade templates into html templates', ['jade','watch']); grunt.loadNpmTasks('grunt-contrib-watch');
Теперь, когда вы запустите команду grunt
она выполнит следующие задачи:
- Компиляция Jade
- Запустите задачу
watch
чтобы просмотреть изменения в файлах Jade и автоматически перекомпилировать их после их изменения.
Процесс будет активен, пока не будет убит CTRL + C
ПРИМЕЧАНИЕ. Команда grunt
является ярлыком / псевдонимом для grunt default
. Он определяет, какие задачи нужно выполнить — в нашем случае jade
и watch
— когда мы запускаем команду grunt
.
Генератор скаффолдов gruntfile.js
Вы можете использовать grunt-init-gruntfile
скаффолдинга grunt-init-gruntfile
для создания базового Gruntfile. Нам не понадобятся все задачи по умолчанию в этом руководстве, поэтому мы не будем его использовать.
Структура проекта
Мы создадим нашу исходную иерархию папок следующим образом:
app └──views | └── layout.jade | └── jobs.jade | └── jobs-container.jade └──── partials | └─ head.jade └─ footer.jade
Выполните команду grunt jade
и для вас будет создана следующая структура.
build └── index.html
Простой нефритовый пример
Jade основан на отступах и пробелах , так как каждый уровень отступов создает уровень вложенности элементов в HTML. Для иллюстрации следующий код показывает, как может выглядеть базовая структура с использованием Jade для создания HTML-документа.
doctype html html head title Jade Tutorial body p.className#idName Hello SitePoint | Readers! img(src="images/image.png")
Который компилируется в:
<!DOCTYPE html> <html> <head> <title> Jade Tutorial </title> </head> <body> <p class="className" id="idName"> Hello SitePoint Readers! </p> <img src="images/image.png"> </body> </html>
Используя Jade, вам не нужно писать закрывающие теги, что помогает избежать потенциальных ошибок, таких как забыть добавить закрывающие теги или потерять их правильный порядок. Любой текст в начале строки интерпретируется как тег. Вы должны использовать правильные отступы для каждого тега.
Примечание: если имя тега опущено, div
будет создан как тег по умолчанию.
Чтобы добавить атрибуты в тег, поместите их в круглые скобки после имени тега и следуйте формату name=value
. Для разделения нескольких атрибутов используйте запятую. Кроме того, классы и идентификаторы могут быть написаны с .
и #
символы соответственно, как в предыдущем примере.
Использование символа трубы ( |
)
Иногда нам нужно записать необработанное содержимое тега в новую строку, но, как я упоминал ранее, любой текст в начале строки считается тегом . Чтобы избежать этого, используйте трубу или |
символ в начале строки и напишите внутренний текст для тега в новой строке.
Примечание: чтобы увидеть изменения, которые вы внесли в файл Jade, скомпилировав его, вам нужно запустить grunt
на основе задачи Grunt, которую мы создали ранее.
Мощные нефритовые функции с Grunt
В предыдущем разделе я дал вам краткий обзор синтаксиса Jade. В следующих разделах мы рассмотрим некоторые другие общие и мощные функции Jade, а также несколько более продвинутых. Мы сделаем это, пройдя простой пример «страницы вакансий». Вы можете найти полные примеры для каждого случая в файлах исходного кода или в репозитории GitHub . Давайте начнем!
Блокировать и расширять (Jade Inheritance)
Файл с именем layout.jade
будет базовой структурой для макета нашей страницы, и это своего рода СУХОЕ понятие, поскольку вам не нужно писать эти теги для каждой страницы. Вместо этого вам нужно extend
макет и начать писать код, специфичный для block content
, как мы увидим.
Блоки являются своего рода разделением или организацией макета. Затем он может быть перезаписан в другом файле.
ПРИМЕЧАНИЕ. Код CSS и JavaScript для краткости и фокуса удалены. Вы можете найти их в репо . Кроме того, я использовал задачу copy
Grunt для переноса каталогов js
и style
из каталога app
каталог build
.
Вот файл layout.jade
:
doctype html html(lang="en" dir="ltr") block head include partials/head.jade body block content block footer include partials/footer.jade
Вы можете создать footer.jade
и head.jade
соответствии с вашими потребностями. Для нашей страницы мы будем использовать Foundation и jQuery, чтобы помочь нам установить базовый дизайн и функциональность.
Вот файл partials/head.jade
:
head meta(name="viewport", content="width=device-width, initial-scale=1.0") meta(charset="UTF-8") title Jobs link(rel = "stylesheet" href = "style/foundation.min.css") link(rel = "stylesheet" href = "style/app.css")
Вот файл partials/footer.jade
:
div#footer.row div.small-12.large-12.columns p Copyright (c) foobar script(src="js/jquery.min.js") script(src="js/foundation.min.js") script(src="js/app.js")
В следующем фрагменте кода мы создадим jobs.jade
, который использует все остальные файлы, наследуя наш макет с помощью ключевого слова extends
а затем перезаписывая нужные нам блоки. В этом примере мы перезаписываем content block
.
jobs.jade
:
extends layout.jade block content div#container.row div.small-12.large-12.columns include job-container.jade
Но что, если нам не нужно перезаписывать весь блок? Что если нам просто нужно добавить контент? Давайте возьмем block head
в качестве примера. Нам нужно добавить специальный скрипт для этой страницы в заголовок, поэтому мы будем использовать ключевые слова append
или prepend
после block
.
// append head can be used without block 'append head' block append head script. alert('Welcome to SitePoint')
Использование итераций и миксинов
В предыдущем разделе мы включили job-container.jade
. В этом разделе мы рассмотрим преимущества циклов и миксинов и то, как мы можем использовать их в Jade.
Вот начальная версия нового фрагмента кода:
- each job in jobs div.sub-container.row div.title.small-12.large-12.columns p #{job.title} div.description.display.small-12.large-12.columns div.row div.block.small-12.large-12.columns p Skills and Requirements ul - each skill in job.skills li #{skill} div.block.small-12.large-12.columns p Preferred Skills ul - each pskill in job.pskills li #{pskill} button.apply.button(value="apply") Apply
Как видите, мы используем несколько нормальных операторов цикла, например, в первой строке - each job in jobs
. Символ -
используется для небуферизованного кода, который не добавляет никаких выходных данных напрямую.
В предыдущем фрагменте кода есть избыточный код, который может стать DRY-ier, используя mixins, как в следующем коде:
- each job in jobs div.sub-container.row div.title.small-12.large-12.columns p #{job.title} div.description.display.small-12.large-12.columns div.row +skillsBlock("Skills and Requirements", job.skills) +skillsBlock("Preferred Skills", job.pskills) button.apply.button(value="apply") Apply mixin skillsBlock(title, loopItems) div.block.small-12.large-12.columns p= title ul - each skill in loopItems li #{skill}
Здесь мы создаем многократно используемый блок Jade, используя функцию mixin
. Миксины похожи на методы (или функции), которые имеют имена и принимают аргументы для оценки во внутреннем коде. В приведенном выше примере мы создали skillsBlock()
под названием skillsBlock()
.
Чтобы использовать этот mixin
, мы просто пишем его имя и передаем правильные значения параметров, добавляя префикс имени миксина со знаком +
чтобы идентифицировать его как вызов миксина.
ПРИМЕЧАНИЕ: как и в приведенном выше коде, мы можем оценивать значения либо по =
!=
Или #{}
. Но будьте осторожны при использовании !=
, Который не делает экранирования, поэтому небезопасен для ввода пользователем.
Передача данных JSON через Grunt
После создания нашей среды давайте сделаем несколько замечательных вещей с комбинацией Grunt и Jade, передав данные JSON из файла JSON в Jade с помощью задачи Grunt.
Сначала создайте файл JSON data.json и заполните его желаемыми данными.
Затем откройте Gruntfile.js
и добавьте атрибут data
в параметры задачи Jade
следующим образом:
jade: { compile: { options: { pretty: true, data: { jobs: grunt.file.readJSON('data.json') } }, files: { 'build/index.html': 'app/views/jobs.jade' } } }
Атрибут data / locals jobs
(данные, передаваемые в шаблоны Jade, называются локальными), передается в файлы Jade, указанные в свойстве files
и может использоваться в коде Jade. Этот способ дает вам возможность легко добавлять текстовое содержимое на веб-страницы.
Наконец, вы можете увидеть, как выглядит страница, если посмотрите демо . Конечно, исходный код скомпилирован, поэтому демонстрация не имеет большого значения в этом случае. Скриншот показан ниже.
Завершение
Причины использования шаблонизаторов могут различаться, но их можно отнести к категории большей производительности, меньшего количества повторений и более приятного синтаксиса. Кроме того, вы можете не захотеть писать код на родном языке, потому что он слишком повторяющийся, подвержен ошибкам, или, возможно, он вам просто не нравится. Именно здесь вступает в игру такой язык, как Jade, настроенный на сжатие и простоту кода.
Jade помогает вам писать более чистый код, который делает вашу работу менее утомительной. Мы рассмотрели некоторые основы, советы и хитрости, используя Grunt. Вы можете больше узнать о Jade, о котором мы не рассказывали в этом руководстве, поэтому вы можете ознакомиться с официальной документацией для получения дополнительной информации.