small-tpl

    3.0.0 • Public • Published

    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

    Install

    npm i small-tpl

    DownloadsWeekly Downloads

    0

    Version

    3.0.0

    License

    MIT

    Unpacked Size

    14.9 kB

    Total Files

    5

    Last publish

    Collaborators

    • hahaboy