New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

fest

Package Overview
Dependencies
Maintainers
2
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fest - npm Package Compare versions

Comparing version 0.7.3 to 0.8.0

59

lib/compile.js

@@ -134,2 +134,21 @@ var compile = (function(){

function compileExpr(attr, _getExpr){
var i = 0, attrValue = '', result = {containsExpr: false, text: []} ;
attrValue = attr.value.replace(/{{/g, "__DOUBLE_LEFT_CURLY_BRACES__").replace(/}}/g, "__DOUBLE_RIGHT_CURLY_BRACES__");
attrValue.match(/{[^}]*}|[^{}]*/g).forEach(function (str) {
if (str !== '') {
if (str[0] === '{') {
i++;
result.text.push('(' + str.slice(1, -1).replace(/__DOUBLE_LEFT_CURLY_BRACES__/g, "{").replace(/__DOUBLE_RIGHT_CURLY_BRACES__/g, "}") + ')');
_getExpr(result.text[result.text.length-1], 'expression #' + (i) + ' in attribute "' + attr.name + '"');
result.containsExpr = true;
} else{
result.text.push('"' + escapeJS(escapeHTML(str)).replace(/__DOUBLE_LEFT_CURLY_BRACES__/g, "{").replace(/__DOUBLE_RIGHT_CURLY_BRACES__/g, "}") + '"');
}
}
});
result.text = result.text.join('+');
return result;
}
function errorMessage(msg, badLine, file) {

@@ -343,3 +362,7 @@ function zeroPadding(s, len) {

opentag = true;
section.source += 'try{__fest_element=' + _getAttr(node, 'select', 'expr') + ';';
if (node.attributes.select) {
section.source += 'try{__fest_element=' + _getAttr(node, 'select', 'expr') + ';';
} else{
section.source += 'try{__fest_element=' + compileExpr(node.attributes.name, _getExpr).text + ';';
}
section.source += 'if(typeof __fest_element !== "string"){__fest_log_error("Element name must be a string");__fest_element="div"}';

@@ -360,3 +383,20 @@ section.source += '}catch(e){__fest_element="div";__fest_log_error(e.message);}';

case 'attribute':
section.source += '__fest_pushstr(__fest_context," ' + escapeJS(_getAttr(node, 'name')) + '=\\"");';
expression = compileExpr(node.attributes.name, _getExpr);
if (expression.containsExpr){
section.source += 'try{__fest_select=' + expression.text + '}catch(e){__fest_select="";__fest_log_error(e.message)}';
section.source += 'if(__fest_select!==""){';
node.conditional = true;
section.source += '__fest_pushstr(__fest_context," " + __fest_select + "=\\"");' ;
} else{
section.source += '__fest_pushstr(__fest_context," ' + escapeJS(_getAttr(node, 'name')) + '=\\"");';
}
if(node.attributes.value){
expression = compileExpr(node.attributes.value, _getExpr);
if (expression.containsExpr){
section.source += 'try{__fest_select=' + expression.text + '}catch(e){__fest_select="";__fest_log_error(e.message)}';
section.source += '__fest_pushstr(__fest_context,__fest_select);';
} else{
section.source += '__fest_pushstr(__fest_context,"' + escapeJS(_getAttr(node, 'value')) + '");';
}
}
return;

@@ -471,5 +511,11 @@ case 'comment':

output.disable_sgo = true;
} else {
section.source += '__fest_select="' + escapeJS(_getAttr(node, 'name')) + '";';
output.uses[_getAttr(node, 'name')] = true;
} else{
var expression = compileExpr(node.attributes.name, _getExpr);
if (expression.containsExpr){
section.source += 'try{__fest_select=' + expression.text + '}catch(e){__fest_select="";__fest_log_error(e.message)}';
output.disable_sgo = true;
} else{
section.source += '__fest_select="' + escapeJS(_getAttr(node, 'name')) + '";';
output.uses[_getAttr(node, 'name')] = true;
}
}

@@ -548,2 +594,5 @@ section.source += '__fest_params={};';

section.source += '__fest_pushstr(__fest_context,"\\"");';
if(node.conditional){
section.source += '}';
}
return;

@@ -550,0 +599,0 @@ case 'cdata':

2

package.json

@@ -5,3 +5,3 @@ {

"keywords": ["template", "templating", "html", "xml"],
"version": "0.7.3",
"version": "0.8.0",
"repository": {

@@ -8,0 +8,0 @@ "type": "git",

@@ -1,8 +0,114 @@

# Fest [![Build Status](https://travis-ci.org/eprev/fest.png?branch=0.7)](https://travis-ci.org/eprev/fest)
# Fest [![Build Status](https://travis-ci.org/mailru/fest.png?branch=0.8)](https://travis-ci.org/mailru/fest)
Fest — это шаблонизатор общего назначения, компилирующий XML шаблоны в самодостаточные JavaScript функции. Для установки требуется Node.js >= 0.8.
## Установка
```
npm install fest
```
## Введение
Шаблоны представляют собой XML документы, содержащие HTML, текстовые данные и управляющие конструкции. Шаблон задается парным элементом `<fest:template>` (с указанием пространства имен `http://fest.mail.ru`). Например:
```xml
<fest:template xmlns:fest="http://fest.mail.ru">
Hello!
</fest:template>
```
Данные передаваемые в шаблон, доступны через переменную с именем, указанным в атрибуте `context_name` элемента `fest:template`:
```xml
<fest:template xmlns:fest="http://fest.mail.ru" context_name="json">
Hello, <fest:value>json.name</fest:value>!
</fest:template>
```
Чтобы посмотреть результат работы, приведенных выше шаблонов, необходимо воспользоваться встроенной утилитой fest-render или API библиотеки.
### fest-render
Утилита `fest-render` используется для компиляции и последующего запуска скомпилированного шаблона из командной строки. В таком случае, для передачи данных в шаблон используется JSON-файл.
hello.json
```json
{"name": "John"}
```
hello.xml
```xml
<fest:template xmlns:fest="http://fest.mail.ru" context_name="json">
Hello, <fest:value>json.name</fest:value>!
</fest:template>
```
```
$ ./node_modules/.bin/fest-render --json=hello.json hello.xml
Hello,John!
```
_Замечание: начальные и конечные пробелы в текстовых узлах удаляются при компиляции. Если необходимо вывести символ пробела, можно вопспользоваться `fest:space`._
### render()
Функция `render()` API компилирует и исполняет шаблон с заданными параметрами.
hello.js
```javascript
var fest = require('fest');
console.log(fest.render('hello.xml'), {name: 'John'});
```
```
$ node ./hello.js
Hello,John!
```
## Данные и вывод
### fest:value
Служит для вывода значения JavaScript выражения. Поддерживаем 4 режима вывода: html (по умолчанию), text, js и json.
```xml
<fest:script><![CDATA[
var value = '"<script/>"';
]]></fest:script>
<fest:value>value</fest:value><!-- &quot;&lt;script/&gt;&quot; -->
<fest:value output="text">value</fest:value><!-- "<script/>" -->
<fest:value output="js">value</fest:value><!-- \"\u003Cscript\/\u003E\" -->
<fest:value output="json">value</fest:value><!-- "\"\u003Cscript/\u003E\"" -->
```
### fest:var
Устаналивает локальную JavaScript переменную.
```xml
<fest:var name="question">Ultimate Question of Life, The Universe, and Everything</fest:value>
<fest:value>question</fest:value><!-- Ultimate Question of Life, The Universe, and Everything -->
<fest:var name="answer" select="question.length - 13" />
<fest:value>answer</fest:value><!-- 42 -->
```
### fest:text
Выводит неформатированный текст.
```xml
<fest:text>"Hello"</fest:text><!-- "Hello" -->
```
### fest:space
Служит для вывода пробела. Необходим в тех случаях, когда пробел в тектовом узле удаляется при компиляции, например:
```xml
Hello,<fest:space/><fest:value>json.name</fest:value>!<!-- Hello, John! -->
```
### fest:set
Объявить внутреннюю переменную
Объявляет именованный подшаблон. Содержимое `fest:set` не будет выполнено до тех пор, пока не будет вызван блок с таким же имененем с помощью `fest:get`.

@@ -15,7 +121,7 @@ ```xml

<fest:set name="full_name">
<fest:get name="name"/><fest:space/>F. Kennedy
<fest:get name="name"/><fest:space/>F. Kennedy
</fest:set>
```
Для ```fest:set``` можно использовать атрибут ```test```. Операция выполнится, если его значение (js-выражение) истинно.
Для `fest:set` можно использовать атрибут `test`. Операция выполнится, если его значение (JavaScript выражение) истинно.

@@ -26,9 +132,9 @@ ```xml

Внутри ```fest:set``` доступен контекст ```params```, передаваемый через ```fest:get```.
Внутри `fest:set` доступен контекст `params`, передаваемый через `fest:get`.
```xml
<fest:set name="line">
Hello,<fest:space/><fest:value>params.username</fest:value>
Hello,<fest:space/><fest:value>params.username</fest:value>!
</fest:set>
<fest:get name="line">{username: "John"}</fest:get>
<fest:get name="line">{username: "John"}</fest:get><!-- Hello, John! -->
```

@@ -38,3 +144,3 @@

Получить переменную, объявленную через ```fest:set```
Выводит содержимое блока, объявленного через `fest:set`.

@@ -49,29 +155,31 @@ ```xml

Через `fest:param` можно передавать в блок XML-данные:
С помощью `fest:param` можно передавать в блок XML-данные.
```xml
<fest:get name="page">
<fest:param name="doctype">html</fest:param>
<fest:params>
{
title: json.title
}
</fest:params>
<fest:param name="content">
<article>
<fest:if test="json.title">
<h1><fest:value>json.title</fest:value></h1>
</fest:if>
</article>
</fest:param>
<fest:param name="doctype">html</fest:param>
<fest:params>
{
title: json.title
}
</fest:params>
<fest:param name="content">
<article>
<fest:if test="json.title">
<h1><fest:value>json.title</fest:value></h1>
</fest:if>
</article>
</fest:param>
</fest:get>
<fest:set name="page">
<fest:doctype><fest:value>params.doctype</fest:value></fest:doctype>
<title><fest:value>params.title</fest:value></title>
<body>
<fest:value output="text">params.content</fest:value>
</body>
<fest:doctype><fest:value>params.doctype</fest:value></fest:doctype>
<title><fest:value>params.title</fest:value></title>
<body>
<fest:value output="text">params.content</fest:value>
</body>
</fest:set>
```
Если указать тег select, то выражение внутри выполнится и результирующая строка будет именем блока set.
Внутри атрибута `name` можно использовать JavaScript выражения для вычисления имени блока во время выполнения. Значения выражений, заключенных в фигурные скобки, объединяются с примыкающим текстом. Помимо этого, можно использовать атрибут `select`.
```xml

@@ -81,5 +189,6 @@ <fest:script>

</fest:srcipt>
<fest:get select="name"/>
<fest:get select="name"/><!-- foo -->
<fest:set name="foo">foo</fest:set>
<fest:set name="bar">bar</fest:set>
<fest:get name="b{true?'a':''}r"/><!-- bar -->
```

@@ -89,5 +198,6 @@

Вывод ноды с переменным именем
Выводит HTML элемент с переменным именем.
```xml
<fest:element name="div" />
<fest:script>

@@ -99,3 +209,3 @@ var variable = 'table';

</fest:element>
<fest:element select="variable2">
<fest:element name="{variable2}">
fest code

@@ -105,6 +215,6 @@ </fest:element>

Выведет
Результат:
```xml
<table>fest code</table><div>fest code</div>
<div></div><table>fest code</table><div>fest code</div>
```

@@ -114,14 +224,14 @@

Добавить атрибуты к родительскому тегу. Все ```fest:attribute``` должны быть внутри блока ```fest:attributes```, который должен быть первым внутри тега.
Добавляет атрибуты к родительскому элементы. Все `fest:attribute` должны быть внутри блока `fest:attributes`, который должен идти первым внутри элемента.
```xml
<a>
<fest:attributes>
<fest:attribute name="href"><fest:value>json.href</fest:value></fest:attribute>
</fest:attributes>
Some link
<fest:attributes>
<fest:attribute name="href"><fest:value>json.href</fest:value></fest:attribute>
</fest:attributes>
Some link
</a>
```
Быстрый способ вставить значение в атрибут
Существует быстрый способ вывести значение в атрибут:

@@ -132,36 +242,12 @@ ```xml

### fest:value
Имена атрибутов можно вычислять в момент исполнения шаблона:
Вывести значение js-выражения
```xml
<fest:value>json.value</fest:value>
<fest:value output="text"><![CDATA["<script/>"]]></fest:value>
<fest:value output="js">'"'</fest:value>
<div>
<fest:attributes>
<fest:attribute name="data-{json.name}" value="{json.value}" />
</fest:attributes>
</div>
```
### fest:var
Установить js-переменную
```xml
<fest:var name="question">Ultimate Question of Life, The Universe, and Everything</fest:value>
<fest:value>question</fest:value>
<fest:var name="answer" select="question.length - 13" />
<fest:value>answer</fest:value>
```
### fest:text
Вывод неформатированного текста
```xml
<fest:text>"Bla bla bla"</fest:text>
```
### fest:space
Пробел
## Управляющие конструкции

@@ -171,3 +257,3 @@

Итерация по объекту
Предоставляет механизм итерации по объекту.

@@ -177,6 +263,6 @@ ```xml

<fest:each iterate="obj" index="i">
<fest:value>i</fest:value>=<fest:value>obj[i]</fest:value>
<fest:value>i</fest:value>=<fest:value>obj[i]</fest:value><!-- foo=bar -->
</fest:each>
<fest:each iterate="obj" index="i" value="v">
<fest:value>i</fest:value>=<fest:value>v</fest:value>
<fest:value>i</fest:value>=<fest:value>v</fest:value><!-- foo=bar -->
</fest:each>

@@ -187,3 +273,3 @@ ```

Итерация по массиву или по числовому ряду
Выполняет итерацию по массиву или числовому ряду.

@@ -193,9 +279,9 @@ ```xml

<fest:for iterate="json.items" index="i">
<fest:value>json.items[i]</fest:value>
<fest:value>json.items[i]</fest:value><!-- abc -->
</fest:for>
<fest:for iterate="json.items" index="i" value="v">
<fest:value>v</fest:value>
<fest:value>v</fest:value><!-- abc -->
</fest:for>
<fest:for from="1" to="5" index="i">
<fest:value>i</fest:value>
<fest:value>i</fest:value><!-- 12345 -->
</fest:for>

@@ -206,7 +292,7 @@ ```

Условный оператор
Условный оператор.
```xml
<fest:if test="true">
true
It's true!
</fest:if>

@@ -217,31 +303,31 @@ ```

Ветвление. Если ни один ```fest:when``` не выполнен, будет выбрана ветвь ```fest:otherwise```.
Ветвление. Если ни у одного `fest:when` условие не выполнено, будет выбрана ветвь `fest:otherwise`.
```xml
<fest:choose>
<fest:when test="1">
<fest:text>one</fest:text>
</fest:when>
<fest:when test="1">
<fest:text>one</fest:text>
</fest:when>
<fest:when test="2">
<fest:text>two</fest:text>
</fest:when>
<fest:when test="2">
<fest:text>two</fest:text>
</fest:when>
<fest:otherwise>
<fest:text>More than 2</fest:text>
</fest:otherwise>
<fest:otherwise>
<fest:text>More than 2</fest:text>
</fest:otherwise>
</fest:choose>
```
## Остальное
## Остальные конструкции
### fest:cdata
Блок CDATA
Служит для вывода блока CDATA.
```xml
<script>
<fest:cdata>
<![CDATA[alert ("2" < 3);]]>
</fest:cdata>
<fest:cdata>
<![CDATA[alert ("2" < 3);]]>
</fest:cdata>
</script>

@@ -252,3 +338,3 @@ ```

HTML комментарий
Выводит HTML комментарий.

@@ -261,3 +347,3 @@ ```xml

Объявление doctype страницы
Задает DOCTYPE генерируемой страницы.

@@ -270,12 +356,14 @@ ```xml

Выполнить javascript
Служит для выполнения произвольного JavaScript.
```xml
<fest:script>
<![CDATA[
json.script = 2 < 3;
]]>
<![CDATA[
json.script = 2 < 3;
]]>
</fest:script>
```
Содержимое `fest:script` можно загрузить из файла, указав в атрибуте `src` путь к нему.
```xml

@@ -287,3 +375,3 @@ <fest:script src="script.js"/>

Вставить содержимое другого шаблона с заданным контекстом.
Вставляет содержимое другого шаблона с заданным контекстом.

@@ -297,7 +385,7 @@ ```xml

Вставить файл напрямую в шаблон
Выводит содержимое файла:
```xml
<style type="text/css">
<fest:insert src="style.css"/>
<fest:insert src="style.css"/>
<style>

@@ -308,12 +396,5 @@ ```

## Установка
## Использование
```
npm install fest
```
## Как использовать
compile():
Компиляция с помощью compile():
```javascript

@@ -331,4 +412,3 @@ var fest = require('fest');

render():
Компиляция с последующей отрисовкой с помощью render():
```javascript

@@ -343,19 +423,16 @@ var fest = require('fest');

basic.xml
```xml
<?xml version="1.0"?>
<fest:template xmlns:fest="http://fest.mail.ru" context_name="json">
<h1>Hello,<fest:space/><fest:value output="text">json.name</fest:value></h1>
<!-- По умолчанию все значения fest:value экранируются -->
<!--
Необходимо использовать fest:space или
fest:text для явного указания строк с пробелами
-->
<h1>Hello,<fest:space/><fest:value output="text">json.name</fest:value></h1>
<!-- По умолчанию все значения fest:value экранируются -->
<!--
Необходимо использовать fest:space или
fest:text для явного указания строк с пробелами
-->
</fest:template>
```
Результат
Результат:

@@ -368,18 +445,15 @@ ```html

Данные на вход
Данные на вход:
```javascript
var data = {
people: [
{name: 'John', age: 20},
{name: 'Mary', age: 21},
{name: 'Gary', age: 55}
],
append: '>>'
people: [
{name: 'John', age: 20},
{name: 'Mary', age: 21},
{name: 'Gary', age: 55}
],
append: '>>'
}
```
foreach.xml (основной шаблон)
foreach.xml (основной шаблон):
```xml

@@ -394,11 +468,9 @@ <?xml version="1.0"?>

<fest:for iterate="json.people.reverse()" index="i">
<!-- Передаваемые значения будут доступны в контексте params -->
<fest:get name="person">json.people[i]</fest:get>
</fest:for>
<!-- Передаваемые значения будут доступны в контексте params -->
<fest:get name="person">json.people[i]</fest:get>
</fest:for>
</fest:template>
```
person.xml
person.xml:
```xml

@@ -408,25 +480,23 @@ <?xml version="1.0"?>

<!--
Используем set для объявления переменной,
которую используем в родительском шаблоне
-->
<fest:set name="person">
<p>
<fest:script><![CDATA[
var first = params.name[0],
other = params.name.slice(1);
]]></fest:script>
<fest:value>json.append</fest:value>
<strong>
<fest:value>first</fest:value>
</strong>
<fest:value>other</fest:value>
</p>
</fest:set>
<!--
Используем set для объявления блока,
который используем в родительском шаблоне
-->
<fest:set name="person">
<p>
<fest:script><![CDATA[
var first = params.name[0],
other = params.name.slice(1);
]]></fest:script>
<fest:value>json.append</fest:value>
<strong>
<fest:value>first</fest:value>
</strong>
<fest:value>other</fest:value>
</p>
</fest:set>
</fest:template>
```
Результат
Результат:
```html

@@ -443,42 +513,42 @@ <p>&gt;&gt;<strong>G</strong>ary</p>

<fest:template xmlns:fest="http://fest.mail.ru" context_name="json">
<fest:set name="host">http://e.mail.ru</fest:set>
<fest:set name="all">msglist</fest:set>
<fest:set name="new">sentmsg?compose</fest:set>
<fest:set name="host">http://e.mail.ru</fest:set>
<fest:set name="all">msglist</fest:set>
<fest:set name="new">sentmsg?compose</fest:set>
<fest:set name="all_link">
<fest:get name="host"/>/<fest:get name="all"/>
</fest:set>
<fest:set name="all_link">
<fest:get name="host"/>/<fest:get name="all"/>
</fest:set>
<fest:set name="new_link">
<fest:get name="host"/>/<fest:get name="new"/>
</fest:set>
<fest:set name="new_link">
<fest:get name="host"/>/<fest:get name="new"/>
</fest:set>
<ul>
<!-- fest:attribute добавляет параметр к родительскому тегу -->
<ul>
<!-- fest:attribute добавляет параметр к родительскому тегу -->
<li><a>
<fest:attributes>
<fest:attribute name="href"><fest:get name="all_link"/></fest:attribute>
</fest:attributes>
Все сообщения
</a></li>
<li><a>
<fest:attributes>
<fest:attribute name="href"><fest:get name="all_link"/></fest:attribute>
</fest:attributes>
Все сообщения
</a></li>
<li><a>
<fest:attributes>
<fest:attribute name="href"><fest:get name="new_link"/></fest:attribute>
</fest:attributes>
Написать письмо
</a></li>
</ul>
<li><a>
<fest:attributes>
<fest:attribute name="href"><fest:get name="new_link"/></fest:attribute>
</fest:attributes>
Написать письмо
</a></li>
</ul>
</fest:template>
```
Результат
Результат:
```html
<ul>
<li><a href="http://e.mail.ru/msglist">Все сообщения</a></li>
<li><a href="http://e.mail.ru/sentmsg?compose">Написать письмо</a></li>
<li><a href="http://e.mail.ru/msglist">Все сообщения</a></li>
<li><a href="http://e.mail.ru/sentmsg?compose">Написать письмо</a></li>
</ul>
```
## Интернационализация

@@ -485,0 +555,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc