
Research
Security News
Malicious PyPI Package Exploits Deezer API for Coordinated Music Piracy
Socket researchers uncovered a malicious PyPI package exploiting Deezer’s API to enable coordinated music piracy through API abuse and C2 server control.
Объявить внутреннюю переменную
<fest:set name="name">John</fest:set>
<fest:set name="full_name">
<fest:get name="name"/><fest:space/>F. Kennedy
</fest:set>
Для fest:set
можно использовать атрибут test
. Операция выполнится, если его значение (js-выражение) истинно.
<fest:set name="name" test="false">should not be set</fest:set>
Внутри fest:set
доступен контекст params
, передаваемый через fest:get
.
<fest:set name="line">
Hello,<fest:space/><fest:value>params.username</fest:value>
</fest:set>
<fest:get name="line">{username: "John"}</fest:get>
Получить переменную, объявленную через fest:set
<fest:get name="name"/>
<fest:get name="name">{'some': 'data'}</fest:get>
Через fest:param
можно передавать в блок 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: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:set>
Если указать тег select, то выражение внутри выполнится и результирующая строка будет именем блока set.
<fest:script>
var name = 'foo'
</fest:srcipt>
<fest:get select="name"/>
<fest:set name="foo">foo</fest:set>
<fest:set name="bar">bar</fest:set>
Вывод ноды с переменным именем
<fest:script>
var variable = 'table';
</fest:script>
<fest:element select="variable">
fest code
</fest:element>
<fest:element select="variable2">
fest code
</fest:element>
Выведет
<table>fest code</table><div>fest code</div>
Добавить атрибуты к родительскому тегу. Все fest:attribute
должны быть внутри блока fest:attributes
, который должен быть первым внутри тега.
<a>
<fest:attributes>
<fest:attribute name="href"><fest:value>json.href</fest:value></fest:attribute>
</fest:attributes>
Some link
</a>
Быстрый способ вставить значение в атрибут
<a href="{json.href}">Some link</a>
Вывести значение js-выражения
<fest:value>json.value</fest:value>
<fest:value output="text"><![CDATA["<script/>"]]></fest:value>
<fest:value output="js">'"'</fest:value>
Установить js-переменную
<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>"Bla bla bla"</fest:text>
Пробел
Итерация по объекту
<fest:script>var obj = {"foo": "bar"}</fest:script>
<fest:each iterate="obj" index="i">
<fest:value>i</fest:value>=<fest:value>obj[i]</fest:value>
</fest:each>
<fest:each iterate="obj" index="i" value="v">
<fest:value>i</fest:value>=<fest:value>v</fest:value>
</fest:each>
Итерация по массиву или по числовому ряду
<fest:script>json.items = ['a', 'b', 'c']</fest:script>
<fest:for iterate="json.items" index="i">
<fest:value>json.items[i]</fest:value>
</fest:for>
<fest:for iterate="json.items" index="i" value="v">
<fest:value>v</fest:value>
</fest:for>
<fest:for from="1" to="5" index="i">
<fest:value>i</fest:value>
</fest:for>
Условный оператор
<fest:if test="true">
true
</fest:if>
Ветвление. Если ни один fest:when
не выполнен, будет выбрана ветвь fest:otherwise
.
<fest:choose>
<fest:when test="1">
<fest:text>one</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:choose>
Блок CDATA
<script>
<fest:cdata>
<![CDATA[alert ("2" < 3);]]>
</fest:cdata>
</script>
HTML комментарий
<fest:comment>comment</fest:comment>
Объявление doctype страницы
<fest:doctype>html</fest:doctype>
Выполнить javascript
<fest:script>
<![CDATA[
json.script = 2 < 3;
]]>
</fest:script>
<fest:script src="script.js"/>
Вставить содержимое другого шаблона с заданным контекстом.
<fest:script>json.list = ['a', 'b', 'c'];</fest:script>
<fest:include context="json.list" src="./include_foreach.xml"/>
Вставить файл напрямую в шаблон
<style type="text/css">
<fest:insert src="style.css"/>
<style>
npm install fest
compile():
var fest = require('fest');
var data = {name: 'Jack "The Ripper"'},
template = './templates/basic.xml';
var compiled = fest.compile(template, {beautify: false}),
template = (new Function('return ' + compiled))();
console.log(template(data));
render():
var fest = require('fest');
var data = {name: 'Jack "The Ripper"'},
template = './templates/basic.xml';
console.log(fest.render(template, data, {beautify: false}));
basic.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 для явного указания строк с пробелами
-->
</fest:template>
Результат
<h1>Hello, Jack "The Ripper"</h1>
Данные на вход
var data = {
people: [
{name: 'John', age: 20},
{name: 'Mary', age: 21},
{name: 'Gary', age: 55}
],
append: '>>'
}
foreach.xml (основной шаблон)
<?xml version="1.0"?>
<fest:template xmlns:fest="http://fest.mail.ru" context_name="json">
<!-- Контекст можно передавать во вложенные шаблоны -->
<fest:include context_name="json" src="./person.xml"/>
<!-- Значением iterate может быть любое js-выражение -->
<fest:for iterate="json.people.reverse()" index="i">
<!-- Передаваемые значения будут доступны в контексте params -->
<fest:get name="person">json.people[i]</fest:get>
</fest:for>
</fest:template>
person.xml
<?xml version="1.0"?>
<fest:template xmlns:fest="http://fest.mail.ru" context_name="json">
<!--
Используем 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>
Результат
<p>>><strong>G</strong>ary</p>
<p>>><strong>M</strong>ary</p>
<p>>><strong>J</strong>ohn</p>
<?xml version="1.0"?>
<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="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>
<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="new_link"/></fest:attribute>
</fest:attributes>
Написать письмо
</a></li>
</ul>
</fest:template>
Результат
<ul>
<li><a href="http://e.mail.ru/msglist">Все сообщения</a></li>
<li><a href="http://e.mail.ru/sentmsg?compose">Написать письмо</a></li>
</ul>
По умолчанию доступна поддержка плюрализации для русского и английского языка. В параметрах fest.compile
можно передать любую другую функцию плюрализации.
<fest:plural select="json.n">один рубль|%s рубля|%s рублей</fest:plural>
Или англоязычный вариант:
<fest:plural select="json.n">one ruble|%s rubles</fest:plural>
Чтобы вывести символ “%” внутри тега fest:plural
используйте “%%”:
<fest:plural select="json.n">…1%%…|…%s%%…|…%s%%…</fest:plural>
Позволяет указать границы фразы для перевода и контекст для снятия многозначности. Например,
<fest:message context="растение">Лук</fest:message>
<fest:message context="оружие">Лук</fest:message>
Для каждого fest:message
, fest:msg
, обычного текста, заключенного между XML тегами (опция auto_message
), или текстового значения некоторых атрибутов компилятор вызывает функцию events.message
(если такая была указана в параметрах). Данный механизм используется в fest-build
утилите для построения оригинального PO-файла.
Пример вызова fest-build
для создания PO-файла:
$ fest-build --dir=fest --po=ru_RU.po --compile.auto_message=true
Пример компиляции локализованных шаблонов:
$ fest-build --dir=fest --translate=en_US.po
Необходимо установить Grunt:
$ git clone git@github.com:mailru/fest.git
$ cd fest
$ sudo npm install -g grunt-cli
$ npm install
$ grunt
Grunt используется для валидации JS (тестов) и запуска тестов. Перед отправкой пулл-риквеста убедись, что успешно выполнены git rebase master
и grunt
.
Если необходимо пересобрать шаблоны spec/expected, то выполните:
$ ./bin/fest-build --dir=spec/templates --exclude=*error* --compile.beautify=true --out=spec/expected/initial
$ ./bin/fest-build --dir=spec/templates --exclude=*error* --compile.beautify=true --out=spec/expected/translated --translate=spec/templates/en_US.po
FAQs
JavaScript Templates
The npm package fest receives a total of 23 weekly downloads. As such, fest popularity was classified as not popular.
We found that fest demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncovered a malicious PyPI package exploiting Deezer’s API to enable coordinated music piracy through API abuse and C2 server control.
Research
The Socket Research Team discovered a malicious npm package, '@ton-wallet/create', stealing cryptocurrency wallet keys from developers and users in the TON ecosystem.
Security News
Newly introduced telemetry in devenv 1.4 sparked a backlash over privacy concerns, leading to the removal of its AI-powered feature after strong community pushback.