New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

small-tpl

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

small-tpl

A small lightweight but powerful template engine.

latest
Source
npmnpm
Version
3.0.2
Version published
Maintainers
1
Created
Source

small-tpl

A small lightweight but powerful template engine.

Install:npm install small-tpl or yarn add small-tpl

模板语法

<? 开始标签

?> 结束标签

each 遍历数组

endeach 结束遍历

echo 在JS脚本里输出数据

$data 模板内嵌变量,渲染模板的数据对象

$fn 模板内嵌变量,渲染模板的helper对象

$encodeChars 模板内嵌变量,输出内容时需要编码的字符,默认包含4个字符<>"'

$encode 模板内嵌函数,输出内容时对内容进行编码

$indent 模板内嵌函数,输出内容时对内容保持当前缩进量

$item 模板内嵌变量,遍历数组时指向当前数组元素

$i 模板内嵌变量,遍历数组时指向当前数组元素的下标

$count 模板内嵌变量,遍历数组时指向当前数组的长度

= 在“each”外时输出$data对象的属性,在“each”里时输出$item对象的属性;属性值为null或undefined时输出空字符串

=: 与“=”相似,区别在于会用$encode编码内容

=] 与“=”相似,区别在于会用$indent保持当前缩进量

+ 直接字符串连接整个语句块,不做任何处理

API

  • compile(template, [options])

    编译模板字符串为渲染函数。

    options有3个选项:openTag自定义开始标签;closeTag自定义结束标签;uglify是否去除HTML里无用的空白字符,默认true去除。

  • setTag(openTag, closeTag)

    全局设置开始标签和结束标签。

Demo

Hello world

const { compile } = require('small-tpl')

// for pure Object
const render = compile('<?= hello ?>, <?= name ?>!')
render({hello: 'Hello', name: 'girl'})
// => Hello, girl!

// for Array
const render = compile('<?+ $data[0] ?>, <?+ $data[1] ?>!')
render(['Hello', 'girl'])
// => Hello, girl!

标签内可以使用原生JS语法:

<div>
<? if ($data.someProp) { ?>
  <h1>哈哈哈</h1>
<? } else { ?>
  <i>嘿嘿嘿</i>
<? } ?>
</div>

JS代码内可以使用echo语句,上面的代码等同于:

<div>
<?
  if ($data.someProp) {
    echo '<h1>哈哈哈</h1>' // 也可以写成 echo('<h1>哈哈哈</h1>')
  } else {
    echo '<i>嘿嘿嘿</i>'
  }
?>
</div>

三目运算:

<h1><?+ ($data.someProp ? '哈哈哈' : '嘿嘿嘿') ?></h1>

遍历数组:

<h1><?= title ?></h1> <!-- 输出 $data.title -->
<ul>
<? each $data.someList ?>
  <li>
    <?= title ?> <!-- 输出 someList 里每一项的 title,即 $item.title -->
  <? if ($item.subTitle) { ?> <!-- $item 指向 someList 的元素 -->
    <span class="sub-title">
      <?+ $fn.encodeXssChar($item.subTitle) ?>
    </span>
  <? } ?>
  </li>
<? endeach ?>
</ul>

特别注意eachendeach只能放在独立的<? ?>标签内,不能跟其他语句同处一个标签内。除了下面这种情况。

在上面的模板中,如果不确定someList这个属性是否存在,可以像下面这样:

<? each $data.someList || [] ?>
  TODO
<? endeach ?>

对输出内容进行编码,预防XSS攻击:

const render = compile('<?=: content ?>')
render({content: '<script>alert("1")</script>'})
// => &lt;script&gt;alert(&quot;1&quot;)&lt;/script&gt;
// 即可在页面上正常显示:<script>alert("1")</script>

扩充默认的$encodeChars,扩充只影响当前模板:

const render = compile(`<? $encodeChars['b'] = 'B' ?><?=: content ?>`)
render({content: 'abc'})
// => aBc

手动调用$encode函数:

const render = compile(`<?+ $encode('Encode: ' + $data.content) ?>`)
render({content: '<b>abc</b>'})
// => Encode: &lt;b&gt;abc&lt;/b&gt;
// 页面上正常显示:Encode: <b>abc</b>

Deep

compile('<p><?= hello ?>, <?= name ?>!</p>')

// 模板将被编译为如下函数
function anonymous($data, $fn) {
  'use strict';
  var $_get = function (data, key) {
    return data[key] || (data[key] == null ? '' : data[key]);
  };
  var echo = '<p>'+ $_get($data, 'hello')+ ', '+ $_get($data, 'name')+ '!</p>';
  return echo
}

compile(`
  <h1><?= title ?></h1>
  <ul>
  <? each $data.someList ?>
    <li>
      <?= title ?>
    </li>
  <? endeach ?>
  </ul>
`)

// 模板将被编译为如下函数
function anonymous($data, $fn) {
  'use strict';
  var $_get = function (data, key) {
    return data[key] || (data[key] == null ? '' : data[key]);
  };
  var echo = '<h1>'+ $_get($data, 'title')+ '</h1><ul>';
  ~function () {
    var $_list = $data.someList, $count = $_list.length, $i = 0, $item;
    for (; $i < $count; $i++) {
      $item = $_list[$i];
      echo += '<li>'+ $_get($item, 'title')+ '</li>'
    }
  }();
  echo += '</ul>';
  return echo
}

compile('<p><?=: content ?></p>')

// 模板将被编译为如下函数
function anonymous($data, $fn) {
  'use strict';
  var $_get = function (data, key) {
    return data[key] || (data[key] == null ? '' : data[key]);
  };
  var $encodeChars = {
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#39;'
  };
  var $encode = function (s) {
    if (typeof s === 'string') {
      var res = '', i = 0, l = s.length;
      for (; i < l; i++) {
        res += $encodeChars[s[i]] || s[i];
      }
      return res;
    }
    return s == null ? '' : s;
  };
  var echo = '<p>'+ $encode($_get($data, 'content'))+ '</p>';
  return echo
}

Keywords

template

FAQs

Package last updated on 08 Feb 2024

Did you know?

Socket

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.

Install

Related posts