Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/olehdutchenko/gulp-ejs-monster
Gulp plugin for ejs with steroids.
https://github.com/olehdutchenko/gulp-ejs-monster
ejs gulp gulp-plugin template-engine
Last synced: 3 months ago
JSON representation
Gulp plugin for ejs with steroids.
- Host: GitHub
- URL: https://github.com/olehdutchenko/gulp-ejs-monster
- Owner: OlehDutchenko
- License: mit
- Created: 2017-05-01T20:09:50.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2024-03-01T20:39:38.000Z (11 months ago)
- Last Synced: 2024-04-14T07:24:15.895Z (9 months ago)
- Topics: ejs, gulp, gulp-plugin, template-engine
- Language: JavaScript
- Homepage:
- Size: 595 KB
- Stars: 11
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README-RU.md
- Changelog: CHANGELOG-RU.md
- Contributing: CONTRIBUTING-RU.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT-RU.md
Awesome Lists containing this project
README
# gulp-ejs-monster
![npm](https://img.shields.io/badge/node-6.3.1-yellow.svg)
![es2015](https://img.shields.io/badge/ECMAScript-2015_(ES6)-blue.svg)
![license](https://img.shields.io/badge/License-MIT-orange.svg)
[![Build Status](https://travis-ci.org/dutchenkoOleg/gulp-ejs-monster.svg?branch=master)](https://travis-ci.org/dutchenkoOleg/gulp-ejs-monster):us: [English](./README.md)
|
:ru: Русский язык> _Gulp плагин для [ejs](http://ejs.co/) со стероидами. Проект вдохновлен [ejs-locals](https://github.com/RandomEtc/ejs-locals)_
[![js happiness style](https://cdn.rawgit.com/JedWatson/happiness/master/badge.svg)](https://github.com/JedWatson/happiness)
---
## Содержание
1. [Благодарность](#Благодарность)
1. [Для чего был создан этот плагин?](#Для-чего-был-создан-этот-плагин)
1. [Пример использования плагина](#Пример-использования-плагина)
1. [gulpEjsMonster()](#gulpejsmonster)
- [Свойства плагина](#Свойства-плагина)
- [Методы плагина](#Методы-плагина)
- [Параметры плагина](#Параметры-плагина)
- [Отчеты о ошибках рендера](#Отчеты-о-ошибках-рендера)
1. [locals API](#locals-api)
- [Свойства](#Свойства)
- [Методы](#Методы)
1. [Информация о проекте](#Информация-о-проекте)---
## Благодарность
Прежде всего, хотим выразит свою благодарность людям которые привели нас к использованию шаблонизатора [`ejs`](https://www.npmjs.com/package/ejs) и созданию на его основе `gulp-ejs-monster`:
- [Matthew Eernisse (mde)](https://github.com/mde) - за создание и поддержку [`ejs`](https://github.com/mde/ejs)(http://ejs.co), а также сообщество `ejs`, которое ему в этом помогает
- [Tom Carden (RandomEtc)](https://github.com/RandomEtc) - за создание проекта [`ejs-locals`](https://github.com/RandomEtc/ejs-locals), с которого мы взяли идею реализации `gulp-ejs-monster`
- [Ryan Zimmerman (RyanZim)](https://github.com/RyanZim) - [`EJS-Lint`](https://github.com/RyanZim/EJS-Lint)
- [Ariya Hidayat (ariya)](https://github.com/ariya) - [`jquery/esprima`](https://github.com/jquery/esprima)
- [Corey Hart (codenothing)](https://github.com/codenothing) - [`jsonlint`](https://github.com/codenothing/jsonlint)## Для чего был создан этот плагин?
[`ejs`](https://www.npmjs.com/package/ejs)(http://ejs.co) - это универсальный шаблонизатор, который позволяет создавать любую разметку, любой сложности. Чем лучше Ваше познания JavaScript - тем больше перед Вами открывается возможностей с `ejs`.
Уже существует много других плагинов для `ejs`. Но мы также решили создать свой, как надстройку к шаблонизатору + прокачав его небольшим набором "стероидов" ))).
Также, основной упор плагина `gulp-ejs-monster` - был сделан на оптимизацию и скорость рендера.
По умолчанию `ejs` использует JavaScript конструкцию [`with (expression)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with) для добавления области видимости - это дает свои преимущества для работы с шаблонизатором, но имеет свою цену - скорость поиска переменных увеличивается - что сказывается на скорости рендера страниц. Это особенно заметно на больших проектах.
Поэтому `gulp-ejs-monster` принудительно отключает родные параметры `ejs` для того чтобы работать в строгом режиме. Что дает значительный прирост к скорости рендера.
Список константных значений от `gulp-ejs-monster` для `ejs`:
```json
{
"strict": true,
"_with": false,
"debug": false,
"rmWhitespace": false,
"client": false
}
```Такой подход, также имеет свою цену - теперь для работы Вам доступен только один глобальный объект, без всяких "проксируемых" свойств (которые раньше имитировала конструкция `with`).
> Если этот подход к работе с `ejs` шаблонизатором Вас не устраивает, Вы можете не читать дальше и не создавать запросов, так как менять его мы не намерены )))
## Пример использования плагина
### Установка
```bash
npm i --save-dev gulp-ejs-monster
# or yarn cli
yarn add --dev gulp-ejs-monster
```### Gulp задача
```js
const gulp = require('gulp');
const gulpEjsMonster = require('gulp-ejs-monster');gulp.task('ejs', function() {
return gulp.src('./src/ejs/*.ejs')
.pipe(gulpEjsMonster({/* plugin options */}))
.pipe(gulp.dest('./dist/'));
});
```### EJS разметка
Пример структуры проекта
```js
ejs/
layouts/
base.ejs
widgets/
news-list.ejs
includes/
critical.css
requires/
news-list.json
index.ejs
news.ejs
```#### Лейауты
###### layouts/base.ejs
```html
<%- locals.blocks.title %>
<%- locals.include('includes/critical.css') %>
<%- locals.blocks.header %>
<%- locals.body %>
```
#### Страницы рендера
###### index.ejs
```html
<% locals.setLayout('layouts/base.ejs') -%>
<% locals.block('title', 'Index view') -%>Index view
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
```###### news.ejs
```html
<% locals.setLayout('layouts/base.ejs') -%>
<% locals.block('title', 'Last News') -%>
<% let newsList = locals.require('requires/news-list.json') -%>Last News
<%- locals.widget('widgets/news-list.ejs', {list: newsList}) %>
```#### Исполняемые файлы
###### requires/news-list.json
```json
[
{
"title": "News title 1",
"description": "Lorem ipsum dolor sit ....",
"href": "news-page.html"
}, {
"title": "News title 2",
"description": "Lorem ipsum dolor sit ....",
"href": "news-page.html"
}, {
"title": "News title 3",
"description": "Lorem ipsum dolor sit ....",
"href": "news-page.html"
}
]
```#### Текстовые файлы
###### includes/critical.css
```css
html{font-family:sans-serif}
body{margin:0}
h1{color:red}
```#### Виджеты
###### widgets/news-list.ejs
```html
<%
let {
list = []
} = locals.entry;
if (!list.length) {
return 'No news yet :((';
}
-%>
<% list.forEach(item => { -%>
<% }); -%>
```
---
## gulpEjsMonster
### Свойства плагина
#### `gulpEjsMonster.pluginName`
Имя плагина.
### Методы плагина
#### `gulpEjsMonster.preventCrash()`
Метод который при ошибке вызовет событие `end` чтобы предотвратить _"падение"_ текущего процесса `gulp` задачи.
###### Пример использования
```js
const gulp = require('gulp');
const gulpEjsMonster = require('gulp-ejs-monster');
gulp.task('ejs', function() {
return gulp.src('./src/ejs/*.ejs')
.pipe(gulpEjsMonster({/* plugin options */}).on('error', gulpEjsMonster.preventCrash))
.pipe(gulp.dest('./dist/'));
});
```
### Параметры плагина
Небольшой совет - чтобы ускорить переработку и подготовку параметров плагина - используйте созданый объект с сохранением в переменную, которую потом Вы сможете указвать при вызове.
В таком случае, за счет сохранения ссылок на внешний объект, параметры не будут пере-подготавливаться. А также появляется возможность сохранения полученных данных (в объекте `locals`) от предыдущей страницы рендера к последующим.
###### Пример использования
```js
const gulp = require('gulp');
const gulpEjsMonster = require('gulp-ejs-monster');
const options = {/* plugin options */}; // save as variable
gulp.task('ejs', function() {
return gulp.src('./src/ejs/*.ejs')
.pipe(gulpEjsMonster(options).on('error', gulpEjsMonster.preventCrash))
.pipe(gulp.dest('./dist/'));
});
```
Далее Вы можете ознакомится со списком всех доступных параметров.
#### `layouts`
_тип данных_ `string`
|
_по умолчанию_ `process.cwd()`
Относительный путь от текущей рабочей директории к директории с лейаутами.
#### `widgets`
_тип данных_ `string`
|
_по умолчанию_ `process.cwd()`
Относительный путь от текущей рабочей директории к директории с виджетами.
#### `requires`
_тип данных_ `string`
|
_по умолчанию_ `process.cwd()`
Относительный путь от текущей рабочей директории к директории с js/json файлами, которые Вы сможете подключать как исполняемые файлы, используя експорт CommonJS Модулей.
#### `includes`
_тип данных_ `string`
|
_по умолчанию_ `process.cwd()`
Относительный путь от текущей рабочей директории к директории c любыми текстовыми файлами, с которых Вы сможете подключать тектовый контент как есть.
#### `extname`
_тип данных_ `string`
|
_по умолчанию_ `'.html'`
Расширение итоговых файлов рендера.
Разрешается не указывать . (точку) в начале значения, пример `'php' => '.php'`
#### `delimiter`
_тип данных_ `string`
|
_по умолчанию_ `'%'`
|
_допустимые значения_ `['%', '&', '$', '?']`
Символ для использования с угловыми скобками для открытия / закрытия.
Если указаннное свойство не соответствует допустимому - будет утановлено значение по умолчанию!
#### `localsName`
_тип данных_ `string`
|
_по умолчанию_ `'locals'`
Имя, которое будет использоваться для объекта, хранящего локальные переменные. Вы можете заменить это значение на свое и в дальнейшем использовать его внутри шаблонизатора.
Соответствено значение должно иметь корректное имя JavaScript переменной!
#### `locals`
_тип данных_ `Object`
|
_по умолчанию_ `{}`
Передача собственных значений в объект, хранящий локальные переменные, которые будут доступны Вам внутри шаблоназотора в объекте `locals` (или под тем именем которое Вы могли указать в свойстве `localsName`)
Важно знать, что плагин уже имеет определенный набор свойств и методов, которые будут добавлены к этому объекту. Поэтому чтобы не было конфликтов и перезаписей - ознакомтесь с [locals API](#locals-api).
#### `compileDebug`
_тип данных_ `boolean`
|
_по умолчанию_ `false`
При отключении - инструменты отладки не компилируются, что позволяет немного ускорить процесс рендера.
Указанное значение будет приведено к булевому.
Важно знать, что при ошибке - плагин не сможет дать пояснения о произошедшем сбое, если значение равно `false`. Поэтому, в случае ошибки - плагин сделает рендер текущей страницы заново c включенным параметром, для того что бы выяснить что пошло не так и вывести максимальный отчет о найденных ошибках.
Если вы используете вотч задачи для рендера - после исправления ошибки параметр снова будет иметь прежнее значение.
> В очень специфических ситуациях ре-рендер может не корректно выявить ошибки, из-за
> повторного прохода, при котором, к примеру уже могут быть переопределены какие-то значение и тд.
> Если это происходит - запустите сразу задачу с включенным параметром `compileDebug`
#### `showHistory`
_тип данных_ `boolean`
|
_по умолчанию_ `false`
Выводит историю рендера после завершения работы с каждой страницей.
#### `showHistoryOnCrash`
_тип данных_ `boolean`
|
_по умолчанию_ `false`
Выводит историю рендера при ошибках.
#### `escape`
_тип данных_ `function`
|
_по умолчанию_ `undefined`
###### Параметры
Name | Type | Description
--- | --- | ---
`markup` | `string` | Разметка внутри конструкции
Собственная функция экранирования, используемая с конструкцией `<%=`, которая должна возвращать строку.
#### `afterRender`
_тип данных_ `function`
|
_по умолчанию_ `undefined`
Метод который будет вызван после рендера страницы с ее лейаутами.
###### Параметры
Name | Type | Description
--- | --- | ---
`markup` | `string` | Итоговая разметка страницы
`file` | `Object` | Текущий файл рендера
`sources` | `Array.` | Пути всех подключенных файлов в процессе рендера текущего файла, включая путь к текущей странице (первый в списке)
Используя метод `afterRender` Вы можете изменить разметку, к примеру отформатировать при помощи [`js-beautify`](https://github.com/beautify-web/js-beautify) и вернуть новый результат использая `return` или использовать метод для установки вотчей на зависимости для каждой страницы отдельно.
###### Пример форматирования разметки
```js
const gulp = require('gulp');
const gulpEjsMonster = require('gulp-ejs-monster');
const jsBeautify = require('js-beautify').html;
const options = {
afterRender (markup) {
return jsBeautify.html(markup, /* jsBeautify options */);
}
};
gulp.task('ejs', function() {
return gulp.src('./src/ejs/*.ejs')
.pipe(gulpEjsMonster(options).on('error', gulpEjsMonster.preventCrash))
.pipe(gulp.dest('./dist/'));
});
```
###### Пример установки вотчей на зависимые файлы
```js
const gulp = require('gulp');
const gulpEjsMonster = require('gulp-ejs-monster');
const gulpWatchAndTouch = require('gulp-watch-and-touch');
const ejsFileWatcher = gulpWatchAndTouch(gulp);
const watchTask = true;
const options = {
afterRender (markup, file, sources) {
if (watchTask) {
let filePath = sources.shift(); // remove path of current view
let newImports = ejsFileWatcher(filePath, filePath, sources);
if (newImports) {
console.log(`${file.stem} has new imports`);
}
}
}
};
gulp.task('ejs', function() {
return gulp.src('./src/ejs/*.ejs')
.pipe(gulpEjsMonster(options).on('error', gulpEjsMonster.preventCrash))
.pipe(gulp.dest('./dist/'));
});
gulp.task('ejs-watch', function() {
gulp.watch('./src/ejs/*.ejs', gulp.series('ejs')); // gulp#4.x
});
```
### Отчеты о ошибках рендера
Мы также сделали упор на вывод максимальных отчетов о ошибках которые могут возникнуть при рендере страниц, чтобы Вы могли понять что пошло не так
При сбое Вы будете получать группу отчетов:
#### render history
История рендера текущей страницы, при помощи которой вы сможете отследить последовательность действий плагина
> _**Внимание!** Начиная с версии 3.1.0_
> История выводится только при включенном параметре [showHistoryOnCrash](#showHistoryOnCrash)
```bash
Render history:
Start
render view - C:\Wezom\NodeModules\gulp-ejs-monster\examples\src\index.ejs
> set layout - C:\Wezom\NodeModules\gulp-ejs-monster\examples\src\_layouts\base.ejs
> render widget - C:\Wezom\NodeModules\gulp-ejs-monster\examples\src\_widgets\demo.ejs
caching new file content
√ file changed
! render file content
> render widget - C:\Wezom\NodeModules\gulp-ejs-monster\examples\src\_widgets\demo.ejs
getting file content from cache
! file not changed
! render file content
> require node module "lodash"
caching new file content
> require file - C:\Wezom\NodeModules\gulp-ejs-monster\examples\src\_requires\data.js
√ file changed
caching new file content
> require file - C:\Wezom\NodeModules\gulp-ejs-monster\examples\src\_requires\component.js
→ CRASH...
```
#### ejs report
Родной `ejs` отчет о найденной ошибке
> Наявность следующих отчетов будет зависеть от самой ошибки и файла в котором она произошла
#### fs report
Если файл, к которому вы обратились, не был найден.
#### ejs-lint report
Если ошибка в `*.ejs` файле - будет проведен линтинг плагином [`EJS-Lint`](https://github.com/RyanZim/EJS-Lint), для выявления возможных ошибок
#### esprima report
Если ошибка в `*.js` файле - будет проведен анализ плагином [`esprima`](https://github.com/jquery/esprima), для выявления возможных ошибок
#### json-lint report
Если ошибка в `*.json` файле - будет проведен линтинг плагином [`json-lint`](https://github.com/codenothing/jsonlint), для выявления возможных ошибок
---
## locals API
`locals` - это единный глобальный объект хранящий в себе локальные значения, который будет доступен для работы шаблонизатора.
### Свойства
#### locals.body
_тип данных_ `string`
Контент текущей страницы, для вставки внутри лейаутов.
Соответственно свойство доступно только внутри лейаутов!
###### Пример использования
```html
<% locals.setLayout('base.ejs') %>
Index view
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
```
```html
Document
<%- locals.body %>
```
#### locals.blocks
_тип данных_ `Object`
Список собранных блоков, которые создаются при помощи метода [`locals.block()`](#localsblock-blockname-markup--mtd---block)
###### Пример использования
```html
<% locals.setLayout('base.ejs') %>
<% locals.block('title', 'Index view') %>
<% locals.block('header', '
Index view header
') %>```
```html
<% locals.setLayout('base.ejs') %>
<% locals.block('title', 'Last News') %>
<% locals.block('header', '
News view header
') %>```
```html
<%- locals.blocks.title %>
<%- locals.blocks.header %>
<%- locals.body %>
```
#### locals.entry
_тип данных_ `Object`
Входящие параметры для текущего виджета.
Соответственно свойство доступно только внутри виджетов!
###### Пример использования
```html
<%- locals.widget('test.ejs') %>
<%- locals.widget('test.ejs', {title: 'Custom title'}) %>
```
```html
<% let title = locals.entry.title || 'Default title'; %>
<%- title) %>
```
###### Пример с используванием деструктуризации es6
```html
<% let {title = 'Default title'} = locals.entry; %>
<%- title) %>
```
#### locals.viewName
_тип данных_ `string`
Имя текущей страницы рендера (без расширения).
Независимо от текущего виджета, инклуда лейаута и тд.
#### locals.viewPath
_тип данных_ `string`
Абсолютный путь к текущей странице рендера в Вашей файловой системе.
Независимо от текущего виджета, инклуда лейаута и тд.
#### locals.fileChanged
_тип данных_ `boolean`
Флаг, изменился ли файл после последнего обращения к нему.
Свойство доступно внутри виджетов. На основных страницах рендера и их лейаутах, свойство также доступно, но для них оно всегда будет равно `true`.
### Методы
#### locals.setLayout (filePath)
Устанавливает путь к лейауту для текущей страницы.
###### Параметры
Name | Type | Description
--- | --- | ---
`filePath` | `string` | Путь к файлу (с расширением) относительно директории указанной в параметре [layouts](#layouts)
#### locals.widget (filePath _[, relativeFolderPath] [, entry] [, cacheRenderResult]_) → `string`
Подключение виджета разметки.
###### Параметры
Name | Type | Attributes | Default | Description
--- | --- | --- | --- | ---
`filePath` | `string` | | | Путь к файлу (с расширением) относительно директории указанной в параметре [widgets](#widgets)
`relativeFolderPath` | `string` | <optional> | | Относительный путь от которого следует подключать указанный файл, игнорируя параметр [widgets](#widgets), Если параметр не равен строке, то он воспринимается как `entry`
`entry` | `Object` | <optional> | `{}` | Входящие данные, которые передаются внутрь виджета, Если параметр `relativeFolderPath` не равен строке и третий параметр равен логическому значению, то он воспринимается как `cacheRenderResult`
`cacheRenderResult` | `boolean` | <optional> | `false` | Кешировать результат рендера разметки.
###### Возвращает
- _тип_: `string`
- _описание_: рендер ejs разметки
Внутри виджета Вы можете принять входящие параметры из [`locals.entry`](#localsentry).
_Кеширование результата рендера_ позволит запоминать полученную строку в виде уже ***готовой статической разметки*** и вставлять ее при последующих вызовах на странице без прохода компиляции. Чтобы это выполнить при последующих применениях виджета нужно также указавать `cacheRenderResult`. Иначе рендер будет выполнен снова для текущего вызова.
При изменении файла самого виджета (смены даты модификации) - кэш будет сброшен.
Этот подход также можно использовать для нескольких страниц в общей задаче рендера.
К примеру - первая страница, `index.ejs`, рендерить блок кода, a `news.ejs`, которая идет после, уже возьмет закэшированный результат.
###### Пример использования
```html
<%- locals.widget('big-rendering-markup.ejs', {/*data*/}, true) %>
<%- locals.widget('big-rendering-markup.ejs', {/*data*/}, true) %>
<%- locals.widget('big-rendering-markup.ejs', {/*data*/}) %>
<%- locals.widget('big-rendering-markup.ejs', {/*data*/}, true) %>
```
#### locals.requireNodeModule (moduleName) → `*`
Подключение модулей из установленных `node_modules`
###### Параметры
Name | Type | Description
--- | --- | ---
`moduleName` | `string` | Имя модуля
###### Возвращает
- _тип_: `*`
- _описание_: подключеный модуль
###### Пример использования
```js
<%
let lodash = locals.requireNodeModule('lodash');
lodash.cloneDeep(options);
lodash.isPlainObject(data);
%>
```
#### locals.require (filePath _[, relativeFolderPath]_) → `*`
Подключение собственных исполняемых js/json файлов с поддержкой CommonJS для экспорта.
###### Параметры
Name | Type | Attributes | Default | Description
--- | --- | --- | --- | ---
`filePath` | `string` | | | Путь к файлу (с расширением) относительно директории указанной в параметре [requires](#requires)
`relativeFolderPath` | `string` | <optional> | | Относительный путь от которого следует подключать указанный файл, игнорируя параметр [requires](#requires)
###### Возвращает
- _тип_: `*`
- _описание_: подключеный файл
Внутри таких файлов объект `locals` не доступен. Вы можете передать его внутрь файла, к примеру, если вы экспортируете некий метод:
Вариант 1. Привязать контекст для метода
```js
<%
let component = locals.require('component.js').bind(locals);
component('Hello');
%>
```
```js
// component.js
function component (message) {
console.log(this);
console.log(message);
// require another components and files
let anotherComponent = this.require('another-component.js').bind(this);
let data = this.require('config.json');
// ...
}
module.exports = component;
```
Вариант 2. Использовать _каррирование (карринг)_
```js
<%
let component = locals.require('component.js')(locals);
component('Hello');
%>
```
```js
// component.js
// Function wrapper
function componentWrapper (locals) {
// component
function component (message) {
console.log(locals);
console.log(message);
// require another components and files
let anotherComponent = locals.require('another-component.js')(locals);
let data = this.require('config.json');
// ...
}
return component;
}
module.exports = componentWrapper;
```
#### locals.include (filePath _[, relativeFolderPath]_) → `Object`
Включает текстовый контент файла в Вашу разметку как есть.
###### Параметры
Name | Type | Attributes | Default | Description
--- | --- | --- | --- | ---
`filePath` | `string` | | | Путь к файлу (с расширением) относительно директории указанной в параметре [includes](#includes)
`relativeFolderPath` | `string` | <optional> | | Относительный путь от которого следует подключать указанный файл, игнорируя параметр [includes](#includes)
###### Возвращает
- _тип_: `Object`
- _описание_: Объект имеет набор свойств
- `changed` - флаг, изменен ли файл
- `mtime` - Дата последней модификации файла
- `content` - Строка с контентом файла
- `toString()` - собственный метод приведения в строку, который возвращает `this.content`, таким образом если выполнить метод в контексте вставки в разметку - результатом будет сразу контент файла.
###### Пример использования
```html
<%- locals.include('critical.css') %>
```
###### Пример создания компонента с конвертацией md в html
```js
// requires/components/md2html.js
function createMd2HtmlComponent (locals) {
const marked = locals.requireNodeModule('marked');
const lodash = locals.requireNodeModule('lodash');
const defaultOptions = {
render: false,
gfm: true,
tables: true,
breaks: true,
pedantic: false,
sanitize: false,
smartLists: true,
smartypants: true
};
/**
* Convert md 2 html
* @param {string} filePath
* @param {Object} [options={}]
* @returns {string} converted html markup
*/
function md2html (filePath, options = {}) {
let mdFile = locals.include(filePath);
if (mdFile.changed) {
let markedOptions = lodash.merge({}, defaultOptions, options);
// rewrite cached file content until it not changed
mdFile.content = marked(mdFile.content, markedOptions);
}
return mdFile;
}
return md2html;
}
module.exports = createMd2HtmlComponent;
```
```js
// requires/extend-locals.js
function extendLocals (locals) {
if (!locals.hasOwnProperty('com')) {
locals.com = {};
}
locals.com.md2html = locals.com.md2html || locals.require('components/md2html.js')(locals);
// set other components inside render
// ...
}
module.exports = extendLocals;
```
```markdown
# icludes/about-us.md
[Markdown-Cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet)
# H1
## H2
### H3
#### H4
##### H5
###### H6
Alternatively, for H1 and H2, an underline-ish style:
Alt-H1
======
Alt-H2
------
```
```html
<% locals.setLayout('base.ejs'); -%>
<% locals.require('extend-locals.js')(locals); -%>
<%- locals.com.md2html('about-us.md') %>
```
#### locals.block (blockName, markup _[, mtd]_) → `Block`
Указание блока разметки, который будет доступен в [списке блоков](#localsblocks).
###### Параметры
Name | Type | Attributes | Default | Description
--- | --- | --- | --- | ---
`blockName` | `string` | | | Имя блока, по которому можно будет обратится в [списке блоков](#localsblocks)
`markup` | `string` | | | Значение блока
`mtd` | `string` | <optional> | `'replace'` | Метод указания значения для блока.
###### Возвращает
- _тип_: `string`
- _описание_: значение блока
При указании значения для блока - формируется массив, которые при выводе склеивается в строку.
Методы указания значения для блока:
- `'replace'` - заменить предыдущее значение, если оно было. Если нет то просто назначит новое значение.
- `'append'` - добавить в конец массива новое значение.
- `'prepend'` - добавить в начало массива новое значение.
###### Пример использования методов добавления
```js
<% locals.block(headers, '
Ipsum
') %>...
<% locals.block(headers, '
Dolor
', 'append') %>...
<% locals.block(headers, '
Lorem
', 'prepend') %>...
<%- locals.blocks.header %> // => ['
Lorem
', 'Ipsum
', 'Dolor
'].join('\n');```
---
## Информация о проекте
* [История изменений](./CHANGELOG-RU.md)
* [Руководство по содействию проекту](./CONTRIBUTING-RU.md)
* [Кодекс поведения](./CODE_OF_CONDUCT-RU.md)
* [Лицензия MIT](./LICENSE)