gulp-fest-hardcore v3.0.0
gulp-fest-hardcore
Fest — это шаблонизатор общего назначения, компилирующий XML шаблоны в самодостаточные JavaScript функции. Для установки требуется Node.js >= 0.8.
кастрированная версия
- нет try-cache - надо оборачивать саму ф-ю вызова
- нет неймспейса fest
- нет контекста, внутри шаблона есть только params
выпилины конструкции:
template
- контексты убраныtext
- нецелесообразенelement
- полигон для усложненийattributes
- нецелесообразенattribute
- нецелесообразенeach
- заменён наfor
choose
- заменён наswitch
when
- заменён наcase
otherwise
- заменён наdefault
script
- обычный html тегvar
- заменен наvars
изменены параметры и значения по умолчанию
value
output -> escape по умолчанию text, вместо htmlfor
from="1" to="5" выпилено
добавлены
for
in <-each
switch
<-choose
case
<-when
default
<-otherwise
vars
<-var
js
,lua
,xslate
,only
<-script
нада быть внимательным: формируемый шаблон условно делится на выражения и возвращаемое значения.
<!--antipatern-->
<value>
(params.c = params.a + params.b, params.c)
</value>
<if test="params.c">
fail
</if>
<!--
module.exports = function (params) {
var __expr0__ = "";
if (params.c) {
__expr0__ = "fail"
}
return ((params.c = params.a + params.b, params.c)) + __expr0__
}
-->
<!--patern-->
<script>
params.d = params.a - params.b
</script>
<if test="params.d">
good
</if>
<!--
module.exports = function (params) {
params.d = params.a - params.b;
var __expr1__ = "";
if (params.d) {
__expr1__ = "good"
}
return __expr1__
}
-->
Установка
npm install gulp-fest-hardcore
Введение
Шаблоны представляют собой псевдо XML документы, содержащие HTML, текстовые данные и управляющие конструкции.
Hello, <value>params.name</value>!
Замечание: начальные и конечные пробелы в текстовых узлах удаляются при компиляции. Если необходимо вывести символ пробела, можно вопспользоваться <space />
.
Данные и вывод
value
Служит для вывода значения JavaScript выражения. Поддерживаем 4 режима вывода: text (по умолчанию), html, js и json.
Использует глобальные функции: $.escapeHTML(value)
, $.escapeJS(value)
- их следует определить самостоятельно,
или использовать следующие:
$.escapeHTML = function (s) {
if (typeof s === 'string') {
if (/[&<>"]/.test(s)) {
return s.replace(/[&<>"]/g, function(chr) {
return {
'&': '&',
'<': '<',
'>': '>',
'\"': '"'
}[chr]
});
}
} else if (typeof s === 'undefined') {
return '';
}
return s;
}
$.escapeJS = function (s) {
if (typeof s==="string") {
if (/[\\'"\/\n\r\t\b\f<>]/g.test(s)) {
return s.replace(/[\\'"\/\n\r\t\b\f<>]/g, function (chr){
return {
'"': '\"',
'\\': '\\',
'/' : '\\/',
'\n': '\\n',
'\r': '\\r',
'\t': '\\t',
'\b': '\\b',
'\f': '\\f',
'\'' : '\\\'',
'<' : '\\u003C',
'>' : '\\u003E'
}[chr];
});
}
} else if (typeof s==="undefined") {
return "";
}
return s;
}
$.extend = function (original, extended) {
extended = extended || {};
for (var key in extended) {
original[key] = extended[key];
}
return original;
}
return {
escapeHTML = function (s)
if s == nil then return '' end
local esc, i = s:gsub('&', '&')
:gsub('<', '<')
:gsub('>', '>')
:gsub('\"', '"')
return esc
end,
escapeJS = function (s)
if s == nil then return '' end
local esc, i = s:gsub('"', '\"')
:gsub('\\', '\\')
:gsub('/' , '\\/')
:gsub('\n', '\\n')
:gsub('\r', '\\r')
:gsub('\t', '\\t')
:gsub('\b', '\\b')
:gsub('\f', '\\f')
:gsub('\'' , '\\\'')
:gsub('<' , '\\u003C')
:gsub('>' , '\\u003E')
return esc
end,
extend = function (destination, source)
for k,v in pairs(source) do
destination[k] = v
end
return destination
end
}
<vars value='"<script/>"' />
<value>value</value><!-- "<script/>" -->
<value escape="html">value</value><!-- "<script/>" -->
<value escape="js">value</value><!-- \"\u003Cscript\/\u003E\" -->
vars
Устаналивает локальную JavaScript переменную. имя будет принудительно переведено в lowercase
<vars Illegar="1" question="'Ultimate Question of Life, The Universe, and Everything'" answer="question.length - 13" />
<value>Illegar</value><!-- undefined -->
<value>illegar</value><!-- 1 -->
<value>question</value><!-- Ultimate Question of Life, The Universe, and Everything -->
<value>answer</value><!-- 42 -->
space
Служит для вывода пробела. Необходим в тех случаях, когда пробел в тектовом узле удаляется при компиляции, например:
Hello,<space/><value>json.name</value>!<!-- Hello, John! -->
require
Вызывает через require модуль с параметрами по аналогии с get
<require name="name0">{some: 'data'}</require>
<!--
var __params0__ = {some: 'data'};
require("name0")(__params0__);
-->
<require name="name1">
<params>
{a: 1, b:2}
</params>
<param name="html">
<div class="a">1</div>
</param>
</require>
<!--
var __params1__ = {};
$.extend(__params1__, {a: 1, b:2});
__params1__.html = '<div class="a">1</div>';
require("name1")(__params1__);
-->
<require name="name2" params="{a:1, b:2}" />
<!--
var __params2__ = {a:1, b:2};
require("name2")(__params2__);
-->
<require name="name3" params="{a:1, b:2}">
{a:2,b:3,c:4}
</require>
<!--
var __params3__ = {a:1, b:2};
$.extend(__params3__, {a:2,b:3,c:4});
require("name3")(__params3__);
-->
set
Объявляет именованную функцию. Содержимое set
не будет выполнено до тех пор, пока не будет вызван блок с таким же имененем с помощью get
.
<set name="name">John</set>
<set name="full_name">
<get name="name"/><space/>F. Kennedy
</set>
Внутри set
доступен контекст params
, передаваемый через get
.
<set name="line">
Hello,<space/><value>params.username</value>!
</set>
<get name="line">{username: "John"}</get><!-- Hello, John! -->
get
Выводит содержимое блока, объявленного через set
.
<get name="name" />
<get name="name">{'some': 'data'}</get>
<get name="test">
{a: 1, b:2}
</get>
<get name="test">
<params>
{a: 1, b:2}
</params>
<param name="html">
<div class="a">1</div>
</param>
</get>
<get name="test" params="{a:1, b:2}" />
Внутри атрибута name
можно использовать JavaScript выражения для вычисления имени блока во время выполнения. Значения выражений, заключенных в фигурные скобки, объединяются с примыкающим текстом. Помимо этого, можно использовать атрибут select
.
<vars name="'foo'" />
<get select="name"/><!-- foo -->
<set name="foo">foo</set>
<set name="bar">bar</set>
<get name="b{true?'a':''}r"/><!-- bar -->
Существует быстрый способ вывести значение в атрибут:
<a href="{params.href}">Some link</a>
Управляющие конструкции
for
Выполняет итерацию по массиву или числовому ряду. неявно оборачивается if который проверяет iterate и его length, в связи с этим можно после закрытия </for>
пришпилить elseif
или else
как в обычном if
стеке
<!-- params.items = ['a', 'b', 'c'] -->
<for iterate="params.items" index="i" value="v">
<value>params.items[i]</value>
</for><!-- abc -->
<!-- params.items = ['a', 'b', 'c'] -->
<for var="v" of="params.items">
<value>v</value>
</for><!-- abc -->
<!-- params.items = ['a', 'b', 'c'] -->
<!-- спорно: в принципе там следует ожидать индекс, а не значение -->
<for var="v" in="params.items">
<value>v</value>
</for><!-- abc -->
<!-- if (params.items && params.items.length)-->
<for iterate="params.items" index="i" value="v">
<value>v</value>
</for><!-- abc -->
<!-- /if -->
<elseif test="foo">
foo text
</elseif>
<elseif test="bar">
bar text
</elseif>
<else>
else text
</else>
if, elseif, else
Условный оператор.
<if test="var0">
<value>var0</value>
</if>
<elseif test="var2">
<value>var2</value>
</elseif>
<else>
ELSE
</else>
switch case default
<switch test="var0">
<case is="1">
var is 1
</case>
<case is="'2'">
var is '2'
</case>
<case is="a">
var is `a`
</case>
<default>
var is not 1 or 2
</default>
</switch>
Если нужно
switch (z) {
case 'a':
case 'b':
case 'c':
domagick;
break;
case 'd':
doD;
break;
default:
'docommon'
}
пользуй аттрибут any
и сепаратор значений |
.
не нужен break
? пользуй аттрибут nobreak
<switch test="z">
<case any="'a' | 'b' | 'c'">
<value>domagick</value>
</case>
<case is="'c'">
<value>doD</value>
</case>
<default nobreak="1">
docommon
</default>
</switch>
Остальные конструкции
cdata
Служит для вывода блока CDATA.
<cdata>
alert ("2" < 3);
</cdata><!-- <![CDATA[alert ("2" < 3);]]> -->
comment
Выводит HTML комментарий.
<comment>comment</comment><!-- <!--comment--> -->
doctype
Задает DOCTYPE генерируемой страницы.
<doctype>html</doctype><!-- <!doctype html> -->
include
выпилено
insert
Вставить файл напрямую в шаблон
src
- относителен к текущему файлу (его папке)
<style type="text/css">
<insert src="style.css"/>
<style>
<script>
<insert src="inline-script.js"/>
</script>
js lua xslate only script
Раньше в script
запихивалась js-магия, нужно было разделить эту магию на js, lua и xslate, когда шаблонизатор начал поддерживать эти языки.
так появился only
с аттрибутом for
. далее появильсь более простые обёртки, в виде тегов смысл которых идентичен:
<script><insert src="inline.js" /></script><!-- <script>#контент файла inline.js#</script> -->
<js>
var i = function(...){...}
</js>
<lua>
<vars cjson="require 'cjson'" />
<script>
console.log(<value>cjson.encode(params)</value>)
</script>
</lua>
<xslate>
my i = include inc::html ->{}
</xslate>
<only for="js">
var i = function(...){...}
</only>
continue
break
return
вставляют в текущий стек выражений соответствующую конструкцию
Примеры
Использование
var parser = new Parser(options);
parser.write(file.contents.toString('utf8'), file.path);
file.contents = parser.getSource();
gulp:
var festHardcore = require('gulp-fest-hardcore');
gulp.src('src/**/*.xml')
.pipe(festHardcore())
.pipe(beautify({
indentSize: 2
}))
.pipe(gulp.dest('build/templates'))
Использование set и get
<set name="host">http://e.mail.ru</set>
<set name="all">msglist</set>
<set name="new">sentmsg?compose</set>
<set name="all_link">
<get name="host"/>/<get name="all"/>
</set>
<set name="new_link">
<get name="host"/>/<get name="new"/>
</set>
Интернационализация
fest:plural - выпилено
7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago