{"id":15765092,"url":"https://github.com/bubkoo/diglett","last_synced_at":"2025-03-31T10:29:43.382Z","repository":{"id":15625699,"uuid":"18362451","full_name":"bubkoo/diglett","owner":"bubkoo","description":"front-end template engine","archived":false,"fork":false,"pushed_at":"2015-01-21T14:08:34.000Z","size":648,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-10-05T12:24:30.009Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bubkoo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-04-02T10:18:20.000Z","updated_at":"2024-08-07T21:58:06.000Z","dependencies_parsed_at":"2022-09-07T01:40:41.136Z","dependency_job_id":null,"html_url":"https://github.com/bubkoo/diglett","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bubkoo%2Fdiglett","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bubkoo%2Fdiglett/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bubkoo%2Fdiglett/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bubkoo%2Fdiglett/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bubkoo","download_url":"https://codeload.github.com/bubkoo/diglett/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246453156,"owners_count":20779903,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-04T12:24:35.496Z","updated_at":"2025-03-31T10:29:43.360Z","avatar_url":"https://github.com/bubkoo.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# diglett\n\n\u003e Diglett 是一个简单的前端（JavaScript）模板引擎，用来将数据和模板组合出最终的 HTML。除了\n除了支持常用的模板语法之外，开发者还可以扩展自己的语法；此外，Diglett 还支持类似 AngularJS\n的过滤器。\n\n- [快速开始](#quick-start)\n  - [引用 Diglett](#add-diglett-script)\n  - [编写模板](#build-template)\n  - [渲染模板](#render-template)\n- [模板语法](#grammar)\n  - [变量替换 {{ 变量 }}](#grammar-placehoder)\n  - [流程控制](#grammar-logic)\n    - [if](#grammar-logic-if)\n    - [if-else](#grammar-logic-if-else)\n    - [if-elseif-else](#grammar-logic-if-elseif-else)\n    - [ifnot](grammar-logic-ifnot)\n  - [循环遍历](#grammar-traverse)\n  - [子模板](#grammar-include)\n  - [模板注释](#grammar-annotation)\n  - [内联](#grammar-inline)\n- [过滤器](#filter)\n - [语法](#filter-grammar)\n - [内置过滤器](#filter-native)\n      - [html HTML 转义](#filter-native-html)\n      - [lowercase 小写](#filter-native-lower)\n      - [uppercase 大写](#filter-native-upper)\n  - [外置过滤器](#filter-ext)\n      - [limitTo 限制字符串或数组的长度](#filter-ext-limitto)\n      - [orderBy 排序](#filter-ext-orderby)\n      - [datetime 格式化日期时间](#filter-ext-datetime)\n      - [number 格式化数字](#filter-ext-number)\n      - [currency 格式化货币](#filter-ext-currency)\n      - [filter](#filter-ext-filter)\n- [API 参考](#api)\n      \n\u003ca name=\"quick-start\" id=\"quick-start\"\u003e\u003c/a\u003e\n## 快速开始\n\n\u003ca name=\"add-diglett-script\" id=\"add-diglett-script\"\u003e\u003c/a\u003e\n### 引用 Diglett\n\n在页面中引入 diglett：\n\n```html\n\u003cscript src=\"src/diglett.js\"\u003e\u003c/script\u003e\n```\n\n也可以通过支持 CMD（[SeaJS](http://seajs.org/)）或 AMD（[RequireJS](http://requirejs.org/)）规范的模块加载器来加载 Diglett。\n\n\u003ca name=\"build-template\" id=\"build-template\"\u003e\u003c/a\u003e\n### 编写模板\n\n使用一个 `type=”text/template”` 的 `script` 标签存放模板：\n\n```html\n\u003cscript id=\"tpl\" type=\"text/template\"\u003e\n\u003ch1\u003e{{ title }}\u003c/h1\u003e\n\u003cul\u003e\n    {{#each list}}\n    \u003cli\u003e条目内容 {{ $index + 1 }} ：{{ $value }}\u003c/li\u003e\n    {{/each}}\n\u003c/ul\u003e\n\u003c/script\u003e\n```\n\n\u003ca name=\"render-template\" id=\"render-template\"\u003e\u003c/a\u003e\n### 渲染模板\n\n指定一个容器来存放渲染后的模板\n\n```html\n\u003cdiv id=\"container\"\u003e\u003c/div\u003e\n```\n准备数据\n\n```js\nvar data = {\n    title: 'Language',\n    list: ['JavaScript', 'C++', 'CSharp', 'Java', 'Python', 'PHP']\n};\n```\n\n渲染模板\n\n```js\nvar html = diglett('#tpl', data);\ndocument.getElementById('container').innerHTML = html;\n```\n\u003ca name=\"grammar\" id=\"grammar\"\u003e\u003c/a\u003e\n## 模板语法\n\n\u003ca name=\"grammar-placehoder\" id=\"grammar-placehoder\"\u003e\u003c/a\u003e\n### 变量替换 {{ 变量 }}\n\n支持简单的变量替换\n\n```js\nvar tpl = 'hello {{ name }} !';\n\nvar data = {\n    name: 'diglett'\n};\n\nvar html = diglett(tpl, data);\n```\n\n\u003ca name=\"grammar-logic\" id=\"grammar-logic\"\u003e\u003c/a\u003e\n### 流程控制\n\n\u003ca name=\"grammar-logic-if\" id=\"grammar-logic-if\"\u003e\u003c/a\u003e\n#### if 语句\n\n```js\nvar tpl = '{{#if title1}} has title1. {{/if}}';\n\nvar data = {\n    title1: 'title',\n    title2: ''\n};\n\nvar html = diglett(tpl, data);\n```\n\n\u003ca name=\"grammar-logic-if-else\" id=\"grammar-logic-if-else\"\u003e\u003c/a\u003e\n#### if-else 语句\n\n```js\nvar tpl = '{{#if title2}} has title2. {{#else}} not has title2. {{/if}}';\n\nvar data = {\n    title1: 'title',\n    title2: ''\n};\n\nvar html = diglett(tpl, data);\n```\n\n\u003ca name=\"grammar-logic-if-elseif-else\" id=\"grammar-logic-if-elseif-else\"\u003e\u003c/a\u003e\n#### if-elseif-else 语句\n\n```js\nvar tpl = '{{#if title2}}'\n            + 'has title2.'\n        + '{{#elseif title1}}'\n            + 'has title1.'\n        + '{{#else}}'\n            + 'not has title.'\n        + '{{/if}}';\n\nvar data = {\n    title1: 'title',\n    title2: ''\n};\n\nvar html = diglett(tpl, data);\n```\n\n\u003ca name=\"grammar-logic-ifnot\" id=\"grammar-logic-ifnot\"\u003e\u003c/a\u003e\n#### ifnot 语句\n\n```js\nvar tpl = '{{#ifnot title2}}'\n            + 'not has title2.'\n        + '{{#else}}'\n            + 'has title2'\n        + '{{/if}}';\n\nvar data = {\n    title1: 'title',\n    title2: ''\n};\n\nvar html = diglett(tpl, data);\n```\n\n\u003ca name=\"grammar-traverse\" id=\"grammar-traverse\"\u003e\u003c/a\u003e\n### 循环遍历\n\n可以对数组和对象进行循环遍历，遍历对象时相当于 `for-in` 循环，而且进行了 `hasOwnProperty` 判断，只会列举本地属性。\n\n最简使用方式 `{{#each list}} ... {{/each}}`，默认会注入 `$value`、`$index`、`$first`、`$last`、`$even` 和 `$odd` 这些变量供循环内部使用：\n\n```js\nvar tpl = '{{#each list}}'\n            + '索引：{{ $index + 1 }}，值：{{ $value }}'\n        + '{{/each}}';\n\nvar data = {\n    list: ['JavaScript', 'C++', 'CSharp', 'Java', 'Python', 'PHP']\n};\n```\n\n指定 value 和 key\n\n```js\nvar tpl = '{{#each as item index}}'\n            + '索引：{{ index + 1 }}，值：{{ item }}'\n        + '{{/each}}';\n\nvar data = {\n    list: ['JavaScript', 'C++', 'CSharp', 'Java', 'Python', 'PHP']\n};\n```\n\n只指定 value\n\n```js\nvar tpl = '{{#each as item}}'\n            + '索引：{{ $index + 1 }}，值：{{ item }}'\n        + '{{/each}}';\n\nvar data = {\n    list: ['JavaScript', 'C++', 'CSharp', 'Java', 'Python', 'PHP']\n};\n```\n\n\u003ca name=\"grammar-include\" id=\"grammar-include\"\u003e\u003c/a\u003e\n### 子模板\n\n- `{{#include subtpl subdata}}`\n\n  `subtpl` 为数据中的模板字符串，`subdata` 为子模板的数据，例如：\n\n  ``` js\n  var data = {\n      subtpl: 'Hello, {{name}}'\n      subdata: {name: 'Diglett'}\n  };\n  ```\n\n- `{{#include '#subtpl' subdata}}`\n\n  `#subtpl` 为定义在页面中的模板的 ID\n\n\u003ca name=\"grammar-annotation\" id=\"grammar-annotation\"\u003e\u003c/a\u003e\n### 模板注释\n\n{{!--这里是注释，将不会被渲染到页面上--}}\n\n\u003ca name=\"grammar-inline\" id=\"grammar-inline\"\u003e\u003c/a\u003e\n### 内联\n\n由于这里的 `{{` 和 `}}` 被当做了语法结构，所以需要在页面上显示 `{{}}` 时需要用内联语法：\n\n`{{// 内联显示}}`\n\n\u003ca name=\"filter\" id=\"filter\"\u003e\u003c/a\u003e\n## 过滤器\n\n\u003ca name=\"filter-grammar\" id=\"filter-grammar\"\u003e\u003c/a\u003e\n### 语法\n\n过滤器的语法结构如下，可以同时指定多个过滤器，可以给过滤器传递参数：\n\n`{{ value | filter1 | filter2:arg1:arg2...  ... }}`\n\n\u003ca name=\"filter-native\" id=\"filter-native\"\u003e\u003c/a\u003e\n### 内置过滤器\n\n\u003ca name=\"filter-native-html\" id=\"filter-native-html\"\u003e\u003c/a\u003e\n#### html\n\n转义 html 标签中的 `\u003c`、`\u003e`、`\"`、`\\` 和 `\u0026`\n\n示例：\n\n```js\nvar tpl = '{{ value | html }}';\nvar data = { value: '\u003cspan\u003e这里是HTML\u003c\\span\u003e' };\n\nvar result = diglett(tpl, data);\n```\n\n\u003ca name=\"filter-native-lower\" id=\"filter-native-lower\"\u003e\u003c/a\u003e\n#### lowercase 转换为全小写\n\n```js\nvar tpl = '{{ value | lowercase }}'\nvar data = { value: 'HELLO WORLD' };\n\nvar result = diglett(tpl, data);\n```\n\n\u003ca name=\"filter-native-upper\" id=\"filter-native-upper\"\u003e\u003c/a\u003e\n#### uppercase 转换为全大写\n\n```js\nvar tpl = '{{ value | uppercase }}'\nvar data = { value: 'hello world' };\n\nvar result = diglett(tpl, data);\n```\n\n\u003ca name=\"filter-ext\" id=\"filter-ext\"\u003e\u003c/a\u003e\n### 外置过滤器\n\n使用外置过滤器前，需要在页面中引入下面三个 JS 文件：\n\n```html\n\u003cscript src=\"currency.js\"\u003e\u003c/script\u003e // 需要使用货币过滤器时引入\n\u003cscript src=\"datetime.js\"\u003e\u003c/script\u003e // 需要日期时间格式化时候引入\n\u003cscript src=\"registerFilter.js\"\u003e\u003c/script\u003e\n```\n\n\u003ca name=\"filter-ext-limitto\" id=\"filter-ext-limitto\"\u003e\u003c/a\u003e\n#### limitTo 限制字符串或数组的长度\n\n限制字符串长度：`{{longStr | limitTo : 4 }}`\n\n限制数组长度：\n\n```txt\n{{#each list | limitTo : 4 as item }}\n\u003cli\u003e{{ item }}\u003c/li\u003e\n{{/each}}\n```\n\n\u003ca name=\"filter-ext-orderby\" id=\"filter-ext-orderby\"\u003e\u003c/a\u003e\n#### orderBy 排序\n\n**简单数组**\n\n```js\nvar data = { arr: [8, 3, 9, 6, 7, 5, 1, 2, 4] };\n```\n\n升序(orderBy:+)：\n\n```html\n{{#each arr as item|orderBy:+}}\n{{item}}\n{{/each}}\n```\n降序(orderBy:-)：\n\n```html\n{{#each arr as item|orderBy:-}}\n{{item}}\n{{/each}}\n```\n**注意：**`+` 表示升序，`-` 表示降序，符号省略时默认为升序\n\n**对象数组**\n\n示例数据：\n```js\nvar data = {\nreverse: true,\nobjArr: [\n\t{name: 'Adam', phone: '555-5678', age: 35},\n    {name: 'Julie', phone: '555-8765', age: 29},\n    {name: 'Mike', phone: '555-4321', age: 21},\n    {name: 'Mike', phone: '555-2321', age: 21},\n    {name: 'Mike', phone: '555-6321', age: 21},\n    {name: 'Mary', phone: '555-9876', age: 19},\n    {name: 'John', phone: '555-1212', age: 10}]\n};\n```\n\n语法：`{{#each objArr as item | orderBy:(+/-)排序的字段1:(+/-)排序字段2...:reverse }}`\n\n**注意：**\n\n1. 排序字段前面的 `+` 和 `-` 分别表示升序和降序，省略时默认为升序\n2. 最后一个参数 `reverse` 为 `true` 时，表示对其紧靠的排序字段进行降序排列，否则进行升序排列\n3. `reverse` 的使用方式[请参看](https://github.com/bubkoo/diglett/blob/master/test/sortable.html)\n\n \n将示例数据按 `name` 升序，`phone` 降序：\n\n```html\n\u003ctable style=\"border:1px solid #ddd\"\u003e\n    \u003ctr\u003e\n        \u003ctd style=\"width: 80px\"\u003e\n            Name\n        \u003c/td\u003e\n        \u003ctd style=\"width: 140px\"\u003e\n            Phone Number\n        \u003c/td\u003e\n        \u003ctd style=\"width: 40px\"\u003e\n            Age\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    {{#each objArr as item | orderBy : name : -phone}}\n    \u003ctr\u003e\n        \u003ctd\u003e{{item.name}}\u003c/td\u003e\n        \u003ctd\u003e{{item.phone}}\u003c/td\u003e\n        \u003ctd\u003e{{item.age}}\u003c/td\u003e\n    \u003c/tr\u003e\n    {{/each}}\n\u003c/table\u003e\n```\n\n\u003ca name=\"filter-ext-datetime\" id=\"filter-ext-datetime\"\u003e\u003c/a\u003e\n#### datetime\n\n`{{ value | datetime:\"yyyy-MM-dd HH:mm:ss\" }}`\n\n参数是时间格式，由于参数中有 `:`，**所以需要将参数放在双引号内**，可以使用如下占位符：\n- `yyyy` - 完整的年份，如 2014\n- `yy` - 短年份，如 14\n- `MMMM` - 长月份名称，如 March\n- `MMM` - 短月份名称，如 Mar，\t\n- `MM` - 月份，不足两位用前置 `0` 补全，如 03\n- `M` - 月份，如 3\n- `dddd` - 长星期名称，如 Sunday\n- `ddd` - 短星期名称，如 Sun\n- `dd` - 一月中的第几天，不足两位用前置 `0` 补全，如 09\n- `d` - 一月中的第几天，如 9\n- `HH` - 24 小时制的小时，不足两位用前置 `0` 补全，如 07\n- `H` - 24 小时制的小时，如 7\n- `hh` - 12 小时制的小时，不足两位用前置 `0` 补全\n- `h` - 12 小时制的小时\n- `mm` - 分钟，不足两位用前置 `0` 补全\n- `m` - 分钟\n- `ss` - 秒，不足两位用前置 `0` 补全\n- `s` - 秒\n- `len` - 毫秒数，保留三位\n- `L` -毫秒数，只保留两位\n- `tt` - 12 小时制中的 \"am\"、\"pm\"\n- `TT` - 12 小时制中的 \"AM\"、\"PM\"\n\n**注意**：月份名称和星期名称可以在引入 `datetime.js` 后，调用 `datetime.options` 来修改\n\n\u003ca name=\"filter-ext-number\" id=\"filter-ext-number\"\u003e\u003c/a\u003e\n#### number\n\n`{{ value | number:precision:grouping:thousand:decimal}}`\n\n参数说明：\n- precision - 浮点数的精度，默认为 `0`\n- grouping - 分组长度，默认为 `3`\n- thousand - 分组的风格符，默认为 `,`\n- decimal - 小数点符号，默认为 `.`\n\n\u003ca name=\"filter-ext-currency\" id=\"filter-ext-currency\"\u003e\u003c/a\u003e\n#### currency\n\n`{{ value | currency:currencySymbol:precision:grouping:thousand:decimal:format}}`\n\n参数说明：\n- currencySymbol - 货币符号，默认为 `$`\n- grouping - 分组长度，默认为 `3`\n- thousand - 分组的风格符，默认为 `,`\n- decimal - 小数点符号，默认为 `.`\n- format - 货币格式，默认为 `%s%v`，%s = 货币符号, %v = 货币值\n\n\u003ca name=\"filter-ext-filter\" id=\"filter-ext-filter\"\u003e\u003c/a\u003e\n#### filter \n\n`{{ objArray | filter:[字段][比较符][值]}}`\n\n参数由三部分构成：字段、比较符、值\n\n支持的比较符：\n- `\u003e` 大于\n- `\u003e=` 大于等于\n- `\u003c` 小于\n- `\u003c=` 小于等于\n- `==` 等于\n- `\u003c\u003e` 不等于\n- `^` 包含\n\n例如：筛选出名字包含 `M` 并且电话包含 `4` 的子数组\n\n```html\n\u003ctable style=\"border:1px solid #ddd\"\u003e\n    \u003ctr\u003e\n        \u003ctd style=\"width: 80px\"\u003e\n            Name\n        \u003c/td\u003e\n        \u003ctd style=\"width: 140px\"\u003e\n            Phone Number\n        \u003c/td\u003e\n        \u003ctd style=\"width: 40px\"\u003e\n            Age\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    {{#each objArr as item | filter : name ^ M : phone ^ 4}}\n    \u003ctr\u003e\n        \u003ctd\u003e{{item.name}}\u003c/td\u003e\n        \u003ctd\u003e{{item.phone}}\u003c/td\u003e\n        \u003ctd\u003e{{item.age}}\u003c/td\u003e\n    \u003c/tr\u003e\n    {{/each}}\n\u003c/table\u003e\n```\n\n\u003ca name=\"api\" id=\"api\"\u003e\u003c/a\u003e\n## API 参考\n\n- diglett(source, data)\n  \n  渲染模板\n  \n  参数：\n  \n  - `source`: 模板字符串或模板 ID\n  - `data`: 模板数据\n\n  返回值：生成后的 HTML\n\n- diglett.options\n\n  全局设置：\n  \n  - `diglett.options.cache`: 是否缓存编译的模板，默认为 `true`\n  - `diglett.options.uglify`: 是否去除生成的 HTML 中多余的空格和注释，默认为 `true`\n\n- diglett.compile(source, options)\n\n  编译模板\n\n  参数：\n  \n  - `source`: 模板字符串或模板 ID\n  - `options`: 选项，参看 `diglett.options`\n  \n  返回值：一个 `render` 函数，调用 `render(data)` 生成最后的 HTML\n\n- diglett.render(source, data, options)\n\n  渲染模板\n\n  参数：\n  \n  - `source`: 模板字符串或模板 ID\n  - `data`: 模板数据\n  - `options`: 选项，参看 `diglett.options`\n  \n  返回值：生成后的 HTML\n\n- diglett.registerFilter(filterName, fn, overwrite)\n\n  注册自定义过滤器\n\n  参数：\n  \n  - `filterName`: 过滤器名称\n  - `fn`: 过滤器方法，参数顺序与使用时的参数顺序相同\n  - `overwrite`: 是否覆盖重名的过滤器\n\n- diglett.removeFilter(filterName)\n\n  删除自定义过滤器\n  \n  参数：\n  \n  - `filterName`: 过滤器名称\n\n\n\n\n\n\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbubkoo%2Fdiglett","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbubkoo%2Fdiglett","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbubkoo%2Fdiglett/lists"}