npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

cb-template

v1.3.9

Published

唱吧模板引擎

Downloads

15

Readme

cbT.js

npm version Downloads

一个支持模板多级继承的 Node.js 服务端模板引擎

目录

安装

$ npm install cb-template

特性

  • 支持模板继承(Layout)
  • 模块化模板
  • 灵活的模板语法

实例

<% if (user) %>
  <p><%=user.name%></p>
<% /if %>

使用

const cbT = require('cb-template');

const template = cbT.compile(str);
template(data);
// => 已渲染的 HTML 字符串

cbT.render(str, data);
// => 已渲染的 HTML 字符串

// 支持模板继承
cbT.renderFile(filename, data, options, (err, data) => {
  if (!err) {
    // => data 是已渲染的 HTML 字符串
  }
});

选项

cbT.leftDelimiter

定义左分隔符,默认值:<%

cbT.rightDelimiter

定义右分隔符,默认值:%>

cbT.basePath

定义读取模板文件的根目录,默认值为空字符串。

例如你想以 /my/template 为所有模板的根目录,则设置 cbT.basePath = '/my/template'

cbT.cachePath

模板缓存目录,默认值为系统临时目录。

cbT.defaultExtName

模板文件默认扩展名,默认值为 .html

API

cbT.compile(str)

编译模板字符串,返回模板函数,不支持模板继承。

参数:

  • str: 字符串,输入的模板内容

返回值:

类型:函数,模板函数,用于后续直接渲染模板。

模板函数参数:

  • data: 对象,输入的数据

例子:

const template = cbT.compile(`<title><%=title%></title><p><%=nickname%></p>`);
template({ title: '标题', nickname: '昵称' });
// => 已渲染的 HTML 字符串

cbT.compileFile(filename, options, callback)

读取模板文件,返回模板函数,支持模板继承。

参数:

  • filename: 字符串,模板文件路径,如果设置了 cbT.basePath 则 basePath 为根目录,建议使用绝对路径。
  • options: 对象,编译参数。
    • cache: 布尔,是否开启编译缓存,默认开启
  • callback: 函数,回调函数,编译完成后回调。
    • 回调函数参数: err: 是否有错误;template: 模板函数

例子:

cbT.compileFile('/your/path/filename.html', {}, (err, template) => {
  template({ title: '标题', nickname: '昵称' });
  // => 已渲染的 HTML 字符串
});

cbT.render(str, data)

编译模板字符串,并返回渲染后的结果,不支持模板继承。

参数:

  • str: 字符串,输入的模板内容
  • data: 对象,用于渲染的数据,对象的 key 会自动转换为模板中的变量名

返回值:

类型:字符串,已渲染的字符串

例子:

cbT.render(`<title><%=title%></title><p><%=nickname%></p>`, { title: '标题', nickname: '昵称' });
// => 已渲染的 HTML 字符串

cbT.renderFile(filename, data, options, callback)

读取模板文件,并返回渲染后的结果,支持模板继承。

参数:

  • filename: 字符串,模板文件路径,如果设置了 cbT.basePath 则 basePath 为根目录,建议使用绝对路径。
  • data: 对象,用于渲染的数据,对象的 key 会自动转换为模板中的变量名
  • options: 对象,编译参数。
    • cache: 布尔,是否开启编译缓存,默认开启
    • cacheName: 字符串,设置缓存名称,默认值 changba-template-cache,如果设置过 cbT.cachePath 则此值无效
  • callback: 函数,回调函数,编译完成后回调。
    • 回调函数参数: err: 是否有错误;content: 渲染后的结果

例子:

cbT.renderFile('/your/path/filename.html', { title: '标题', nickname: '昵称' }, {}, (err, content) => {
  console.log(content);
  // => 已渲染的 HTML 字符串
});

cbT.getInstance()

获取模板引擎的一个新实例,一般用于单独设置模板引擎的某个选项,比如单独设置左右分隔符。

