https://github.com/B-Vladi/TSN/
Templating System for Node.JS.
MIT: https://github.com/appendto/amplify/blob/master/MIT-LICENSE.txt
TSN - синхронный шаблонизатор, реализован в виде модуля для NodeJS.
Зависимости:
Основные характеристики:
- Простота - управляющие конструкции имеют стандартный XML-синтаксис. Выражения, используемые в значениях атрибутов тегов TSN, являются JavaScript-выражениями.
- Скорость - тест производительности показывает, что TSN быстрее похожего шаблонизатора Fest от Mail.ru, который в свою очередь быстрее известного шаблонизатора CTPP. Так же TSN выигрывает в производительности Dust, но этот тест не сохранился.
- Гибкость шаблонов - достигается за счет подключаемых шаблонов, динамического контекста и многого другого.
- Расширяемость - реализация логики тегов вынесена в отдельный файл, в который легко можно добавлять собственные теги, используя API TSN. В скором будущем появится соответствующая страница в wiki.
- Поддержка IDE - благодаря XML-синтаксису управляющих конструкций шаблонизатора, можно использовать приемущества редакторов кода, как то: подсветка синтаксиса и Zen Coding. Так же легко настроить валидацию и автокомплит, если IDE поддерживает подключение пользовательских DTD-файлов. В этом случае достаточно настроить IDE на использование DTD-файла тегов TSN и объявить префикс пространства имен в шаблоне.
###Конфигурация парсинга шаблонов. В вики: https://github.com/B-Vladi/TSN/wiki/Configuration
###Инициализация.
var TSN = require('TSN');
###Примеры компиляции шаблона. Компиляция из файла:
var template = TSN.load('path/to/template.xml'); // Компиляция относительно TSN.config.templateRoot.
Использование имени шаблона:
var template = TSN.load('path/to/template.xml', 'My name');
console.log(template.cacheName === 'My name'); // true
console.log(TSN.cache['My name'] === template); // true
Компиляция шаблона с использованием собственных настроек. Параметры, которые не были указаны в этом объекте, будут унаследованы от TSN.config
.
var template = TSN.load('path/to/template.xml', null, {
templateRoot: 'path/to/new/template/root'
});
Компиляция шаблона из данных:
TSN.compile('<tsn:root xmlns:tsn="TSN">Text data</tsn:root>');
###Примеры рендеринга шаблона.
С использованием API:
var result = TSN.render(template, data);
Без использования:
var result = template.call(data);
Запись результата в поток:
template.call(data, response);
Документация по API находится в вики: https://github.com/B-Vladi/TSN/wiki/API.
Так же вы можете сгенерировать JSDoc документацию по API из исходников (файл TSN.js).
###Контекст данных.
В JavaScript-выражениях, используемых в значениях атрибутов тегов TSN, переданные данные доступны в виде контекста через ключевое слово this.
Если TSN тег влияет на контекст, это затрагивает только его дочерних элементов.
###Теги
Управляющие конструкци TSN-шаблона представляют собой XML-теги с префиксом пространства имен TSN
. Префикс может использоваться любой и настраивается в конфигурационном файле, либо через API.
TSN-парсер не учитывает XML-окружение, поэтому явно регистрировать префикс для постранства имен TSN
не обязательно, но рекоммендуется для комфортной работы в IDE.
В значениях атрибутов тегов TSN могут использоваться следующие XML-сущности: & < > " '
.
Описание тегов с примерами использования в вики: https://github.com/B-Vladi/TSN/wiki/Tags
###Пример Web-приложения Файл page_name.xml:
<?xml version="1.0"?>
<tsn:root xmlns:tsn="TSN"
xmlns="http://www.w3.org/1999/xhtml">
<!-- Формирование контента для тега head -->
<tsn:template name="head">
<link type="text/css"
rel="stylesheet"
href="/page.css" />
</tsn:template>
<!-- Сохранение данных в области видимости этого шаблона -->
<tsn:data name="GET"
value="this.request.GET" />
<!-- Формирование контента для тега body -->
<tsn:template name="body">
<!-- Вывод GET-параметра userName -->
<h2>Hello, <tsn:echo data="_data.GET.userName"
escape="html" />!
</h2>
</tsn:template>
<!-- Добавление контента перед закрывающим тегом body -->
<tsn:template name="footer">
<script type="text/javascript"
src="page.js"></script>
</tsn:template>
<!-- Вставка базоваого шаблона разметки и формирование данных,
которые будут для него контекстом -->
<tsn:include src="/base.xml"
context="({
title: 'My name',
navigation: this.navigation,
request: {
status: 200
}
})" />
</tsn:root>
Файл base.xml:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<tsn:root xmlns:tsn="TSN">
<head>
<!-- Формирование заголовка страницы -->
<title>
<tsn:echo data="this.title" /> - Hostname
</title>
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8" />
<!-- Общие стили -->
<link type="text/css"
rel="stylesheet"
href="/base.css" />
<!-- Стили для конкретной страницы -->
<tsn:include name="head" />
</head>
<body>
<div class="wrapper">
<!-- Шапка -->
<tsn:include src="/header.xml"
context="this.navigation" />
<!-- Если статус 200... -->
<tsn:if test="this.request.status == 200">
<!-- ...вставляем унаследованный контент страницы -->
<tsn:include name="body" />
<tsn:else />
<!-- ...иначе вставляем страницу ошибки -->
<tsn:include src="/error.xml" context="this.request.status" />
</tsn:if>
</div>
<!-- Подключение скриптов для текущей страницы -->
<tsn:include name="footer" />
</body>
</tsn:root>
</html>
JavaScript-код приложения:
/* Подключение зависимостей */
var http = require('http');
var queryString = require('querystring');
var TSN = require('TSN');
/* Уберём комментарии из результата */
TSN.config.saveComments = false;
/* Компиляция шаблона */
TSN.load('page_name.xml', 'page_name', {
indent: 4
});
/* Создание сервера */
http.Server(
function (request, response) {
/* Формирование данных для рендеринга */
var data = {
request: {
GET: queryString.parse(request.url.substring(2))
}
};
/* Рендеринг шаблона с записью результата в поток */
TSN.cache['page_name'].call(data, response);
}).listen(80, '127.0.0.1');
Запрос:
http://127.0.0.1/?userName=Vasya
Результат: ```html <title>My name - Hostname </title>
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8" />
<link type="text/css"
rel="stylesheet"
href="/base.css" />
По всем вопросам отвечу по почте: b-vladi@cs-console.ru.