例子:

const myInstance = cbT.getInstance();
myInstance.render(`<title><%=title%></title><p><%=nickname%></p>`, { title: '标题', nickname: '昵称' });
// => 已渲染的 HTML 字符串

注意:获取的新实例不能进行 getInstance() 操作,只能从 cbT 中 getInstance()

模板语法

模板默认分隔符为 <% %>,例如:<% block %>

模板继承(Layout)

extends 标签

<% extends 模板路径 %>

例如 <% extends /welcome/test %>

这里指的是从 basePath/welcome/test.html 这个模板继承。

注意:extends 标签必须在模板文件首行首字母位置。另外这个标签不需要结束标签。

block 标签

<% block 名称 %>
  内容...
<% /block %>

在父模板中使用 block 代表定义一个名为“名称”的 block。

在子模板中使用 block 代表替换父模板中同名的 block。

parent 标签

<% block 名称 %>
  <% parent %>

  内容...
<% /block %>

parent 标签只能在 block 标签中使用,功能是把父模板相同 block 名称的内容放到当前 block 中 parent 所在位置。

child 标签

<% block 名称 %>
  <% child %>

  内容...
<% /block %>

child 标签只能在 block 标签中使用,功能是把子模板相同 block 名称的内容放到当前 block 中 child 所在位置。

slot 标签

<% block 名称 %>
  <% slot 插槽名称 %>
    内容
  <% /slot %>

  内容...
<% /block %>

slot 标签只能在 block 标签中使用。

slot 标签是用于在父模板中定义一些插槽位置,子模板会替换父模板相同插槽名称所在位置的内容。

call 标签

<% block 名称 %>
  <% call 其它block名称 %>
    <% slot 插槽名称 %>
      内容
    <% /slot %>
  <% /call %>

  内容...
<% /block %>
<% block 名称 %>
  <% call 其它block名称 slot1="插槽内容1" slot2="插槽内容2" %>
    <% slot 插槽3 %>
      插槽内容3
    <% /slot %>
  <% /call %>

  内容...
<% /block %>

call 用于把当前文件其它 block 名称(支持所有父模板)的内容,替换 call 所在位置的内容。其中 slot 的意义与上节一样,会替换相应的内容。

use 标签

<% block 名称 %>
  <% use 其它block名称 slot1="插槽内容1" slot2="插槽内容2" %>

  内容...
<% /block %>

use 是简化版的 call

实例

父模板 parent.html:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Welcome to <% block title %>测试标题<% /block %></title>
</head>
<body>
  <h1>Welcome to <% block name %>测试内容<% /block %>!</h1>
  <p>
    <% block test-1 %>
      测试内容-1
    <% /block %>
  </p>

  <p>
    <% block test-2 %>
      <small><% child %></small>
      测试内容-2
    <% /block %>
  </p>
</body>
</html>

子模板 welcome.html:

<% extends parent %>

<% block title %>子模板标题<% /block %>

<% block name %><strong>子模板内容</strong><% /block %>

<% block test-1 %>
  <% parent %>
  <strong>子模板内容-1</strong>
<% /block %>

<% block test-2 %>
  子模板内容-2
<% /block %>

最终渲染成:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Welcome to 子模板标题</title>
</head>
<body>
  <h1>Welcome to <strong>子模板内容</strong>!</h1>
  <p>
    测试内容-1
    <strong>子模板内容-1</strong>
  </p>

  <p>
    <small>子模板内容-2</small>
    测试内容-2
  </p>
</body>
</html>

其他语法

转义后输出变量内容

进行 HTML 转义后输出变量内容,可确保没有 XSS 安全问题。

基本用法:<%=变量%>

例子:

<title><%=title%></title>
<p><%=nickname%></p>

不转义输出变量内容

原样输出变量内容,除非你知道自己在做什么,否则不要使用,会有 XSS 安全问题。

基本用法:<%:=变量%><%-变量%>

例子:

<title><%:=title%></title>
<p><%-nickname%></p>

URL 转义输出变量内容

对变量做 URL 转义,一般用于 URL 传参中。

基本用法:<%:u=变量%>

例子:

<a href="https://domain.com/index?title=<%:u=title%>&nickname=<%:u=nickname%>">链接</a>

转义 HTML 属性值后输出变量内容

进行 HTML 属性值的转义输出,一般用于 HTML 属性值的安全输出。

基本用法:<%:v=变量%>

例子:

<div data-title="<%:v=title%>" data-nickname="<%:v=nickname%>">内容</div>

转义输出数组

迭代数组并做 HTML 转义输出。

基本用法:<%:a=数组变量 | 分隔符%>

分隔符可不写,默认值为 <br>

例子:

<div><%:a=listing%></div> <!-- 输出 <div>元素0<br>元素1<br>元素2<div> -->
<div><%:a=listing | ,%></div> <!-- 输出 <div>元素0,元素1,元素2<div> -->

格式化钱数

四舍五入保留两位小数输出变量内容。

基本用法:<%:m=变量%>

例子:

<div><%:m=money%></div>

内容截取

截取内容后输出变量,如果被截断自动在末尾添加 ...,否则不添加。

基本用法:<%:s=变量 | 保留字数%>

例子:

<div><%:s=title | 10%></div>

URL 协议自适应

把 URL 处理成协议自适应格式,类似 //domian.com/index

基本用法:<%:p=变量%>

例子:

<img src="<%:p=avatar%>" alt="头像">

转义输出函数返回值

用于转义输出函数返回值。

基本用法:<%:func=函数%>

例子:

<p><%:func=getData()%></p>

不转义输出函数返回值

不转义输出函数返回值,慎用。

基本用法:<%:func-函数%>

例子:

<p><%:func-getData()%></p>

定义变量

用于在模板作用域中定义变量。

基本用法:<% let 变量名 = 变量值 %>

例子:

<% let myData = '123' %>
<p><%=myData%></p>

遍历数组

一般用于循环输出数组内容。

基本用法:

  • <% foreach (循环变量 in 数组变量) %>循环体<% /foreach %>
  • <% foreach (循环变量 in 数组变量) %>循环体<% foreachelse %>数组为空时的内容<% /foreach %>

如果需要获取数组下标,可以使用 循环变量Index 的形式获取。

例子:

<ul>
  <% foreach (item in listing) %>
  <li><%=itemIndex%>: <%=item.nickname%></li>
  <% foreachelse %>
  <li>暂无内容</li>
  <% /foreach %>
</ul>

条件输出

用于根据不同条件输出不同内容

基本用法:

  • <% if (标准 js 条件表达式) %>条件为真时输出<% else %>条件为假时输出<% /if %>
  • <% if (标准 js 条件表达式) %>本条件为真时输出<% elseif (标准 js 条件表达式) %>本条件为真时输出<% else %>条件都不符合时输出<% /if %>

例子:

<div>
  <% if (nickname === 'name1') %>
    <p>这是 name1</p>
  <% elseif (nickname === 'name2') %>
   <p>这是 name2</p>
  <% elseif (nickname === 'name3') %>
    <p>这是 name3</p>
  <% else %>
    <p>都不是</p>
  <% /if %>
</div>

定义子模板

一般用于定义一个公共的模板部分,以方便重复使用

基本用法:<% define 子模板名称(参数) %>子模板内容<% /define %>

其中 参数 为合法变量名,用于在子模板中接收外部参数

例子:

<% define mySubTemplate(params) %>
 <p><%=params.nickname%></p>
 <p><%=params.title%></p>
<% /define %>

调用子模板

调用已经定义的子模板

基本用法:<% run 子模板名称(参数对象) %>

例子:

<% run mySubTemplate({ nickname: '昵称', title: '标题' }) %>