From be18f33e20670a51034d3ebea8ee38769e8a7743 Mon Sep 17 00:00:00 2001 From: Yang Jun Date: Sat, 6 Jun 2026 23:39:06 +0800 Subject: [PATCH] docs: revamp homepage and switch to custom GitHub buttons - Make the docs English-only by removing all zh-cn content, the language switcher UI, and related JS/config - Rework homepage feature cards (Safe & Typed, Pure JavaScript, Shopify & Jekyll, Streaming) and refresh section colors/layout - Replace buttons.github.io with custom Star/Sponsor buttons featuring a live star count and dark-mode support - Drop the buttons.js script and tidy banner, header, footer, and share partials Co-authored-by: Cursor --- docs/_config.yml | 8 +- docs/source/_data/languages.yml | 2 - docs/source/_data/news.yml | 24 -- docs/source/index.pug | 16 +- docs/source/zh-cn/filters/abs.md | 39 --- docs/source/zh-cn/filters/append.md | 31 -- .../zh-cn/filters/array_to_sentence_string.md | 27 -- docs/source/zh-cn/filters/at_least.md | 27 -- docs/source/zh-cn/filters/at_most.md | 27 -- docs/source/zh-cn/filters/capitalize.md | 29 -- docs/source/zh-cn/filters/ceil.md | 49 --- docs/source/zh-cn/filters/cgi_escape.md | 17 - docs/source/zh-cn/filters/compact.md | 49 --- docs/source/zh-cn/filters/concat.md | 55 ---- docs/source/zh-cn/filters/date.md | 86 ------ .../zh-cn/filters/date_to_long_string.md | 31 -- docs/source/zh-cn/filters/date_to_rfc822.md | 20 -- docs/source/zh-cn/filters/date_to_string.md | 30 -- .../source/zh-cn/filters/date_to_xmlschema.md | 20 -- docs/source/zh-cn/filters/default.md | 64 ---- docs/source/zh-cn/filters/divided_by.md | 48 --- docs/source/zh-cn/filters/downcase.md | 27 -- docs/source/zh-cn/filters/escape.md | 27 -- docs/source/zh-cn/filters/escape_once.md | 27 -- docs/source/zh-cn/filters/find.md | 25 -- docs/source/zh-cn/filters/find_exp.md | 25 -- docs/source/zh-cn/filters/first.md | 37 --- docs/source/zh-cn/filters/floor.md | 49 --- docs/source/zh-cn/filters/group_by.md | 48 --- docs/source/zh-cn/filters/group_by_exp.md | 48 --- docs/source/zh-cn/filters/inspect.md | 42 --- docs/source/zh-cn/filters/join.md | 19 -- docs/source/zh-cn/filters/json.md | 39 --- docs/source/zh-cn/filters/jsonify.md | 9 - docs/source/zh-cn/filters/last.md | 37 --- docs/source/zh-cn/filters/lstrip.md | 17 - docs/source/zh-cn/filters/map.md | 27 -- docs/source/zh-cn/filters/minus.md | 37 --- docs/source/zh-cn/filters/modulo.md | 37 --- docs/source/zh-cn/filters/newline_to_br.md | 23 -- .../zh-cn/filters/normalize_whitespace.md | 17 - docs/source/zh-cn/filters/number_of_words.md | 49 --- docs/source/zh-cn/filters/overview.md | 19 -- docs/source/zh-cn/filters/plus.md | 37 --- docs/source/zh-cn/filters/pop.md | 24 -- docs/source/zh-cn/filters/prepend.md | 31 -- docs/source/zh-cn/filters/push.md | 25 -- docs/source/zh-cn/filters/raw.md | 52 ---- docs/source/zh-cn/filters/remove.md | 17 - docs/source/zh-cn/filters/remove_first.md | 17 - docs/source/zh-cn/filters/remove_last.md | 17 - docs/source/zh-cn/filters/replace.md | 17 - docs/source/zh-cn/filters/replace_first.md | 17 - docs/source/zh-cn/filters/replace_last.md | 17 - docs/source/zh-cn/filters/reverse.md | 33 -- docs/source/zh-cn/filters/round.md | 37 --- docs/source/zh-cn/filters/rstrip.md | 17 - docs/source/zh-cn/filters/shift.md | 24 -- docs/source/zh-cn/filters/size.md | 39 --- docs/source/zh-cn/filters/slice.md | 49 --- docs/source/zh-cn/filters/slugify.md | 59 ---- docs/source/zh-cn/filters/sort.md | 30 -- docs/source/zh-cn/filters/sort_natural.md | 30 -- docs/source/zh-cn/filters/split.md | 31 -- docs/source/zh-cn/filters/strip.md | 17 - docs/source/zh-cn/filters/strip_html.md | 17 - docs/source/zh-cn/filters/strip_newlines.md | 23 -- docs/source/zh-cn/filters/times.md | 37 --- docs/source/zh-cn/filters/to_integer.md | 17 - docs/source/zh-cn/filters/truncate.md | 47 --- docs/source/zh-cn/filters/truncatewords.md | 47 --- docs/source/zh-cn/filters/uniq.md | 18 -- docs/source/zh-cn/filters/unshift.md | 25 -- docs/source/zh-cn/filters/upcase.md | 27 -- docs/source/zh-cn/filters/uri_escape.md | 19 -- docs/source/zh-cn/filters/url_decode.md | 17 - docs/source/zh-cn/filters/url_encode.md | 27 -- docs/source/zh-cn/filters/where.md | 134 -------- docs/source/zh-cn/filters/where_exp.md | 37 --- docs/source/zh-cn/filters/xml_escape.md | 17 - docs/source/zh-cn/index.pug | 29 -- docs/source/zh-cn/manifest.json | 58 ---- docs/source/zh-cn/playground.pug | 5 - docs/source/zh-cn/tags/assign.md | 33 -- docs/source/zh-cn/tags/capture.md | 37 --- docs/source/zh-cn/tags/case.md | 25 -- docs/source/zh-cn/tags/comment.md | 19 -- docs/source/zh-cn/tags/cycle.md | 50 --- docs/source/zh-cn/tags/decrement.md | 27 -- docs/source/zh-cn/tags/echo.md | 20 -- docs/source/zh-cn/tags/for.md | 245 --------------- docs/source/zh-cn/tags/if.md | 44 --- docs/source/zh-cn/tags/include.md | 110 ------- docs/source/zh-cn/tags/increment.md | 45 --- docs/source/zh-cn/tags/inline_comment.md | 50 --- docs/source/zh-cn/tags/layout.md | 66 ---- docs/source/zh-cn/tags/liquid.md | 28 -- docs/source/zh-cn/tags/overview.md | 18 -- docs/source/zh-cn/tags/raw.md | 20 -- docs/source/zh-cn/tags/render.md | 65 ---- docs/source/zh-cn/tags/tablerow.md | 130 -------- docs/source/zh-cn/tags/unless.md | 27 -- .../tutorials/access-scope-in-filters.md | 32 -- docs/source/zh-cn/tutorials/caching.md | 55 ---- .../tutorials/contribution-guidelines.md | 30 -- docs/source/zh-cn/tutorials/differences.md | 58 ---- docs/source/zh-cn/tutorials/drops.md | 201 ------------ docs/source/zh-cn/tutorials/escaping.md | 76 ----- .../source/zh-cn/tutorials/intro-to-liquid.md | 60 ---- docs/source/zh-cn/tutorials/migrate-to-9.md | 29 -- docs/source/zh-cn/tutorials/operators.md | 68 ---- docs/source/zh-cn/tutorials/options.md | 159 ---------- .../zh-cn/tutorials/parse-parameters.md | 100 ------ .../zh-cn/tutorials/partials-and-layouts.md | 60 ---- docs/source/zh-cn/tutorials/plugins.md | 49 --- .../zh-cn/tutorials/register-filters-tags.md | 97 ------ docs/source/zh-cn/tutorials/render-file.md | 113 ------- .../zh-cn/tutorials/render-tag-content.md | 137 -------- docs/source/zh-cn/tutorials/security-model.md | 89 ------ docs/source/zh-cn/tutorials/setup.md | 70 ----- .../source/zh-cn/tutorials/static-analysis.md | 292 ------------------ docs/source/zh-cn/tutorials/sync-and-async.md | 112 ------- .../zh-cn/tutorials/truthy-and-falsy.md | 45 --- .../zh-cn/tutorials/use-in-expressjs.md | 72 ----- .../zh-cn/tutorials/whitespace-control.md | 56 ---- docs/themes/navy/languages/en.yml | 2 +- docs/themes/navy/languages/zh-cn.yml | 68 ---- docs/themes/navy/layout/index.swig | 49 +-- .../navy/layout/partial/after_footer.swig | 1 - docs/themes/navy/layout/partial/header.swig | 23 +- .../navy/layout/partial/mobile_nav.swig | 8 - docs/themes/navy/layout/partial/share.swig | 2 - .../navy/source/css/_partial/header.styl | 76 ++++- .../navy/source/css/_partial/index.styl | 116 +++---- .../themes/navy/source/css/_partial/page.styl | 5 +- docs/themes/navy/source/css/_variables.styl | 2 - docs/themes/navy/source/js/main.js | 41 +-- package.json | 1 - 138 files changed, 166 insertions(+), 5969 deletions(-) delete mode 100644 docs/source/_data/news.yml delete mode 100644 docs/source/zh-cn/filters/abs.md delete mode 100644 docs/source/zh-cn/filters/append.md delete mode 100644 docs/source/zh-cn/filters/array_to_sentence_string.md delete mode 100644 docs/source/zh-cn/filters/at_least.md delete mode 100644 docs/source/zh-cn/filters/at_most.md delete mode 100644 docs/source/zh-cn/filters/capitalize.md delete mode 100644 docs/source/zh-cn/filters/ceil.md delete mode 100644 docs/source/zh-cn/filters/cgi_escape.md delete mode 100644 docs/source/zh-cn/filters/compact.md delete mode 100644 docs/source/zh-cn/filters/concat.md delete mode 100644 docs/source/zh-cn/filters/date.md delete mode 100644 docs/source/zh-cn/filters/date_to_long_string.md delete mode 100644 docs/source/zh-cn/filters/date_to_rfc822.md delete mode 100644 docs/source/zh-cn/filters/date_to_string.md delete mode 100644 docs/source/zh-cn/filters/date_to_xmlschema.md delete mode 100644 docs/source/zh-cn/filters/default.md delete mode 100644 docs/source/zh-cn/filters/divided_by.md delete mode 100644 docs/source/zh-cn/filters/downcase.md delete mode 100644 docs/source/zh-cn/filters/escape.md delete mode 100644 docs/source/zh-cn/filters/escape_once.md delete mode 100644 docs/source/zh-cn/filters/find.md delete mode 100644 docs/source/zh-cn/filters/find_exp.md delete mode 100644 docs/source/zh-cn/filters/first.md delete mode 100644 docs/source/zh-cn/filters/floor.md delete mode 100644 docs/source/zh-cn/filters/group_by.md delete mode 100644 docs/source/zh-cn/filters/group_by_exp.md delete mode 100644 docs/source/zh-cn/filters/inspect.md delete mode 100644 docs/source/zh-cn/filters/join.md delete mode 100644 docs/source/zh-cn/filters/json.md delete mode 100644 docs/source/zh-cn/filters/jsonify.md delete mode 100644 docs/source/zh-cn/filters/last.md delete mode 100644 docs/source/zh-cn/filters/lstrip.md delete mode 100644 docs/source/zh-cn/filters/map.md delete mode 100644 docs/source/zh-cn/filters/minus.md delete mode 100644 docs/source/zh-cn/filters/modulo.md delete mode 100644 docs/source/zh-cn/filters/newline_to_br.md delete mode 100644 docs/source/zh-cn/filters/normalize_whitespace.md delete mode 100644 docs/source/zh-cn/filters/number_of_words.md delete mode 100644 docs/source/zh-cn/filters/overview.md delete mode 100644 docs/source/zh-cn/filters/plus.md delete mode 100644 docs/source/zh-cn/filters/pop.md delete mode 100644 docs/source/zh-cn/filters/prepend.md delete mode 100644 docs/source/zh-cn/filters/push.md delete mode 100644 docs/source/zh-cn/filters/raw.md delete mode 100644 docs/source/zh-cn/filters/remove.md delete mode 100644 docs/source/zh-cn/filters/remove_first.md delete mode 100644 docs/source/zh-cn/filters/remove_last.md delete mode 100644 docs/source/zh-cn/filters/replace.md delete mode 100644 docs/source/zh-cn/filters/replace_first.md delete mode 100644 docs/source/zh-cn/filters/replace_last.md delete mode 100644 docs/source/zh-cn/filters/reverse.md delete mode 100644 docs/source/zh-cn/filters/round.md delete mode 100644 docs/source/zh-cn/filters/rstrip.md delete mode 100644 docs/source/zh-cn/filters/shift.md delete mode 100644 docs/source/zh-cn/filters/size.md delete mode 100644 docs/source/zh-cn/filters/slice.md delete mode 100644 docs/source/zh-cn/filters/slugify.md delete mode 100644 docs/source/zh-cn/filters/sort.md delete mode 100644 docs/source/zh-cn/filters/sort_natural.md delete mode 100644 docs/source/zh-cn/filters/split.md delete mode 100644 docs/source/zh-cn/filters/strip.md delete mode 100644 docs/source/zh-cn/filters/strip_html.md delete mode 100644 docs/source/zh-cn/filters/strip_newlines.md delete mode 100644 docs/source/zh-cn/filters/times.md delete mode 100644 docs/source/zh-cn/filters/to_integer.md delete mode 100644 docs/source/zh-cn/filters/truncate.md delete mode 100644 docs/source/zh-cn/filters/truncatewords.md delete mode 100644 docs/source/zh-cn/filters/uniq.md delete mode 100644 docs/source/zh-cn/filters/unshift.md delete mode 100644 docs/source/zh-cn/filters/upcase.md delete mode 100644 docs/source/zh-cn/filters/uri_escape.md delete mode 100644 docs/source/zh-cn/filters/url_decode.md delete mode 100644 docs/source/zh-cn/filters/url_encode.md delete mode 100644 docs/source/zh-cn/filters/where.md delete mode 100644 docs/source/zh-cn/filters/where_exp.md delete mode 100644 docs/source/zh-cn/filters/xml_escape.md delete mode 100644 docs/source/zh-cn/index.pug delete mode 100644 docs/source/zh-cn/manifest.json delete mode 100644 docs/source/zh-cn/playground.pug delete mode 100644 docs/source/zh-cn/tags/assign.md delete mode 100644 docs/source/zh-cn/tags/capture.md delete mode 100644 docs/source/zh-cn/tags/case.md delete mode 100644 docs/source/zh-cn/tags/comment.md delete mode 100644 docs/source/zh-cn/tags/cycle.md delete mode 100644 docs/source/zh-cn/tags/decrement.md delete mode 100644 docs/source/zh-cn/tags/echo.md delete mode 100644 docs/source/zh-cn/tags/for.md delete mode 100644 docs/source/zh-cn/tags/if.md delete mode 100644 docs/source/zh-cn/tags/include.md delete mode 100644 docs/source/zh-cn/tags/increment.md delete mode 100644 docs/source/zh-cn/tags/inline_comment.md delete mode 100644 docs/source/zh-cn/tags/layout.md delete mode 100644 docs/source/zh-cn/tags/liquid.md delete mode 100644 docs/source/zh-cn/tags/overview.md delete mode 100644 docs/source/zh-cn/tags/raw.md delete mode 100644 docs/source/zh-cn/tags/render.md delete mode 100644 docs/source/zh-cn/tags/tablerow.md delete mode 100644 docs/source/zh-cn/tags/unless.md delete mode 100644 docs/source/zh-cn/tutorials/access-scope-in-filters.md delete mode 100644 docs/source/zh-cn/tutorials/caching.md delete mode 100644 docs/source/zh-cn/tutorials/contribution-guidelines.md delete mode 100644 docs/source/zh-cn/tutorials/differences.md delete mode 100644 docs/source/zh-cn/tutorials/drops.md delete mode 100644 docs/source/zh-cn/tutorials/escaping.md delete mode 100644 docs/source/zh-cn/tutorials/intro-to-liquid.md delete mode 100644 docs/source/zh-cn/tutorials/migrate-to-9.md delete mode 100644 docs/source/zh-cn/tutorials/operators.md delete mode 100644 docs/source/zh-cn/tutorials/options.md delete mode 100644 docs/source/zh-cn/tutorials/parse-parameters.md delete mode 100644 docs/source/zh-cn/tutorials/partials-and-layouts.md delete mode 100644 docs/source/zh-cn/tutorials/plugins.md delete mode 100644 docs/source/zh-cn/tutorials/register-filters-tags.md delete mode 100644 docs/source/zh-cn/tutorials/render-file.md delete mode 100644 docs/source/zh-cn/tutorials/render-tag-content.md delete mode 100644 docs/source/zh-cn/tutorials/security-model.md delete mode 100644 docs/source/zh-cn/tutorials/setup.md delete mode 100644 docs/source/zh-cn/tutorials/static-analysis.md delete mode 100644 docs/source/zh-cn/tutorials/sync-and-async.md delete mode 100644 docs/source/zh-cn/tutorials/truthy-and-falsy.md delete mode 100644 docs/source/zh-cn/tutorials/use-in-expressjs.md delete mode 100644 docs/source/zh-cn/tutorials/whitespace-control.md delete mode 100644 docs/themes/navy/languages/zh-cn.yml diff --git a/docs/_config.yml b/docs/_config.yml index d28a0fbed..b2055096c 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,10 +1,8 @@ title: LiquidJS -subtitle: "A simple, expressive and safe template engine." -description: "LiquidJS is a simple, expressive and safe Shopify / GitHub Pages compatible template engine in pure JavaScript." +subtitle: "A simple, expressive, and safe template engine for JavaScript." +description: "LiquidJS is a simple, expressive, and safe template engine for JavaScript, compatible with Shopify and GitHub Pages." author: Harttle -language: - - en - - zh-cn +language: en timezone: UTC url: https://liquidjs.com diff --git a/docs/source/_data/languages.yml b/docs/source/_data/languages.yml index e4b3acd42..6cf5ad282 100644 --- a/docs/source/_data/languages.yml +++ b/docs/source/_data/languages.yml @@ -1,3 +1 @@ en: English -zh-cn: - name: 简体中文 diff --git a/docs/source/_data/news.yml b/docs/source/_data/news.yml deleted file mode 100644 index 0e2236057..000000000 --- a/docs/source/_data/news.yml +++ /dev/null @@ -1,24 +0,0 @@ -- - url: https://opencollective.com/liquidjs/#section-contribute - date: '2020-02-26' - title: - zh-cn: '赞助人:第一个 backer 通过 Open Collective 贡献于 LiquidJS。' - en: 'Backers: the first backer contributed to LiquidJS via Open Collective.' -- - url: https://github.com/harttle/liquidjs/pull/202 - date: '2020-03-11' - title: - zh-cn: '内存优化:用更精细的手法重写了解析器,来避免临时字符串的生成,内存占用降低 57.7% 以上。' - en: 'Memory Optimization: a more elaborate parser reducing the memory footprint by 57.7%.' -- - url: https://github.com/harttle/liquidjs/pull/205 - date: '2020-03-15' - title: - zh-cn: '性能提升:引入 AST 并重新设计 Token 类型系统,使渲染性能平均提升 100.3%。' - en: 'Performance Boost: a simple AST to improve render performance by 100.3%.' -- - url: https://github.com/harttle/liquidjs/milestone/3?closed=1 - date: '2021-09-30' - title: - zh-cn: '流式渲染:4 倍渲染速度,并增加了对流式渲染的支持。' - en: 'Streamed Rendering: now render is 4x faster and support streamed rendering.' diff --git a/docs/source/index.pug b/docs/source/index.pug index 41ba55af0..64048edf7 100644 --- a/docs/source/index.pug +++ b/docs/source/index.pug @@ -7,23 +7,23 @@ ul#intro-feature-list .intro-feature .intro-feature-icon i.icon-shield - h3.intro-feature-title Safe Rendering - p.intro-feature-desc Liquid templates are highly readable and fault-tolerant thus suitable for designers and customers. Operators and expressions are parsed to AST and no #[code eval] or #[code new Function] are used. + h3.intro-feature-title Safe & Typed + p.intro-feature-desc Templates are readable and fault-tolerant, parsed to an AST with no #[code eval] or #[code new Function]. The whole repo is written in TypeScript strict mode, so types stay precise and docs accurate. li.intro-feature-wrap .intro-feature .intro-feature-icon i.icon-rocket h3.intro-feature-title Pure JavaScript - p.intro-feature-desc Written with pure JavaScript with no native bindings, available in both Node.js and browsers. All of the CMD, ESM and CJS bundles are available on CDN. + p.intro-feature-desc Written in pure JavaScript with no native bindings, running in both Node.js and the browser. The CMD, ESM and CJS bundles are all available on CDN. li.intro-feature-wrap .intro-feature .intro-feature-icon i.icon-shopify - h3.intro-feature-title Shopify Compatible - p.intro-feature-desc All filters and tags from Ruby #[a(href="https://github.com/shopify/liquid") shopify/liquid] are supported by LiquidJS. #[a(href="https://jekyllrb.com/") Jekyll sites], #[a(href="https://pages.github.com/") GitHub Pages] and #[a(href="https://themes.shopify.com/") Shopify templates] can be ported to Node.js without pain. + h3.intro-feature-title Shopify & Jekyll + p.intro-feature-desc All filters and tags from Ruby #[a(href="https://github.com/shopify/liquid") shopify/liquid] are supported, so #[a(href="https://themes.shopify.com/") Shopify templates] work out of the box — as do #[a(href="https://jekyllrb.com/") Jekyll] sites and #[a(href="https://pages.github.com/") GitHub Pages]. li.intro-feature-wrap .intro-feature .intro-feature-icon - i.icon-typescript - h3.intro-feature-title TypeScript Strict - p.intro-feature-desc The whole repo is re-written in TypeScript strict mode to ensure a smooth experience using this lib and the document is precise and always up to date. \ No newline at end of file + i.icon-network + h3.intro-feature-title Streaming + p.intro-feature-desc Render directly to a Node.js stream with #[code renderToNodeStream], emitting output as it's produced — for a faster time to first byte and low memory usage on large pages. \ No newline at end of file diff --git a/docs/source/zh-cn/filters/abs.md b/docs/source/zh-cn/filters/abs.md deleted file mode 100644 index 84483954a..000000000 --- a/docs/source/zh-cn/filters/abs.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: abs ---- - -{% since %}v1.9.1{% endsince %} - -返回数字的绝对值。 - -输入 -```liquid -{{ -17 | abs }} -``` - -输出 -```text -17 -``` - -输入 -```liquid -{{ 4 | abs }} -``` - -输出 -```text -4 -``` - -对于只包含数字的字符串也好使: - -输入 -```liquid -{{ "-19.86" | abs }} -``` - -输出 -```text -19.86 -``` diff --git a/docs/source/zh-cn/filters/append.md b/docs/source/zh-cn/filters/append.md deleted file mode 100644 index 7fa4cca10..000000000 --- a/docs/source/zh-cn/filters/append.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: append ---- - -{% since %}v1.9.1{% endsince %} - -连接两个字符串并返回结果。 - -输入 -```liquid -{{ "/my/fancy/url" | append: ".html" }} -``` - -输出 -```text -/my/fancy/url.html -``` - -也可以用于变量。 - -输入 -```liquid -{% assign filename = "/index.html" %} -{{ "website.com" | append: filename }} -``` - -输出 -```text - -website.com/index.html -``` diff --git a/docs/source/zh-cn/filters/array_to_sentence_string.md b/docs/source/zh-cn/filters/array_to_sentence_string.md deleted file mode 100644 index 3e1d8b537..000000000 --- a/docs/source/zh-cn/filters/array_to_sentence_string.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: array_to_sentence_string ---- - -{% since %}v10.13.0{% endsince %} - -把数组转化为句子,用于做标签列表。有一个可选的连接词参数。 - -输入 -```liquid -{{ "foo,bar,baz" | split: "," | array_to_sentence_string }} -``` - -输出 -```text -foo, bar, and baz -``` - -输入 -```liquid -{{ "foo,bar,baz" | split: "," | array_to_sentence_string: "or" }} -``` - -输出 -```text -foo, bar, or baz -``` diff --git a/docs/source/zh-cn/filters/at_least.md b/docs/source/zh-cn/filters/at_least.md deleted file mode 100644 index 0a1f2e85e..000000000 --- a/docs/source/zh-cn/filters/at_least.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: at_least ---- - -{% since %}v8.4.0{% endsince %} - -限制数字到某个最小值。 - -输入 -```liquid -{{ 4 | at_least: 5 }} -``` - -输出 -```text -5 -``` - -输入 -```liquid -{{ 4 | at_least: 3 }} -``` - -输出 -```text -4 -``` diff --git a/docs/source/zh-cn/filters/at_most.md b/docs/source/zh-cn/filters/at_most.md deleted file mode 100644 index 7410c1d06..000000000 --- a/docs/source/zh-cn/filters/at_most.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: at_most ---- - -{% since %}v8.4.0{% endsince %} - -限制数字到某个最大值。 - -输入 -```liquid -{{ 4 | at_most: 5 }} -``` - -输出 -```text -4 -``` - -输入 -```liquid -{{ 4 | at_most: 3 }} -``` - -输出 -```text -3 -``` diff --git a/docs/source/zh-cn/filters/capitalize.md b/docs/source/zh-cn/filters/capitalize.md deleted file mode 100644 index 5e7562931..000000000 --- a/docs/source/zh-cn/filters/capitalize.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: capitalize ---- - -{% since %}v1.9.1{% endsince %} - -把字符串首字母改为大写。 - -输入 -```liquid -{{ "title" | capitalize }} -``` - -输出 -```text -Title -``` - -`capitalize` 只会大写首字母,因此后续单词的不会受影响: - - Input -```liquid -{{ "my great title" | capitalize }} -``` - -输出 -```text -My great title -``` diff --git a/docs/source/zh-cn/filters/ceil.md b/docs/source/zh-cn/filters/ceil.md deleted file mode 100644 index 5217227d0..000000000 --- a/docs/source/zh-cn/filters/ceil.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: ceil ---- - -{% since %}v1.9.1{% endsince %} - -向上取整,取整前 LiquidJS 会首先把输入转换为数字。 - -输入 -```liquid -{{ 1.2 | ceil }} -``` - -输出 -```text -2 -``` - -输入 -```liquid -{{ 2.0 | ceil }} -``` - -输出 -```text -2 -``` - -输入 -```liquid -{{ 183.357 | ceil }} -``` - -输出 -```text -184 -``` - -下面的例子中输入是字符串: - -输入 -```liquid -{{ "3.5" | ceil }} -``` - -输出 -```text -4 -``` diff --git a/docs/source/zh-cn/filters/cgi_escape.md b/docs/source/zh-cn/filters/cgi_escape.md deleted file mode 100644 index 159dd5bdb..000000000 --- a/docs/source/zh-cn/filters/cgi_escape.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: cgi_escape ---- - -{% since %}v10.13.0{% endsince %} - -把字符串 CGI 转义,用于 URL。用对应的 `%XX` 替换特殊字符,空格会被转义为 `+` 号。 - -输入 -```liquid -{{ "foo, bar; baz?" | cgi_escape }} -``` - -输出 -```text -foo%2C+bar%3B+baz%3F -``` diff --git a/docs/source/zh-cn/filters/compact.md b/docs/source/zh-cn/filters/compact.md deleted file mode 100644 index 6760b62a4..000000000 --- a/docs/source/zh-cn/filters/compact.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: compact ---- - -{% since %}v9.22.0{% endsince %} - -从数组里移除任何 `null` 和 `undefined` 值。 - -假设 `site.pages` 是网页列表,有些网页包含 `category` 属性用来标明类别。如果把它们 `map` 到数组里,那么对于没有 `category` 属性的元素就会是 `undefined`。 - -输入 -```liquid -{% assign site_categories = site.pages | map: "category" %} - -{% for category in site_categories %} -- {{ category }} -{% endfor %} -``` - -输出 -```text -- business -- celebrities -- -- lifestyle -- sports -- -- technology -``` - -使用 `compact` 创建 `site_categories` 数组,可以移除所有 `null` 和 `undefined` 值。 - -输入 -```liquid -{% assign site_categories = site.pages | map: "category" | compact %} - -{% for category in site_categories %} -- {{ category }} -{% endfor %} -``` - -输出 -```text -- business -- celebrities -- lifestyle -- sports -- technology -``` diff --git a/docs/source/zh-cn/filters/concat.md b/docs/source/zh-cn/filters/concat.md deleted file mode 100644 index 376375039..000000000 --- a/docs/source/zh-cn/filters/concat.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: concat ---- - -{% since %}v2.0.0{% endsince %} - -连接多个数组,返回的数组包含所有传入数组的元素。 - -输入 -```liquid -{% assign fruits = "apples, oranges, peaches" | split: ", " %} -{% assign vegetables = "carrots, turnips, potatoes" | split: ", " %} - -{% assign everything = fruits | concat: vegetables %} - -{% for item in everything %} -- {{ item }} -{% endfor %} -``` - -输出 -```text -- apples -- oranges -- peaches -- carrots -- turnips -- potatoes -``` - -可以链式地使用 `concat` 过滤器来连接多个数组: - -输入 -```liquid -{% assign furniture = "chairs, tables, shelves" | split: ", " %} - -{% assign everything = fruits | concat: vegetables | concat: furniture %} - -{% for item in everything %} -- {{ item }} -{% endfor %} -``` - -输出 -```text -- apples -- oranges -- peaches -- carrots -- turnips -- potatoes -- chairs -- tables -- shelves -``` diff --git a/docs/source/zh-cn/filters/date.md b/docs/source/zh-cn/filters/date.md deleted file mode 100644 index be922a665..000000000 --- a/docs/source/zh-cn/filters/date.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: date ---- - -{% since %}v1.9.1{% endsince %} - -把时间戳转换为字符串。LiquidJS 尝试跟 Shopify/Liquid 保持一致,它用的是 Ruby 核心的 [Time#strftime(string)](http://www.ruby-doc.org/core/Time.html#method-i-strftime)。此外 LiquidJS 会先通过 [new Date()][newDate] 尝试把输入转换为 Date 对象。 - -但 LiquidJS 支持的格式与 [Ruby 的 flag](https://ruby-doc.org/core/strftime_formatting_rdoc.html) 有些不同: - * `%Z`(自 v10.11.1 起支持)只有在传入了时区时才起作用(可以通过 `LiquidOption` 传入,也可以在创建日期时单独传入,见下文)。如果传入的时区是个数字,那么它的表现将会与 `%z` 相同。如果没有传入时区,将会返回 [运行时默认时区](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/resolvedOptions#timezone)。 - * LiquidJS 提供额外的 `%q` 用来处理序数:`{{ '2023/02/02' | date: '%d%q of %b'}}` => `02nd of Feb` -* 日期字面量会通过 [new Date()][jsDate] 转化为 `Date` 对象,这意味着字面量默认使用运行时默认时区。 -* 格式字参数是可选的: - * 如果不传,默认为 `%A, %B %-e, %Y at %-l:%M %P %z`。 - * 上述默认值可以通过 [`dateFormat`](/api/interfaces/LiquidOptions.html#dateFormat) 参数覆盖。 - -输入 -```liquid -{{ article.published_at | date: "%a, %b %d, %y" }} -``` - -输出 -```text -Fri, Jul 17, 15 -``` - -{% note info 时区 %} -日期在输出时会转换为当地时区,设置 `timezoneOffset` LiquidJS 参数可以指定一个不同的时区。或者设置 `preserveTimezones` 为 `true` 来保持字面量时间戳的时区,数据中的日期对象不受此参数的影响。 -{% endnote %} - -你也可以在使用 `date` 时再设置时区: - -输入 -```liquid -{{ "1990-12-31T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S", 360}} // 等价于设置 `options.timezoneOffset` to `360`. -{{ "1990-12-31T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S", "Asia/Colombo" }} -``` - -输出 -```liquid -1990-12-31T17:00:00 -1991-01-01T04:30:00 -``` - - -输入 -```liquid -{{ article.published_at | date: "%Y" }} -``` - -输出 -```text -2015 -``` - -输入也可以是符合 JavaScript `Date` 格式的字符串:: - -输入 -```liquid -{{ "March 14, 2016" | date: "%b %d, %y" }} -``` - -输出 -```text -Mar 14, 16 -``` - -{% note info 时间戳字符串 %} -LiquidJS 使用 JavaScript [Date][newDate] 来解析输入字符串,意味着支持 [IETF-compliant RFC 2822 时间戳](https://datatracker.ietf.org/doc/html/rfc2822#page-14) 和 [特定版本的 ISO8601](https://www.ecma-international.org/ecma-262/11.0/#sec-date.parse)。 -{% endnote %} - -可以用特殊值 `"now"`(或`"today"`)来获取当前时间: - -输入 -```liquid -This page was last updated at {{ "now" | date: "%Y-%m-%d %H:%M" }}. -``` - -输出 -```text -This page was last updated at 2020-03-25 15:57. -``` - -{% note info 当前时间 %}注意得到的当前时间是模板渲染时的时间,如果你在用静态站点生成器或者模板有被缓存这一时间可能与用户看到的时间不同。{% endnote %} - -[newDate]: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date diff --git a/docs/source/zh-cn/filters/date_to_long_string.md b/docs/source/zh-cn/filters/date_to_long_string.md deleted file mode 100644 index 0cb54dc74..000000000 --- a/docs/source/zh-cn/filters/date_to_long_string.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: date_to_long_string ---- -{% since %}v10.13.0{% endsince %} - -把日期转换为长格式(只支持 US/UK 两种),与 Jekyll 的 `date_to_long_string` 过滤器一样。 - -输入 -```liquid -{{ site.time | date_to_long_string }} -``` - -输出 -```text -07 November 2008 -``` - -输入 -```liquid -{{ site.time | date_to_long_string: "ordinal" }} -``` - -输出 -```text -7th November 2008 -``` - - -注意 JavaScript `Date` 没有时区信息,详情请参考 [date][date] 过滤器。 - -[date]: ./date.html diff --git a/docs/source/zh-cn/filters/date_to_rfc822.md b/docs/source/zh-cn/filters/date_to_rfc822.md deleted file mode 100644 index fd704397e..000000000 --- a/docs/source/zh-cn/filters/date_to_rfc822.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: date_to_rfc822 ---- -{% since %}v10.13.0{% endsince %} - -把日期转换为 RFC-822 格式用于 RSS feed,与 Jekyll 的 `date_to_rfc822` 过滤器一样。 - -输入 -```liquid -{{ site.time | date_to_rfc822 }} -``` - -输入 -```text -Mon, 07 Nov 2008 13:07:54 -0800 -``` - -注意 JavaScript `Date` 没有时区信息,详情请参考 [date][date] 过滤器。 - -[date]: ./date.html diff --git a/docs/source/zh-cn/filters/date_to_string.md b/docs/source/zh-cn/filters/date_to_string.md deleted file mode 100644 index 569454bf4..000000000 --- a/docs/source/zh-cn/filters/date_to_string.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: date_to_string ---- -{% since %}v10.13.0{% endsince %} - -把日期转换为短格式(只支持 US/UK 两种),与 Jekyll 的 `date_to_string` 过滤器一样。 - -输入 -```liquid -{{ site.time | date_to_string }} -``` - -输出 -```text -07 Nov 2008 -``` - -输入 -```liquid -{{ site.time | date_to_string: "ordinal", "US" }} -``` - -输出 -```text -Nov 7th, 2008 -``` - -注意 JavaScript `Date` 没有时区信息,详情请参考 [date][date] 过滤器。 - -[date]: ./date.html diff --git a/docs/source/zh-cn/filters/date_to_xmlschema.md b/docs/source/zh-cn/filters/date_to_xmlschema.md deleted file mode 100644 index e1051cdc3..000000000 --- a/docs/source/zh-cn/filters/date_to_xmlschema.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: date_to_xmlschema ---- -{% since %}v10.13.0{% endsince %} - -把日期转换为 XML Schema (ISO 8601) 格式,与 Jekyll 的 `date_to_xmlschema` 过滤器一样。 - -输入 -```liquid -{{ site.time | date_to_xmlschema }} -``` - -输出 -```text -2008-11-07T13:07:54-08:00 -``` - -注意 JavaScript `Date` 没有时区信息,详情请参考 [date][date] 过滤器。 - -[date]: ./date.html diff --git a/docs/source/zh-cn/filters/default.md b/docs/source/zh-cn/filters/default.md deleted file mode 100644 index ad16cf45b..000000000 --- a/docs/source/zh-cn/filters/default.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: default ---- - -{% since %}v1.9.1{% endsince %} - -在值不存在时给一个默认值,如果左侧是 [falsy][falsy] 或空(`string` 或 `Array`)就会使用这个默认值。下面的例子中 `product_price` 没有定义,因此使用了默认值。 - -输入 -```liquid -{{ product_price | default: 2.99 }} -``` - -输出 -```text -2.99 -``` - -下面的例子中定义了 `product_price` 所以没有使用默认值。 - -输入 -```liquid -{% assign product_price = 4.99 %} -{{ product_price | default: 2.99 }} -``` - -输出 -```text -4.99 -``` - -下面例子中 `product_price` 为空,所以使用了默认值。 - -输入 -```liquid -{% assign product_price = "" %} -{{ product_price | default: 2.99 }} -``` - -输出 -```text -2.99 -``` - -## 允许 `false` - -{% since %}v9.32.0{% endsince %} - -为了允许让 `false` 直接输出而不是用默认值,可以用 `allow_false` 参数。 - -输入 - -```liquid -{% assign display_price = false %} -{{ display_price | default: true, allow_false: true }} -``` - -输出 - -```text -false -``` - -[falsy]: ../tutorials/truthy-and-falsy.html diff --git a/docs/source/zh-cn/filters/divided_by.md b/docs/source/zh-cn/filters/divided_by.md deleted file mode 100644 index 2eb2d4264..000000000 --- a/docs/source/zh-cn/filters/divided_by.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: divided_by ---- - -{% since %}v1.9.1{% endsince %} - -两数相除返回商,返回结果数字在 JavaScript 中 `.toString()` 得到的字符串。 - -输入 -```liquid -{{ 16 | divided_by: 4 }} -``` - -输出 -```text -4 -``` - -输入 -```liquid -{{ 5 | divided_by: 3 }} -``` - -输出 -```text -1.6666666666666667 -``` - -在 JavaScript 里数字没有浮点和整数的区分,它们的类型都是 `number`: - -```javascript -// always true -5.0 === 5 -``` - -因此如果需要做整数运算,需要传入额外的 `integerArithmetic` 参数: - -Input -```liquid -{{ 5 | divided_by: 3, true }} -``` - -Output -```text -1 -``` - -[floor]: ./floor.html diff --git a/docs/source/zh-cn/filters/downcase.md b/docs/source/zh-cn/filters/downcase.md deleted file mode 100644 index 4fb4cdbb9..000000000 --- a/docs/source/zh-cn/filters/downcase.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: downcase ---- - -{% since %}v1.9.1{% endsince %} - -字符串中每个字符都转为小写,对已经是小写的字符没有影响。 - -输入 -```liquid -{{ "Parker Moore" | downcase }} -``` - -输出 -```text -parker moore -``` - -输入 -```liquid -{{ "apple" | downcase }} -``` - -输出 -```text -apple -``` diff --git a/docs/source/zh-cn/filters/escape.md b/docs/source/zh-cn/filters/escape.md deleted file mode 100644 index 02e5c781e..000000000 --- a/docs/source/zh-cn/filters/escape.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: escape ---- - -{% since %}v1.9.1{% endsince %} - -把字符串中的 HTML 特殊字符转义,对不需要转义的字符串不会产生影响。 - -输入 -```liquid -{{ "Have you read 'James & the Giant Peach'?" | escape }} -``` - -输出 -
-{{"Have you read 'James & the Giant Peach'?" | escape}}
-
- -输入 -```liquid -{{ "Tetsuro Takara" | escape }} -``` - -输出 -```text -Tetsuro Takara -``` diff --git a/docs/source/zh-cn/filters/escape_once.md b/docs/source/zh-cn/filters/escape_once.md deleted file mode 100644 index 14a2f2e8f..000000000 --- a/docs/source/zh-cn/filters/escape_once.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: escape_once ---- - -{% since %}v1.9.1{% endsince %} - -把字符串中的特殊字符转义得到可用在 URL 里的字符串,对已经转义过的字符串和不需要转义的字符串不会产生影响。 - -输入 -```liquid -{{ "1 < 2 & 3" | escape_once }} -``` - -输出 -
-{{"1 < 2 & 3" | escape}}
-
- -输入 -
-{{ "{{"1 < 2 & 3" | escape}}" | escape_once }}
-
- -输出 -
-{{"1 < 2 & 3" | escape}}
-
diff --git a/docs/source/zh-cn/filters/find.md b/docs/source/zh-cn/filters/find.md deleted file mode 100644 index baebe69b8..000000000 --- a/docs/source/zh-cn/filters/find.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: find ---- - -{% since %}v10.11.0{% endsince %} - -在数组中找到给定的属性为给定的值的第一个元素并返回;如果没有这样的元素则返回 `nil`。对于 `members` 数组: - -```javascript -const members = [ - { graduation_year: 2013, name: 'Jay' }, - { graduation_year: 2014, name: 'John' }, - { graduation_year: 2014, name: 'Jack' } -] -``` - -输入 -```liquid -{{ members | find: "graduation_year", 2014 | json }} -``` - -输出 -```text -{"graduation_year":2014,"name":"John"} -``` diff --git a/docs/source/zh-cn/filters/find_exp.md b/docs/source/zh-cn/filters/find_exp.md deleted file mode 100644 index 60a55c70e..000000000 --- a/docs/source/zh-cn/filters/find_exp.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: find_exp ---- - -{% since %}v10.11.0{% endsince %} - -找到数组中给定的表达式值为 `true` 的第一个元素,如果没有这样的元素则返回 `nil`。对于下面的 `members` 数组: - -```javascript -const members = [ - { graduation_year: 2013, name: 'Jay' }, - { graduation_year: 2014, name: 'John' }, - { graduation_year: 2014, name: 'Jack' } -] -``` - -输入 -```liquid -{{ members | find_exp: "item", "item.graduation_year == 2014" | json }} -``` - -输出 -```text -{"graduation_year":2014,"name":"John"} -``` diff --git a/docs/source/zh-cn/filters/first.md b/docs/source/zh-cn/filters/first.md deleted file mode 100644 index fd98ba7ea..000000000 --- a/docs/source/zh-cn/filters/first.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: first ---- - -{% since %}v1.9.1{% endsince %} - -返回数组的第一个元素。 - -输入 -```liquid -{{ "Ground control to Major Tom." | split: " " | first }} -``` - -输出 -```text -Ground -``` - -输入 -```liquid -{% assign my_array = "zebra, octopus, giraffe, tiger" | split: ", " %} -{{ my_array.first }} -``` - -输出 -```text - -zebra -``` - -需要在标签中使用的时候,可以用点来计算 `first`: - -```liquid -{% if my_array.first == "zebra" %} - Here comes a zebra! -{% endif %} -``` diff --git a/docs/source/zh-cn/filters/floor.md b/docs/source/zh-cn/filters/floor.md deleted file mode 100644 index 3401b52a6..000000000 --- a/docs/source/zh-cn/filters/floor.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: floor ---- - -{% since %}v1.9.1{% endsince %} - -数字下取整,LiquidJS 会尝试把输入转换为数字再做下取整操作。 - -输入 -```liquid -{{ 1.2 | floor }} -``` - -输出 -```text -1 -``` - -输入 -```liquid -{{ 2.0 | floor }} -``` - -输出 -```text -2 -``` - -输入 -```liquid -{{ 183.357 | floor }} -``` - -输出 -```text -183 -``` - -下面的例子中输入是个数字: - -输入 -```liquid -{{ "3.5" | floor }} -``` - -输出 -```text -3 -``` diff --git a/docs/source/zh-cn/filters/group_by.md b/docs/source/zh-cn/filters/group_by.md deleted file mode 100644 index 2ce1b08ac..000000000 --- a/docs/source/zh-cn/filters/group_by.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: group_by ---- - -{% since %}v10.11.0{% endsince %} - -把数组元素按照给定的属性的值分组。对于 `members` 数组: - -```javascript -const members = [ - { graduation_year: 2003, name: 'Jay' }, - { graduation_year: 2003, name: 'John' }, - { graduation_year: 2004, name: 'Jack' } -] -``` - -输入 -```liquid -{{ members | group_by: "graduation_year" | json: 2 }} -``` - -输出 -```text -[ - { - "name": 2003, - "items": [ - { - "graduation_year": 2003, - "name": "Jay" - }, - { - "graduation_year": 2003, - "name": "John" - } - ] - }, - { - "name": 2004, - "items": [ - { - "graduation_year": 2004, - "name": "Jack" - } - ] - } -] -``` diff --git a/docs/source/zh-cn/filters/group_by_exp.md b/docs/source/zh-cn/filters/group_by_exp.md deleted file mode 100644 index a68aaaee6..000000000 --- a/docs/source/zh-cn/filters/group_by_exp.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: group_by_exp ---- - -{% since %}v10.11.0{% endsince %} - -把数组元素按照给定的 Liquid 表达式的值分组。对于 `members` 数组: - -```javascript -const members = [ - { graduation_year: 2013, name: 'Jay' }, - { graduation_year: 2014, name: 'John' }, - { graduation_year: 2009, name: 'Jack' } -] -``` - -输入 -```liquid -{{ members | group_by_exp: "item", "item.graduation_year | truncate: 3, ''" | json: 2 }} -``` - -输出 -```text -[ - { - "name": "201", - "items": [ - { - "graduation_year": 2013, - "name": "Jay" - }, - { - "graduation_year": 2014, - "name": "John" - } - ] - }, - { - "name": "200", - "items": [ - { - "graduation_year": 2009, - "name": "Jack" - } - ] - } -] -``` diff --git a/docs/source/zh-cn/filters/inspect.md b/docs/source/zh-cn/filters/inspect.md deleted file mode 100644 index e59dff12f..000000000 --- a/docs/source/zh-cn/filters/inspect.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: inspect ---- - -{% since %}v10.13.0{% endsince %} - -类似于 `json`,但可以处理循环引用的情况。例如对于上下文: - -``` -const foo = { - bar: 'BAR' -} -foo.foo = foo -const scope = { foo } -``` - -输入 -```liquid -{% foo | inspect %} -``` - -输出 -```text -{"bar":"BAR","foo":"[Circular]"} -``` - -## 格式化 - -可以指定一个 `space` 参数来缩进长度。 - -输入 -```liquid -{{ foo | inspect: 4 }} -``` - -输出 -```text -{ - "bar": "BAR", - "foo": "[Circular]" -} -``` diff --git a/docs/source/zh-cn/filters/join.md b/docs/source/zh-cn/filters/join.md deleted file mode 100644 index cfda7ffb8..000000000 --- a/docs/source/zh-cn/filters/join.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: join ---- - -{% since %}v1.9.1{% endsince %} - -把数组中的元素连接成为一个字符串,以传入的参数作为分隔符。 - -输入 -```liquid -{% assign beatles = "John, Paul, George, Ringo" | split: ", " %} -{{ beatles | join: " and " }} -``` - -输出 -```text - -John and Paul and George and Ringo -``` diff --git a/docs/source/zh-cn/filters/json.md b/docs/source/zh-cn/filters/json.md deleted file mode 100644 index 3fc6e71f7..000000000 --- a/docs/source/zh-cn/filters/json.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: json ---- - -{% since %}v9.10.0{% endsince %} - -通过 `JSON.stringify()` 把值转换为字符串,多用于调试用途。 - -输入 -```liquid -{% assign arr = "foo bar coo" | split: " " %} -{{ arr | json }} -``` - -输出 -```text -["foo","bar","coo"] -``` - -## 格式化 - -{% since %}v10.11.0{% endsince %} - -可以指定一个 `space` 参数来格式化 JSON。 - -输入 -```liquid -{% assign arr = "foo bar coo" | split: " " %} -{{ arr | json: 4 }} -``` - -输出 -```text -[ - "foo", - "bar", - "coo" -] -``` diff --git a/docs/source/zh-cn/filters/jsonify.md b/docs/source/zh-cn/filters/jsonify.md deleted file mode 100644 index 55ff26ed6..000000000 --- a/docs/source/zh-cn/filters/jsonify.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: jsonify ---- - -{% since %}v10.13.0{% endsince %} - -见 [json][json]。 - -[json]: ./json.html diff --git a/docs/source/zh-cn/filters/last.md b/docs/source/zh-cn/filters/last.md deleted file mode 100644 index 971acb5a2..000000000 --- a/docs/source/zh-cn/filters/last.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: last ---- - -{% since %}v1.9.1{% endsince %} - -返回数组的最后一个元素。 - -输入 -```liquid -{{ "Ground control to Major Tom." | split: " " | last }} -``` - -输出 -```text -Tom. -``` - -输入 -```liquid -{% assign my_array = "zebra, octopus, giraffe, tiger" | split: ", " %} -{{ my_array.last }} -``` - -输出 -```text - -tiger -``` - -需要在标签中使用的时候,可以用点来计算 `last`: - -```liquid -{% if my_array.last == "tiger" %} - There goes a tiger! -{% endif %} -``` diff --git a/docs/source/zh-cn/filters/lstrip.md b/docs/source/zh-cn/filters/lstrip.md deleted file mode 100644 index f7e07a85e..000000000 --- a/docs/source/zh-cn/filters/lstrip.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: lstrip ---- - -{% since %}v1.9.1{% endsince %} - -移除字符串左侧的空白字符(制表符、空格、换行),不影响词之间的空格。 - -输入 -```liquid -BEGIN{{ " So much room for activities! " | lstrip }}END -``` - -输出 -```text -BEGINSo much room for activities! END -``` diff --git a/docs/source/zh-cn/filters/map.md b/docs/source/zh-cn/filters/map.md deleted file mode 100644 index 5686e8c8a..000000000 --- a/docs/source/zh-cn/filters/map.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: map ---- - -{% since %}v1.9.1{% endsince %} - -按照属性名提取对象的属性形成另一个数组并返回。 - -下面的例子中假设 `site.pages` 包含了站点的所有网页元信息。使用 `assign` 加 `map` 过滤器创建了一个 `site.pages` 中所有对象的 `category` 属性的值构成的数组。 - -输入 -```liquid -{% assign all_categories = site.pages | map: "category" %} - -{% for item in all_categories %} -- {{ item }} -{% endfor %} -``` - -输出 -```text -- business -- celebrities -- lifestyle -- sports -- technology -``` diff --git a/docs/source/zh-cn/filters/minus.md b/docs/source/zh-cn/filters/minus.md deleted file mode 100644 index 8c7c45a04..000000000 --- a/docs/source/zh-cn/filters/minus.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: minus ---- - -{% since %}v1.9.1{% endsince %} - -两数相减。 - -输入 -```liquid -{{ 4 | minus: 2 }} -``` - -输出 -```text -2 -``` - -输入 -```liquid -{{ 16 | minus: 4 }} -``` - -输出 -```text -12 -``` - -输入 -```liquid -{{ 183.357 | minus: 12 }} -``` - -输出 -```text -171.357 -``` diff --git a/docs/source/zh-cn/filters/modulo.md b/docs/source/zh-cn/filters/modulo.md deleted file mode 100644 index 037502bc4..000000000 --- a/docs/source/zh-cn/filters/modulo.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: modulo ---- - -{% since %}v1.9.1{% endsince %} - -返回两数相除的余数。 - -输入 -```liquid -{{ 3 | modulo: 2 }} -``` - -输出 -```text -1 -``` - -输入 -```liquid -{{ 24 | modulo: 7 }} -``` - -输出 -```text -3 -``` - -输入 -```liquid -{{ 183.357 | modulo: 12 }} -``` - -输出 -```text -3.3569999999999993 -``` diff --git a/docs/source/zh-cn/filters/newline_to_br.md b/docs/source/zh-cn/filters/newline_to_br.md deleted file mode 100644 index 8c60e7725..000000000 --- a/docs/source/zh-cn/filters/newline_to_br.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: newline_to_br ---- - -{% since %}v1.9.1{% endsince %} - -把字符串里的所有换行符(`\n`)替换为 HTML 换行(`
`)。 - -输入 -```liquid -{% capture string_with_newlines %} -Hello -there -{% endcapture %} - -{{ string_with_newlines | newline_to_br }} -``` - -输出 -```html - -
Hello
there
-``` diff --git a/docs/source/zh-cn/filters/normalize_whitespace.md b/docs/source/zh-cn/filters/normalize_whitespace.md deleted file mode 100644 index db203419b..000000000 --- a/docs/source/zh-cn/filters/normalize_whitespace.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: normalize_whitespace ---- - -{% since %}v10.13.0{% endsince %} - -把连续的空白字符替换为单个空格。 - -输入 -```liquid -{{ "a \n b" | normalize_whitespace }} -``` - -输出 -```html -a b -``` diff --git a/docs/source/zh-cn/filters/number_of_words.md b/docs/source/zh-cn/filters/number_of_words.md deleted file mode 100644 index 2e239b876..000000000 --- a/docs/source/zh-cn/filters/number_of_words.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: number_of_words ---- - -{% since %}v10.13.0{% endsince %} - -计算文本中的单词数。此过滤器接受一个可选参数,用于控制输入字符串中汉字-日语-韩语(CJK)字符的处理方式: -- `'cjk'`:将每个检测到的 CJK 字符计为一个单词,无论是否由空格分隔。 -- `'auto'`:与 `'cjk'` 类似,但如果过滤器用于可能包含或不包含 CJK 字符的字符串,则性能更好。 - -输入 -```liquid -{{ "Hello world!" | number_of_words }} -``` - -输出 -```text -2 -``` - -输入 -```liquid -{{ "你好hello世界world" | number_of_words }} -``` - -输出 -```text -1 -``` - -输入 -```liquid -{{ "你好hello世界world" | number_of_words: "cjk" }} -``` - -输出 -```text -6 -``` - -输入 -```liquid -{{ "你好hello世界world" | number_of_words: "auto" }} -``` - -输出 -```text -6 -``` diff --git a/docs/source/zh-cn/filters/overview.md b/docs/source/zh-cn/filters/overview.md deleted file mode 100644 index 3e19c0852..000000000 --- a/docs/source/zh-cn/filters/overview.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: 过滤器 -description: 每个 Liquid 过滤器的描述和示例 ---- - -LiquidJS 支持 Liquid 语法中具体业务无关的过滤器,基本上 [shopify/liquid 核心][shopify/liquid] 支持的 LiquidJS 都支持。这部分包含了所有 LiquidJS 支持的过滤器的文档和使用示例。 - -LiquidJS 共支持 40+ 个过滤器,可以分为如下几类: - -类别 | 过滤器 ---- | --- -数学 | plus, minus, modulo, times, floor, ceil, round, divided_by, abs, at_least, at_most -字符串 | append, prepend, capitalize, upcase, downcase, strip, lstrip, rstrip, strip_newlines, split, replace, replace_first, replace_last, remove, remove_first, remove_last, truncate, truncatewords, normalize_whitespace, number_of_words, array_to_sentence_string -HTML/URI | escape, escape_once, url_encode, url_decode, strip_html, newline_to_br, xml_escape, cgi_escape, uri_escape, slugify -数组 | slice, map, sort, sort_natural, uniq, where, where_exp, group_by, group_by_exp, find, find_exp, first, last, join, reverse, concat, compact, size, push, pop, shift, unshift -日期 | date, date_to_xmlschema, date_to_rfc822, date_to_string, date_to_long_string -其他 | default, json, jsonify, inspect, raw, to_integer - -[shopify/liquid]: https://github.com/Shopify/liquid diff --git a/docs/source/zh-cn/filters/plus.md b/docs/source/zh-cn/filters/plus.md deleted file mode 100644 index a44740656..000000000 --- a/docs/source/zh-cn/filters/plus.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: plus ---- - -{% since %}v1.9.1{% endsince %} - -两数相加。 - -输入 -```liquid -{{ 4 | plus: 2 }} -``` - -输出 -```text -6 -``` - -输入 -```liquid -{{ 16 | plus: 4 }} -``` - -输出 -```text -20 -``` - -输入 -```liquid -{{ 183.357 | plus: 12 }} -``` - -输出 -```text -195.357 -``` diff --git a/docs/source/zh-cn/filters/pop.md b/docs/source/zh-cn/filters/pop.md deleted file mode 100644 index fb72a9788..000000000 --- a/docs/source/zh-cn/filters/pop.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: pop ---- - -{% since %}v10.11.0{% endsince %} - -从数组末尾弹出一个元素。注意该操作不会改变原数组,而是在一份拷贝上操作。 - -输入 -```liquid -{% assign fruits = "apples, oranges, peaches" | split: ", " %} - -{% assign everything = fruits | pop %} - -{% for item in everything %} -- {{ item }} -{% endfor %} -``` - -输出 -```text -- apples -- oranges -``` diff --git a/docs/source/zh-cn/filters/prepend.md b/docs/source/zh-cn/filters/prepend.md deleted file mode 100644 index fa0cb9e22..000000000 --- a/docs/source/zh-cn/filters/prepend.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: prepend ---- - -{% since %}v1.9.1{% endsince %} - -在字符串开头添加另一个字符串。 - -输入 -```liquid -{{ "apples, oranges, and bananas" | prepend: "Some fruit: " }} -``` - -输出 -```text -Some fruit: apples, oranges, and bananas -``` - -`prepend` 也可以用于变量。 - -输入 -```liquid -{% assign url = "example.com" %} -{{ "/index.html" | prepend: url }} -``` - -输出 -```text - -example.com/index.html -``` diff --git a/docs/source/zh-cn/filters/push.md b/docs/source/zh-cn/filters/push.md deleted file mode 100644 index ea24324d9..000000000 --- a/docs/source/zh-cn/filters/push.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: push ---- - -{% since %}v10.8.0{% endsince %} - -在数组中添加一个元素。注意该操作不会改变原数组,而是在一份拷贝上操作。 - -输入 -```liquid -{% assign fruits = "apples, oranges" | split: ", " %} - -{% assign everything = fruits | push: "peaches" %} - -{% for item in everything %} -- {{ item }} -{% endfor %} -``` - -输出 -```text -- apples -- oranges -- peaches -``` diff --git a/docs/source/zh-cn/filters/raw.md b/docs/source/zh-cn/filters/raw.md deleted file mode 100644 index 03be9fca9..000000000 --- a/docs/source/zh-cn/filters/raw.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: raw ---- - -{% since %}v9.37.0{% endsince %} - -直接返回变量的值。配合 [outputEscape](/api/interfaces/LiquidOptions.html#outputEscape) 参数使用。 - -{% note info 自动转义 %} -默认情况下 `outputEscape` 为 `undefined`,这意味着 LiquidJS 输出不会默认转义,因此这时使用 `raw` 没有意义。 -{% endnote %} - -输入(未设置 `outputEscape`) -```liquid -{{ "<" }} -``` - -输出 -```text -< -``` - -输入(`outputEscape="escape"`) -```liquid -{{ "<" }} -``` - -输出 -```text -< -``` - -输入(`outputEscape="json"`) -```liquid -{{ "<" }} -``` - -输出 -```text -"<" -``` - -输入(`outputEscape="escape"`) -```liquid -{{ "<" | raw }} -``` - -输出 -```text -< -``` - diff --git a/docs/source/zh-cn/filters/remove.md b/docs/source/zh-cn/filters/remove.md deleted file mode 100644 index 3489e6d4a..000000000 --- a/docs/source/zh-cn/filters/remove.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: remove ---- - -{% since %}v1.9.1{% endsince %} - -移除字符串中出现的所有指定子字符串。 - -输入 -```liquid -{{ "I strained to see the train through the rain" | remove: "rain" }} -``` - -输出 -```text -I strained to see the t through the -``` diff --git a/docs/source/zh-cn/filters/remove_first.md b/docs/source/zh-cn/filters/remove_first.md deleted file mode 100644 index cc3400f04..000000000 --- a/docs/source/zh-cn/filters/remove_first.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: remove_first ---- - -{% since %}v1.9.1{% endsince %} - -移除字符串中出现的第一个指定子字符串。 - -输入 -```liquid -{{ "I strained to see the train through the rain" | remove_first: "rain" }} -``` - -输出 -```text -I strained to see the t through the rain -``` diff --git a/docs/source/zh-cn/filters/remove_last.md b/docs/source/zh-cn/filters/remove_last.md deleted file mode 100644 index f5afdb45d..000000000 --- a/docs/source/zh-cn/filters/remove_last.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: remove_last ---- - -{% since %}v10.2.0{% endsince %} - -移除字符串中出现的最后一个指定子字符串。 - -输入 -```liquid -{{ "I strained to see the train through the rain" | remove_last: "rain" }} -``` - -输出 -```text -I strained to see the train through the -``` diff --git a/docs/source/zh-cn/filters/replace.md b/docs/source/zh-cn/filters/replace.md deleted file mode 100644 index c7109f9cc..000000000 --- a/docs/source/zh-cn/filters/replace.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: replace ---- - -{% since %}v1.9.1{% endsince %} - -把字符串中出现的每一个指定子字符串替换为另一个字符串。 - -输入 -```liquid -{{ "Take my protein pills and put my helmet on" | replace: "my", "your" }} -``` - -输出 -```text -Take your protein pills and put your helmet on -``` diff --git a/docs/source/zh-cn/filters/replace_first.md b/docs/source/zh-cn/filters/replace_first.md deleted file mode 100644 index 6636db913..000000000 --- a/docs/source/zh-cn/filters/replace_first.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: replace_first ---- - -{% since %}v1.9.1{% endsince %} - -把字符串中出现的第一个指定子字符串替换为另一个字符串。 - -输入 -```liquid -{{ "Take my protein pills and put my helmet on" | replace_first: "my", "your" }} -``` - -输出 -```text -Take your protein pills and put my helmet on -``` diff --git a/docs/source/zh-cn/filters/replace_last.md b/docs/source/zh-cn/filters/replace_last.md deleted file mode 100644 index 46736de7d..000000000 --- a/docs/source/zh-cn/filters/replace_last.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: replace_last ---- - -{% since %}v10.2.0{% endsince %} - -把字符串中出现的最后一个指定子字符串替换为另一个字符串。 - -输入 -```liquid -{{ "Take my protein pills and put my helmet on" | replace_last: "my", "your" }} -``` - -输出 -```text -Take my protein pills and put your helmet on -``` diff --git a/docs/source/zh-cn/filters/reverse.md b/docs/source/zh-cn/filters/reverse.md deleted file mode 100644 index 0ebef2698..000000000 --- a/docs/source/zh-cn/filters/reverse.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: reverse ---- - -{% since %}v1.9.1{% endsince %} - -反转数组的所有元素,不可用于字符串。 - -输入 -```liquid -{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %} - -{{ my_array | reverse | join: ", " }} -``` - -输出 -```text - - -plums, peaches, oranges, apples -``` - -尽管 `reverse` 不能直接用于字符串,可以把字符串分割成数组,反转后再连接成字符串: - -输入 -```liquid -{{ "Ground control to Major Tom." | split: "" | reverse | join: "" }} -``` - -输出 -```text -.moT rojaM ot lortnoc dnuorG -``` diff --git a/docs/source/zh-cn/filters/round.md b/docs/source/zh-cn/filters/round.md deleted file mode 100644 index 9f013db75..000000000 --- a/docs/source/zh-cn/filters/round.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: round ---- - -{% since %}v1.9.1{% endsince %} - -数字四舍五入取整,如果传入小数位数作为参数。 - -输入 -```liquid -{{ 1.2 | round }} -``` - -输出 -```text -1 -``` - -输入 -```liquid -{{ 2.7 | round }} -``` - -输出 -```text -3 -``` - -输入 -```liquid -{{ 183.357 | round: 2 }} -``` - -输出 -```text -183.36 -``` diff --git a/docs/source/zh-cn/filters/rstrip.md b/docs/source/zh-cn/filters/rstrip.md deleted file mode 100644 index a717a7ed6..000000000 --- a/docs/source/zh-cn/filters/rstrip.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: rstrip ---- - -{% since %}v1.9.1{% endsince %} - -移除字符串右侧的空白字符(制表符、空格、换行),不影响词之间的空格。 - -输入 -```liquid -BEGIN{{ " So much room for activities! " | rstrip }}END -``` - -输出 -```text -BEGIN So much room for activities!END -``` diff --git a/docs/source/zh-cn/filters/shift.md b/docs/source/zh-cn/filters/shift.md deleted file mode 100644 index e2bb70481..000000000 --- a/docs/source/zh-cn/filters/shift.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: shift ---- - -{% since %}v10.11.0{% endsince %} - -从数组头部弹出一个元素。注意该操作不会改变原数组,而是在一份拷贝上操作。 - -输入 -```liquid -{% assign fruits = "apples, oranges, peaches" | split: ", " %} - -{% assign everything = fruits | shift %} - -{% for item in everything %} -- {{ item }} -{% endfor %} -``` - -输出 -```text -- oranges -- peaches -``` diff --git a/docs/source/zh-cn/filters/size.md b/docs/source/zh-cn/filters/size.md deleted file mode 100644 index 661273b0e..000000000 --- a/docs/source/zh-cn/filters/size.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: size ---- - -{% since %}v1.9.1{% endsince %} - -返回字符串的字符个数或者数组的元素个数。 - -输入 -```liquid -{{ "Ground control to Major Tom." | size }} -``` - -输出 -```text -28 -``` - -输入 -```liquid -{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %} - -{{ my_array.size }} -``` - -输出 -```text - - -4 -``` - -在标签里可以用点来计算 `size`: - -```liquid -{% if site.pages.size > 10 %} - This is a big website! -{% endif %} -``` diff --git a/docs/source/zh-cn/filters/slice.md b/docs/source/zh-cn/filters/slice.md deleted file mode 100644 index a3f2a4df7..000000000 --- a/docs/source/zh-cn/filters/slice.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: slice ---- - -{% since %}v1.9.1{% endsince %} - -返回第一个参数为下标位置的一个字符,如果指定了第二个参数会被解释为子字符串的长度。字符串下标从零开始。 - -输入 -```liquid -{{ "Liquid" | slice: 0 }} -``` - -输出 -```text -L -``` - -输入 -```liquid -{{ "Liquid" | slice: 2 }} -``` - -输出 -```text -q -``` - -输入 -```liquid -{{ "Liquid" | slice: 2, 5 }} -``` - -输出 -```text -quid -``` - -If the first argument is a negative number, the indices are counted from the end of the string: - -输入 -```liquid -{{ "Liquid" | slice: -3, 2 }} -``` - -输出 -```text -ui -``` diff --git a/docs/source/zh-cn/filters/slugify.md b/docs/source/zh-cn/filters/slugify.md deleted file mode 100644 index c6fd88260..000000000 --- a/docs/source/zh-cn/filters/slugify.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: slugify ---- - -将字符串转换为小写的 URL “slug”。`slugify` 过滤器接受两个选项: - -1. `mode: string`。默认为`"default"`,它可选的值如下: - - `"none"`:没有字符 - - `"raw"`:空格 - - `"default"`:空格和非字母数字字符 - - `"pretty"`:空格和非字母数字字符,但排除 `._~!$&'()+,;=@` - - `"ascii"`:空格、非字母数字和非 ASCII 字符 - - `"latin"`:与默认相同,但拉丁字符首先进行音译(例如,àèïòü 转换为 aeiou)。 -2. `case: boolean`。默认为 `false`。如果为 `true`,则保留 `slug` 原本的大小写。 - -输入 -```liquid -{{ "The _config.yml file" | slugify }} -``` -输出 -``` -the-config-yml-file -``` - -输入 -```liquid -{{ "The _config.yml file" | slugify: "pretty" }} -``` -输出 -``` -the-_config.yml-file -``` - -输入 -```liquid -{{ "The _cönfig.yml file" | slugify: "ascii" }} -``` -输出 -``` -the-c-nfig-yml-file -``` - -输入 -```liquid -{{ "The cönfig.yml file" | slugify: "latin" }} -``` -输出 -``` -the-config-yml-file -``` - -输入 -```liquid -{{ "The cönfig.yml file" | slugify: "latin", true }} -``` -输出 -``` -The-config-yml-file -``` diff --git a/docs/source/zh-cn/filters/sort.md b/docs/source/zh-cn/filters/sort.md deleted file mode 100644 index 705c7ca9f..000000000 --- a/docs/source/zh-cn/filters/sort.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: sort ---- - -{% since %}v1.9.1{% endsince %} - -对数组中的元素排序,排序方式为 JavaScript `Array.prototype.sort()`。 - -输入 -```liquid -{% assign my_array = "zebra, octopus, giraffe, Sally Snake" | split: ", " %} - -{{ my_array | sort | join: ", " }} -``` - -输出 -```text - - -Sally Snake, giraffe, octopus, zebra -``` - -有一个参数来指定用元素的哪个属性排序。 - -```liquid -{% assign products_by_price = collection.products | sort: "price" %} -{% for product in products_by_price %} -

{{ product.title }}

-{% endfor %} -``` diff --git a/docs/source/zh-cn/filters/sort_natural.md b/docs/source/zh-cn/filters/sort_natural.md deleted file mode 100644 index dc097d025..000000000 --- a/docs/source/zh-cn/filters/sort_natural.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: sort_natural ---- - -{% since %}v8.4.0{% endsince %} - -大小写不敏感地对数组元素排序。 - -输入 -```liquid -{% assign my_array = "zebra, octopus, giraffe, Sally Snake" | split: ", " %} - -{{ my_array | sort_natural | join: ", " }} -``` - -输出 -```text - - -giraffe, octopus, Sally Snake, zebra -``` - -有一个参数来指定用元素的哪个属性排序。 - -```liquid -{% assign products_by_company = collection.products | sort_natural: "company" %} -{% for product in products_by_company %} -

{{ product.title }}

-{% endfor %} -``` diff --git a/docs/source/zh-cn/filters/split.md b/docs/source/zh-cn/filters/split.md deleted file mode 100644 index 328600213..000000000 --- a/docs/source/zh-cn/filters/split.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: split ---- - -{% since %}v1.9.1{% endsince %} - -把字符串按照指定的分隔符进行分割,`split` 通常用于把逗号分隔的字符串转换为数组。 - -输入 -```liquid -{% assign beatles = "John, Paul, George, Ringo" | split: ", " %} - -{% for member in beatles %} - {{ member }} -{% endfor %} -``` - -输出 -```text - - - - - John - - Paul - - George - - Ringo -``` diff --git a/docs/source/zh-cn/filters/strip.md b/docs/source/zh-cn/filters/strip.md deleted file mode 100644 index 08dd4d3dc..000000000 --- a/docs/source/zh-cn/filters/strip.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: strip ---- - -{% since %}v1.9.1{% endsince %} - -移除字符串两侧的空白字符(制表符、空格、换行),不影响词之间的空格。 - -输入 -```liquid -BEGIN{{ " So much room for activities! " | strip }}END -``` - -输出 -```text -BEGINSo much room for activities!END -``` diff --git a/docs/source/zh-cn/filters/strip_html.md b/docs/source/zh-cn/filters/strip_html.md deleted file mode 100644 index ac907c911..000000000 --- a/docs/source/zh-cn/filters/strip_html.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: strip_html ---- - -{% since %}v1.9.1{% endsince %} - -移除字符串中的 HTML 标签。 - -输入 -```liquid -{{ "Have you read Ulysses?" | strip_html }} -``` - -输出 -```text -Have you read Ulysses? -``` diff --git a/docs/source/zh-cn/filters/strip_newlines.md b/docs/source/zh-cn/filters/strip_newlines.md deleted file mode 100644 index ca9eefe9a..000000000 --- a/docs/source/zh-cn/filters/strip_newlines.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: strip_newlines ---- - -{% since %}v1.9.1{% endsince %} - -移除字符串中的换行符。 - -输入 -```liquid -{% capture string_with_newlines %} -Hello -there -{% endcapture %} - -{{ string_with_newlines | strip_newlines }} -``` - -输出 -```html - -Hellothere -``` diff --git a/docs/source/zh-cn/filters/times.md b/docs/source/zh-cn/filters/times.md deleted file mode 100644 index ea0d8adaf..000000000 --- a/docs/source/zh-cn/filters/times.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: times ---- - -{% since %}v1.9.1{% endsince %} - -两数相乘。 - -输入 -```liquid -{{ 3 | times: 2 }} -``` - -输出 -```text -6 -``` - -输入 -```liquid -{{ 24 | times: 7 }} -``` - -输出 -```text -168 -``` - -输入 -```liquid -{{ 183.357 | times: 12 }} -``` - -输出 -```text -2200.284 -``` diff --git a/docs/source/zh-cn/filters/to_integer.md b/docs/source/zh-cn/filters/to_integer.md deleted file mode 100644 index e79c879ec..000000000 --- a/docs/source/zh-cn/filters/to_integer.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: to_integer ---- - -{% since %}v10.13.0{% endsince %} - -转换为数字类型。 - -输入 -```liquid -{{ "123" | to_integer | json }} -``` - -输出 -```text -123 -``` diff --git a/docs/source/zh-cn/filters/truncate.md b/docs/source/zh-cn/filters/truncate.md deleted file mode 100644 index 0ae5fa5e6..000000000 --- a/docs/source/zh-cn/filters/truncate.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: truncate ---- - -{% since %}v1.9.1{% endsince %} - -把字符串截断为指定长度,可以指定一个数字表示截断到多少长度。最后会添加一个省略号(...)且记在长度里。 - -## 基本使用 - -输入 -```liquid -{{ "Ground control to Major Tom." | truncate: 20 }} -``` - -输出 -```text -Ground control to... -``` - -## 自定义省略号 - -`truncate` 的第二个可选参数用来指定后面追加的字符串,默认为省略号(...)。这个参数的长度会计算在第一个参数的长度里。例如,如果要把字符串截断到 10 个字符,并使用了一个 3 字符长度的省略号,那么第一个参数的值要设置到 **13**。 - -输入 -```liquid -{{ "Ground control to Major Tom." | truncate: 25, ", and so on" }} -``` - -输出 -```text -Ground control, and so on -``` - -## 不要省略号 - -如果需要把字符串截断到特定长度且不要添加省略号,则把第二个参数设置为空字符串: - -输入 -```liquid -{{ "Ground control to Major Tom." | truncate: 20, "" }} -``` - -输出 -```text -Ground control to Ma -``` diff --git a/docs/source/zh-cn/filters/truncatewords.md b/docs/source/zh-cn/filters/truncatewords.md deleted file mode 100644 index 62ae88215..000000000 --- a/docs/source/zh-cn/filters/truncatewords.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: truncatewords ---- - -{% since %}v1.9.1{% endsince %} - -把字符串截断为指定个数的单词,可以指定一个数字表示截断到多少个单词。最后会添加一个省略号(...)。 - -## 基本使用 - -输入 -```liquid -{{ "Ground control to Major Tom." | truncatewords: 3 }} -``` - -输出 -```text -Ground control to... -``` - -## 自定义省略号 - -`truncate` 的第二个可选参数用来指定后面追加的字符串,默认为省略号(...)。 - -输入 -```liquid -{{ "Ground control to Major Tom." | truncatewords: 3, "--" }} -``` - -输出 -```text -Ground control to-- -``` - -## 不要省略号 - -如果不希望添加省略号,把第二个参数设置为空字符串即可: - -输入 -```liquid -{{ "Ground control to Major Tom." | truncatewords: 3, "" }} -``` - -输出 -```text -Ground control to -``` diff --git a/docs/source/zh-cn/filters/uniq.md b/docs/source/zh-cn/filters/uniq.md deleted file mode 100644 index 85cff1466..000000000 --- a/docs/source/zh-cn/filters/uniq.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: uniq ---- - -{% since %}v1.9.1{% endsince %} - -移除数组中的重复元素。 - -输入 -```liquid -{% assign my_array = "ants, bugs, bees, bugs, ants" | split: ", " %} -{{ my_array | uniq | join: ", " }} -``` - -输出 -```text - -ants, bugs, bees``` diff --git a/docs/source/zh-cn/filters/unshift.md b/docs/source/zh-cn/filters/unshift.md deleted file mode 100644 index e29ebd2f7..000000000 --- a/docs/source/zh-cn/filters/unshift.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: unshift ---- - -{% since %}v10.11.0{% endsince %} - -往数组头部添加一个元素。注意该操作不会改变原数组,而是在一份拷贝上操作。 - -输入 -```liquid -{% assign fruits = "oranges, peaches" | split: ", " %} - -{% assign everything = fruits | unshift: "apples" %} - -{% for item in everything %} -- {{ item }} -{% endfor %} -``` - -输出 -```text -- apples -- oranges -- peaches -``` diff --git a/docs/source/zh-cn/filters/upcase.md b/docs/source/zh-cn/filters/upcase.md deleted file mode 100644 index 8d4b26e58..000000000 --- a/docs/source/zh-cn/filters/upcase.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: upcase ---- - -{% since %}v1.9.1{% endsince %} - -字符串中每个字符都转为大写,对已经是大写的字符没有影响。 - -输入 -```liquid -{{ "Parker Moore" | upcase }} -``` - -输出 -```text -PARKER MOORE -``` - -输入 -```liquid -{{ "APPLE" | upcase }} -``` - -输出 -```text -APPLE -``` diff --git a/docs/source/zh-cn/filters/uri_escape.md b/docs/source/zh-cn/filters/uri_escape.md deleted file mode 100644 index 31c2c1fb5..000000000 --- a/docs/source/zh-cn/filters/uri_escape.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: uri_escape ---- - -{% since %}v10.13.0{% endsince %} - -把 URI 中的特殊字符做百分号编码,空格会变成 `%20`。[保留字][reserved] 不会被转义。 - -输入 -```liquid -{{ "https://example.com/?q=foo, \bar?" | uri_escape }} -``` - -输出 -```text -https://example.com/?q=foo,%20%5Cbar? -``` - -[reserved]: https://en.wikipedia.org/wiki/Percent-encoding#Types_of_URI_characters diff --git a/docs/source/zh-cn/filters/url_decode.md b/docs/source/zh-cn/filters/url_decode.md deleted file mode 100644 index 8bfa63db5..000000000 --- a/docs/source/zh-cn/filters/url_decode.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: url_decode ---- - -{% since %}v6.1.0{% endsince %} - -把 URL 编码的字符串解码。 - -输入 -```liquid -{{ "%27Stop%21%27+said+Fred" | url_decode }} -``` - -输出 -```text -'Stop!' said Fred -``` diff --git a/docs/source/zh-cn/filters/url_encode.md b/docs/source/zh-cn/filters/url_encode.md deleted file mode 100644 index 3817d8743..000000000 --- a/docs/source/zh-cn/filters/url_encode.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: url_encode ---- - -{% since %}v1.9.1{% endsince %} - -把字符串中 URL 不安全的字符转义为百分号编码。 - -输入 -```liquid -{{ "john@liquid.com" | url_encode }} -``` - -输出 -```text -john%40liquid.com -``` - -输入 -```liquid -{{ "Tetsuro Takara" | url_encode }} -``` - -输出 -```text -Tetsuro+Takara -``` diff --git a/docs/source/zh-cn/filters/where.md b/docs/source/zh-cn/filters/where.md deleted file mode 100644 index e35a8f0c8..000000000 --- a/docs/source/zh-cn/filters/where.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -title: where ---- - -{% since %}v8.1.0{% endsince %} - -按照数组中对象的属性值来过滤得到新数组,如果未指定第二个参数(属性值)则过滤得到所有属性值为 [truthy][truthy] 的对象。 - -下面的例子中,假设你有一个 `products` 列表并且希望展示其中的厨房产品。使用 `where` 过滤器可以得到一个只包含 `"type"` 属性值为 `"kitchen"` 的元素的数组。 - -输入 -```liquid -All products: -{% for product in products %} -- {{ product.title }} -{% endfor %} - -{% assign kitchen_products = products | where: "type", "kitchen" %} - -Kitchen products: -{% for product in kitchen_products %} -- {{ product.title }} -{% endfor %} -``` - -输出 -```text -All products: -- Vacuum -- Spatula -- Television -- Garlic press - -Kitchen products: -- Spatula -- Garlic press -``` - -如果你有一个产品列表且希望只显示可用的产品,可以用 `where` 过滤器但不指定目标值,LiquidJS 会过滤得到 `"available"` 值为 [truthy][truthy] 的产品列表。 - -输入 -```liquid -All products: -{% for product in products %} -- {{ product.title }} -{% endfor %} - -{% assign available_products = products | where: "available" %} - -Available products: -{% for product in available_products %} -- {{ product.title }} -{% endfor %} -``` - -输出 -```text -All products: -- Coffee mug -- Limited edition sneakers -- Boring sneakers - -Available products: -- Coffee mug -- Boring sneakers -``` - -`where` 后面再加一个 `first` 可以用来得到单个元素。例如,你要展示秋季系列里的单个 T-shirt。 - -输入 -```liquid -{% assign new_shirt = products | where: "type", "shirt" | first %} - -Featured product: {{ new_shirt.title }} -``` - -输出 -```text -Featured product: Hawaiian print sweater vest -``` - -此外 `property` 可以是任意合法的变量表达式,就像在**输出**结构中一样,只是它的上下文是数组的每一个元素。对于下面的 `products` 数组: - -```javascript -const products = [ - { meta: { details: { class: 'A' } }, order: 1 }, - { meta: { details: { class: 'B' } }, order: 2 }, - { meta: { details: { class: 'B' } }, order: 3 } -] -``` - -输入 -```liquid -{% assign selected = products | where: 'meta.details["class"]', "B" %} -{% for item in selected -%} -- {{ item.order }} -{% endfor %} -``` - -输出 -```text -- 2 -- 3 -``` - -## Jekyll 风格 - -{% since %}v10.19.0{% endsince %} - -对于从 Jekyll 迁移到 Liquid 的用户,有一个 `jekyllWhere` 选项可以模拟 Jekyll 的 `where` 过滤器的行为。该选项默认设置为 `false`。启用后,如果 `property` 是一个数组,目标值将使用 `Array.includes` 而不是 `==` 进行匹配,这在过滤标签时特别有用。 - -例如,以下代码: - -```javascript -const pages = [ - { tags: ["cat", "food"], title: 'Cat Food' }, - { tags: ["dog", "food"], title: 'Dog Food' }, -] -``` - -输入 -```liquid -{% assign selected = pages | where: 'tags', "cat" %} -{% for item in selected -%} -- {{ item.title }} -{% endfor %} -``` - -输出 -```text -Cat Food -``` - -[truthy]: ../tutorials/truthy-and-falsy.html diff --git a/docs/source/zh-cn/filters/where_exp.md b/docs/source/zh-cn/filters/where_exp.md deleted file mode 100644 index f28368950..000000000 --- a/docs/source/zh-cn/filters/where_exp.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: where_exp ---- - -{% since %}v10.12.0{% endsince %} - -从数组中选择所有表达式值为真的对象。下面的例子中,假设你要从产品列表中筛选出来厨房用品。利用 `where_exp` 可以创建一个只包含 `"type"` 为 `"kitchen"` 的列表。 - -输入 -```liquid -All products: -{% for product in products %} -- {{ product.title }} -{% endfor %} - -{% assign kitchen_products = products | where_exp: "item", "item.type == 'kitchen'" %} - -Kitchen products: -{% for product in kitchen_products %} -- {{ product.title }} -{% endfor %} -``` - -输出 -```text -All products: -- Vacuum -- Spatula -- Television -- Garlic press - -Kitchen products: -- Spatula -- Garlic press -``` - -[truthy]: ../tutorials/truthy-and-falsy.html diff --git a/docs/source/zh-cn/filters/xml_escape.md b/docs/source/zh-cn/filters/xml_escape.md deleted file mode 100644 index 3fa6d7014..000000000 --- a/docs/source/zh-cn/filters/xml_escape.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: xml_escape ---- - -{% since %}v10.13.0{% endsince %} - -把文本做 XML 转义。 - -输入 -```liquid -{{ "Have you read \'James & the Giant Peach\'?" | xml_escape }} -``` - -输出 -```text -Have you read 'James & the Giant Peach'? -``` diff --git a/docs/source/zh-cn/index.pug b/docs/source/zh-cn/index.pug deleted file mode 100644 index 5d1fa0ca5..000000000 --- a/docs/source/zh-cn/index.pug +++ /dev/null @@ -1,29 +0,0 @@ -layout: index -description: LiquidJS 是一个纯 JavaScript 实现的,简洁的、安全的模板引擎,兼容 Shopify / Github Pages。 -subtitle: 简单安全的 Liquid 模板引擎 ---- -ul#intro-feature-list - li.intro-feature-wrap - .intro-feature - .intro-feature-icon - i.icon-shield - h3.intro-feature-title 安全渲染 - p.intro-feature-desc Liquid 模板有很强的可读性和容错性,适用于开放给设计师和客户。运算符和表达式都先解析到 AST 再去渲染,避免了 #[code eval] 和 #[code new Function]。 - li.intro-feature-wrap - .intro-feature - .intro-feature-icon - i.icon-rocket - h3.intro-feature-title 纯 JavaScript - p.intro-feature-desc 纯 JavaScript 的没有 Native Binding 的 Liquid 实现,Node.js 和浏览器通用。同时提供了 CDN 可用的 CMD, ESM 和 CJS 打包。 - li.intro-feature-wrap - .intro-feature - .intro-feature-icon - i.icon-shopify - h3.intro-feature-title Shopify 兼容 - p.intro-feature-desc 支持 #[a(href="https://github.com/shopify/liquid") shopify/liquid] 的所有标签和过滤器,#[a(href="https://jekyllrb.com/") Jekyll 站点], #[a(href="https://pages.github.com/") Github Pages] 和 #[a(href="https://themes.shopify.com/") Shopify 模板] 都可以轻松迁移到 Node.js。 - li.intro-feature-wrap - .intro-feature - .intro-feature-icon - i.icon-typescript - h3.intro-feature-title TypeScript - p.intro-feature-desc 整个项目在 TypeScript strict 模式下重写,让这个库拥有顺滑的使用体验,同时确保了一致的 API 和实时的、精确的文档。 diff --git a/docs/source/zh-cn/manifest.json b/docs/source/zh-cn/manifest.json deleted file mode 100644 index 596469ec5..000000000 --- a/docs/source/zh-cn/manifest.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "short_name": "LiquidJS", - "name": "LiquidJS", - "description": "LiquidJS 是一个简单的、安全的、兼容 Shopify 的、纯 JavaScript 编写的模板引擎。", - "icons": [ - { - "src": "/icon/apple-touch-icon-57x57.png", - "type": "image/png", - "sizes": "57x57" - }, - { - "src": "/icon/favicon-96x96.png", - "type": "image/png", - "sizes": "96x96" - }, - { - "src": "/icon/favicon-196x196.png", - "type": "image/png", - "sizes": "196x196" - }, - { - "src": "/icon/apple-touch-icon.png", - "type": "image/png", - "sizes": "512x512" - } - ], - "shortcuts" : [ - { - "name": "教程", - "url": "/zh-cn/tutorials/intro-to-liquid.html", - "description": "一系列描述如何使用 LiquidJS 的文章" - }, - { - "name": "标签", - "url": "/zh-cn/tags/overview.html", - "description": "每个 Liquid 标签的描述和示例" - }, - { - "name": "过滤器", - "url": "/zh-cn/filters/overview.html", - "description": "每个 Liquid 过滤器的描述和示例" - }, - { - "name": "演示", - "url": "/zh-cn/playground.html", - "description": "一个用来尝试和分享 Liquid 模板的在线编辑器" - }, - { - "name": "API", - "url": "/api/classes/Liquid.html", - "description": "LiquidJS 类和接口的 TypeScript 文档" - } - ], - "start_url": "/zh-cn", - "display": "standalone", - "theme_color": "#0f83ce", - "background_color": "#0f83ce" -} diff --git a/docs/source/zh-cn/playground.pug b/docs/source/zh-cn/playground.pug deleted file mode 100644 index 4fc10b206..000000000 --- a/docs/source/zh-cn/playground.pug +++ /dev/null @@ -1,5 +0,0 @@ ---- -layout: playground -title: 演示 -description: 一个用来尝试和分享 Liquid 模板的在线编辑器 ---- diff --git a/docs/source/zh-cn/tags/assign.md b/docs/source/zh-cn/tags/assign.md deleted file mode 100644 index 3b7382bfe..000000000 --- a/docs/source/zh-cn/tags/assign.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Assign ---- - -{% since %}v1.9.1{% endsince %} - -创建一个新变量。 - -输入 -```liquid -{% assign my_variable = false %} -{% if my_variable != true %} - This statement is valid. -{% endif %} -``` - -输出 -```text -This statement is valid. -``` - -用引号(`"`)包起来表示一个字符串。 - -输入 -```liquid -{% assign foo = "bar" %} -{{ foo }} -``` - -输出 -```text -bar -``` diff --git a/docs/source/zh-cn/tags/capture.md b/docs/source/zh-cn/tags/capture.md deleted file mode 100644 index 0d6927bff..000000000 --- a/docs/source/zh-cn/tags/capture.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: capture ---- - -{% since %}v1.9.1{% endsince %} - -把 `capture` 开闭标签之间的内容渲染后赋值给一个变量,这个变量的类型总是字符串。 - -输入 -```liquid -{% capture my_variable %}I am being captured.{% endcapture %} -{{ my_variable }} -``` - -输出 -```text -I am being captured. -``` - -在 `capture` 里可以使用 `assign` 创建的其他变量来构建复杂字符串: - -输入 -```liquid -{% assign favorite_food = "pizza" %} -{% assign age = 35 %} - -{% capture about_me %} -I am {{ age }} and my favorite food is {{ favorite_food }}. -{% endcapture %} - -{{ about_me }} -``` - -输出 -```text -I am 35 and my favourite food is pizza. -``` diff --git a/docs/source/zh-cn/tags/case.md b/docs/source/zh-cn/tags/case.md deleted file mode 100644 index dba539c13..000000000 --- a/docs/source/zh-cn/tags/case.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: case ---- - -{% since %}v1.9.1{% endsince %} - -创建一个 switch 语句,把变量跟不同的值比较。`case` 创建 switch 语句,`when` 比较它的值。 - -输入 -```liquid -{% assign handle = "cake" %} -{% case handle %} - {% when "cake" %} - This is a cake - {% when "cookie", "biscuit" %} - This is a cookie - {% else %} - This is neither a cake nor a cookie -{% endcase %} -``` - -输出 -```text -This is a cake -``` diff --git a/docs/source/zh-cn/tags/comment.md b/docs/source/zh-cn/tags/comment.md deleted file mode 100644 index 7b9da4faa..000000000 --- a/docs/source/zh-cn/tags/comment.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Comment ---- - -{% since %}v1.9.1{% endsince %} - -让 Liquid 模板里一段代码不渲染。处于 `comment` 开闭标签之间的文本都不会输出,Liquid 代码都不会执行。 - -输入 -```liquid -Anything you put between {% comment %} and {% endcomment %} tags -is turned into a comment. -``` - -输出 -```liquid -Anything you put between tags -is turned into a comment. -``` diff --git a/docs/source/zh-cn/tags/cycle.md b/docs/source/zh-cn/tags/cycle.md deleted file mode 100644 index 931b027ca..000000000 --- a/docs/source/zh-cn/tags/cycle.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: cycle ---- - -{% since %}v1.9.1{% endsince %} - -循环一组字符串按照它们传入的顺序打印出来。每次调用 `cycle` 打印下一个参数。 - -## 基本使用 - -输入 -```liquid -{% cycle "one", "two", "three" %} -{% cycle "one", "two", "three" %} -{% cycle "one", "two", "three" %} -{% cycle "one", "two", "three" %} -``` - -输出 -```text -one -two -three -one -``` - -`cycle` 可以用于: - -- 对表格里每一行按奇偶应用不同样式 -- 对每行最后一项应用特殊样式 - -## 参数 - -一个模板中需要多个 `cycle` 时可以使用 "cycle 组" 参数。如果没有提供组名,使用同样参数调用的 `cycle` 会被认为处于同一组。 - -输入 -```liquid -{% cycle "first": "one", "two", "three" %} -{% cycle "second": "one", "two", "three" %} -{% cycle "second": "one", "two", "three" %} -{% cycle "first": "one", "two", "three" %} -``` - -输出 -```text -one -one -two -two -``` diff --git a/docs/source/zh-cn/tags/decrement.md b/docs/source/zh-cn/tags/decrement.md deleted file mode 100644 index dafa6f12d..000000000 --- a/docs/source/zh-cn/tags/decrement.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Decrement ---- - -{% since %}v1.9.1{% endsince %} - -创建一个新的数字类型的变量,每次调用都把它的值减一。第一次是 `-1`。 - -输入 -```liquid -{% decrement variable %} -{% decrement variable %} -{% decrement variable %} -``` - -输出 -```text --1 --2 --3 -``` - -像 [increment][increment] 一样,在 `decrement` 里声明的变量独立于 [assign][assign] 或 [capture][capture] 创建的变量。 - -[increment]: ./increment.html -[assign]: ./assign.html -[capture]: ./capture.html diff --git a/docs/source/zh-cn/tags/echo.md b/docs/source/zh-cn/tags/echo.md deleted file mode 100644 index 3ec0dbf09..000000000 --- a/docs/source/zh-cn/tags/echo.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Echo ---- - -{% since %}v9.31.0{% endsince %} - -根据表达式输出渲染 HTML。和使用 `{{` expression `}}` 包裹模板效果一样,不同的是 echo 可以在 liquid 标签中使用,同时也支持过滤器。 - -## echo - -输入 -```liquid -{% assign username = 'Bob' %} -{% echo username | append: ", welcome to LiquidJS!" | capitalize %} -``` - -输出 -```text -Bob, welcome to LiquidJS! -``` diff --git a/docs/source/zh-cn/tags/for.md b/docs/source/zh-cn/tags/for.md deleted file mode 100644 index 474fdef94..000000000 --- a/docs/source/zh-cn/tags/for.md +++ /dev/null @@ -1,245 +0,0 @@ ---- -title: For ---- - -{% since %}v1.9.1{% endsince %} - -重复执行代码块的迭代标签。 - -## 基本使用 - -### for...in - -重复执行一段代码。 - -输入 -```liquid -{% for product in collection.products %} - {{ product.title }} -{% endfor %} -``` - -输出 -```text -hat shirt pants -``` - -### else - -指定 `for` 循环的集合长度为零时执行的代码块。 - -输入 -```liquid -{% for product in collection.products %} - {{ product.title }} -{% else %} - The collection is empty. -{% endfor %} -``` - -输出 -```text -The collection is empty. -``` - -### break - -遇到 `break` 标签时 `for` 循环停止执行。 - -输入 -```liquid -{% for i in (1..5) %} - {%- if i == 4 -%} - {% break %} - {%- else -%} - {{ i }} - {%- endif -%} -{% endfor %} -``` - -输出 -```text -123 -``` - -### continue - -遇到 `continue` 标签时跳过当前这次迭代。 - -输入 -```liquid -{% for i in (1..5) %} - {%- if i == 4 -%} - {%- continue -%} - {%- else -%} - {{ i }} - {%- endif -%} -{% endfor %} -``` - -输出 -```text -1235 -``` - -### forloop - -在 `for` 循环里有一个 `forloop` 变量可用,用来表示迭代的当前状态。 - -`forloop.first`, `forloop.last` 和 `forloop.length` 属性: - -输入 -``` -{% for i in (1..5) %} - {%- if forloop.first == true -%} First - {%- elsif forloop.last == true -%} Last - {%- else -%} {{ forloop.length }} - {%- endif %} -{% endfor -%} -``` - -输出 -``` -First -5 -5 -5 -Last -``` - -`forloop.index`, `forloop.index0`, `forloop.rindex` 和 `forloop.rindex0` 属性: - -输入 -``` -index index0 rindex rindex0 -{% for i in (1..5) %} - {{- forloop.index }} {{ forloop.index0 }} {{ forloop.rindex }} {{ forloop.rindex0 }} -{% endfor -%} -``` - -输出 -``` -index index0 rindex rindex0 -1 0 5 4 -2 1 4 3 -3 2 3 2 -4 3 2 1 -5 4 1 0 -``` - -## 参数 - -### limit - -限制循环执行的次数。 - -输入 -```liquid - -{% for item in array limit:2 %} - {{- item -}} -{% endfor %} -``` - -输出 -```text -12 -``` - -### offset - -从指定的下标处开始循环。 - -输入 -```liquid - -{% for item in array offset:2 %} - {{- item -}} -{% endfor %} -``` - -输出 -```text -3456 -``` - -#### offset:continue - -{% since %}v9.33.0{% endsince %} - -`offset` 的值可以是 `continue`,用来继续上一次循环。例如: - -输入 -```liquid - -{% for item in array limit:2 %} - {{- item -}} -{% endfor%} -{% for item in array offset:continue %} - {{- item -}} -{% endfor%} -``` - -输出 -```text -12 -3456 -``` - -对同样的变量名和集合名(这个例子中是 `"item-array"`),存在唯一的位置记录。也就是说用新的变量名就可以开启一个新的循环: - -输入 -```liquid - -{% for item in array limit:2 %} - {{- item -}} -{% endfor%} -{% for item2 in array offset:continue %} - {{- item2 -}} -{% endfor%} -``` - -输出 -```text -12 -123456 -``` - -### range - -定义一个用于循环的数字范围。可以用字面量定义范围,也可以用变量定义范围。 - -输入 -```liquid -{% for i in (3..5) %} - {{ i }} -{% endfor %} - -{% assign num = 4 %} -{% for i in (1..num) %} - {{ i }} -{% endfor %} -``` - -输出 -```text -3 4 5 -1 2 3 4 -``` - -### reversed - -反转循环的顺序。注意这个参数的拼写和过滤器 `reverse` 不同。 - -输入 -```liquid - -{% for item in array reversed %} - {{ item }} -{% endfor %} -``` - -输出 -```text -6 5 4 3 2 1 -``` diff --git a/docs/source/zh-cn/tags/if.md b/docs/source/zh-cn/tags/if.md deleted file mode 100644 index 264f9e10a..000000000 --- a/docs/source/zh-cn/tags/if.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: If ---- - -{% since %}v1.9.1{% endsince %} - -条件为 `true` 时执行某个代码块。 - -## if - -输入 -```liquid -{% if product.title == "Awesome Shoes" %} - These shoes are awesome! -{% endif %} -``` - -输出 -```text -These shoes are awesome! -``` - -## elsif / else - -在 `if` 或 [unless][unless] 块中添加更多的条件。 - -输入 -```liquid - -{% if customer.name == "kevin" %} - Hey Kevin! -{% elsif customer.name == "anonymous" %} - Hey Anonymous! -{% else %} - Hi Stranger! -{% endif %} -``` - -输出 -```text -Hey Anonymous! -``` - -[unless]: ./unless.html diff --git a/docs/source/zh-cn/tags/include.md b/docs/source/zh-cn/tags/include.md deleted file mode 100644 index 59e993fc7..000000000 --- a/docs/source/zh-cn/tags/include.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: Include ---- - -{% since %}v1.9.1{% endsince %} - -{% note warn 已废弃 %} -这个标签已经废弃,请使用封装更好的 render 标签。 -{% endnote %} - -## 引入一个模板 - -从模板 [根路径][root] 引入一个模板: - -```liquid -{% include 'footer.liquid' %} -``` - -设置 [extname][extname] 选项为 `".liquid"` 后上面的 `.liquid` 后缀就可以省略了,等价于: - -```liquid -{% include 'footer' %} -``` - -通过 `include` 渲染一个子模板时,它内部的代码可以访问父模板的变量,但父模板中不能访问它里面定义的变量。 - -## 变量传递 - -父模板里定义的变量可以通过 `include` 标签的参数列表传递给子模板: - -```liquid -{% assign my_variable = 'apples' %} -{% include 'name', my_variable: my_variable, my_other_variable: 'oranges' %} -``` - -## `with` 参数 - -使用 `with...as` 语法可以给子模板传递一个变量: - -```liquid -{% assign featured_product = all_products['product_handle'] %} -{% include 'product' with featured_product as product %} -``` - -上面的例子中,子模板中 `product` 会保有父模板中的 `featured_product` 变量的值。 - -## 输出和过滤器 - -文件名为字符串字面量时,支持 Liquid 输出和过滤器。在拼接文件名时很方便: - -```liquid -{% include "prefix/{{name | append: \".html\"}}" %} -``` - -{% note info 转义 %} -字符串字面量里的 `"` 需要转义为 `\"`,使用静态文件名可以避免这个问题,见下面的 Jekyll-like 文件名。 -{% endnote %} - -## Jekyll-like 文件名 - -设置 [dynamicPartials][dynamicPartials] 为 `false` 来启用 Jekyll-like 文件名,这时文件名不需要用引号包含,会被当作字面量处理。 这样的字符串里面仍然支持 Liquid 输出和过滤器,例如: - -```liquid -{% include prefix/{{ page.my_variable }}/suffix %} -``` - -这样文件名里的 `"` 就不用转义了。 - -```liquid -{% include prefix/{{name | append: ".html"}} %} -``` - -## Jekyll include - -{% since %}v9.33.0{% endsince %} - -[jekyllInclude][jekyllInclude] 用来启用 Jekyll-like include 语法。默认为 `false`,当设置为 `true` 时: - -- 默认启用静态文件名:`dynamicPartials` 的默认值变为 `false`(而非 `true`)。但你也可以把它设置回 `true`。 -- 参数的键和值之间由 `=` 分隔(本来是 `:`)。 -- 参数放到了 `include` 变量下,而非当前作用域。 - -例如下面的模板: - -```liquid -{% include article.html header="HEADER" content="CONTENT" %} -``` - -其中 `article.html` 的内容是: - -```liquid -
-
{{include.header}}
- {{include.content}} -
-``` - -注意我们通过 `include.header` 引用第一个参数,而不是 `header`。输出如下: - -```html -
-
HEADER
- CONTENT -
-``` - -[extname]: /api/interfaces/LiquidOptions.html#extname -[root]: /api/interfaces/LiquidOptions.html#root -[dynamicPartials]: /api/interfaces/LiquidOptions.html#dynamicPartials -[jekyllInclude]: /api/interfaces/LiquidOptions.html#jekyllInclude diff --git a/docs/source/zh-cn/tags/increment.md b/docs/source/zh-cn/tags/increment.md deleted file mode 100644 index 721491f29..000000000 --- a/docs/source/zh-cn/tags/increment.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: Increment ---- - -{% since %}v1.9.1{% endsince %} - -创建一个新的数字类型的变量,每次调用都把它的值加一。第一次为 `0`。 - -输入 -```liquid -{% increment my_counter %} -{% increment my_counter %} -{% increment my_counter %} -``` - -输出 -```text -0 -1 -2 -``` - -在 `increment` 里声明的变量独立于 [assign][assign] 或 [capture][capture] 创建的变量。 - -下面的例子中通过 `assign` 创建了变量 `var`。然后用 `increment` 标签在同名变量上多次递增。注意 `increment` 标签不会影响 `assign` 创建的 `var` 的值。 - -输入 -```liquid -{% assign var = 10 %} -{% increment var %} -{% increment var %} -{% increment var %} -{{ var }} -``` - -输出 -```text -0 -1 -2 -10 -``` - -[assign]: ./assign.html -[capture]: ./capture.html diff --git a/docs/source/zh-cn/tags/inline_comment.md b/docs/source/zh-cn/tags/inline_comment.md deleted file mode 100644 index 5b688d51c..000000000 --- a/docs/source/zh-cn/tags/inline_comment.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "#(单行注释)" ---- - -{% since %}v9.38.0{% endsince %} - -在 Liquid 模板中添加注释,注释标签内的文字不会被输出。 - -输入 -```liquid -注释标签内的东西都不会输出。 -{% # this is an inline comment %} -但每行都必须以 '#' 开头。 -{% - # this is a comment - # that spans multiple lines -%} -``` - -输出 -```text -注释标签内的东西都不会输出。 -但每行都必须以 '#' 开头。 -``` - -在 `liquid` 标签里也可以使用注释标签。 - -```liquid -{% liquid - # required args - assign product = collection.products.first - - # optional args - assign should_show_border = should_show_border | default: true - assign should_highlight = should_highlight | default: false -%} -``` - -但注释标签不能用于把其他标签注释掉。这时应该使用 `comment` 标签来临时禁用其他标签。 - -输入 -```liquid -{%- # {% echo 'Welcome to LiquidJS!' %} -%} -{% comment %}{% echo 'Welcome to LiquidJS!' %}{% endcomment %} -``` - -输出 -```text - -%} -``` diff --git a/docs/source/zh-cn/tags/layout.md b/docs/source/zh-cn/tags/layout.md deleted file mode 100644 index 79bfef443..000000000 --- a/docs/source/zh-cn/tags/layout.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: Layout ---- - -{% since %}v1.9.1{% endsince %} - -## 使用布局模板 - -套用模板 [根路径][root] 下的某个布局模板中。 - -```liquid -{% layout 'footer.liquid' %} -``` - -设置 [extname][extname] 选项为 `".liquid"` 后上面的 `.liquid` 后缀就可以省略了,等价于: - -```liquid -{% layout 'footer' %} -``` - -通过 `layout` 渲染一个子模板时,它内部的代码可以访问父模板的变量,但父模板中不能访问它里面定义的变量。 - -## 变量传递 - -当前模板里定义的变量可以通过 `layout` 标签的参数列表传递给布局模板: - -```liquid -{% assign my_variable = 'apples' %} -{% layout 'name', my_variable: my_variable, my_other_variable: 'oranges' %} -``` - -## 块 - -布局模板中可以包含若干 `block` 标签,这些 `block` 渲染时会按照子模板提供的内容进行填充。例如我们有布局模板 `default-layout.liquid`: - -``` -Header -{% block content %}My default content{% endblock %} -Footer -``` - -它被子模板 `page.liquid` 通过 `layout` 标签引用: - -``` -{% layout "default-layout" %} -{% block content %}My page content{% endblock %} -``` - -`page.liquid` 的渲染结果将会是: - -``` -Header -My page content -Footer -``` - -{% note tip 块 %} - -{% endnote %} - -[extname]: /api/interfaces/LiquidOptions.html#extname -[root]: /api/interfaces/LiquidOptions.html#root diff --git a/docs/source/zh-cn/tags/liquid.md b/docs/source/zh-cn/tags/liquid.md deleted file mode 100644 index ca74ffec9..000000000 --- a/docs/source/zh-cn/tags/liquid.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Liquid ---- - -{% since %}v9.31.0{% endsince %} - -通过 liquid 标签可以在一个分隔符中使用多个标签, 使 Liquid 逻辑书写更简洁。 - -## liquid - -输入 -```liquid -{% liquid - assign names = 'Bob, Sally' | split: ', ' - - for name in names - echo 'Hello, ' | append: name - unless forloop.last - echo ', ' - endunless - endfor -%} -``` - -输出 -```text -Hello, Bob, Hello Sally -``` diff --git a/docs/source/zh-cn/tags/overview.md b/docs/source/zh-cn/tags/overview.md deleted file mode 100644 index 3ca4a5881..000000000 --- a/docs/source/zh-cn/tags/overview.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: 标签 -description: 每个 Liquid 标签的描述和示例 ---- - -LiquidJS 支持 Liquid 语法中具体业务无关的标签,包含 [shopify/liquid 核心][shopify/liquid] 里的所有标签。这部分包含了所有 LiquidJS 支持的标签的文档和使用示例。 - -LiquidJS 支持十几个过滤器,可以分为如下几类: - -类别 | 用途 | 标签 ---- | --- | --- -迭代 | 遍历一个集合 | for, cycle, tablerow -控制流 | 控制模板渲染的执行分支 | if, unless, elif, else, case, when -变量 | 定义和修改变量 | assign, increment, decrement, capture, echo -文件 | 引入或继承其他模板 | render, include, layout -语言 | 暂时禁用 Liquid 语法 | # (单行注释), raw, comment, liquid - -[shopify/liquid]: https://github.com/Shopify/liquid diff --git a/docs/source/zh-cn/tags/raw.md b/docs/source/zh-cn/tags/raw.md deleted file mode 100644 index 71f7c4599..000000000 --- a/docs/source/zh-cn/tags/raw.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Raw ---- - -{% since %}v1.9.1{% endsince %} - -`raw` 标签可以暂时禁用 LiquidJS 的语法。生成和 Liquid 冲突的语言(比如 Nunjucks、Handlebars)时很有用。 - -输入 -```liquid -{% raw %} - In Handlebars, {{ this }} will be HTML-escaped, but - {{{ that }}} will not. -{% endraw %} -``` - -输出 -```text -In Handlebars, {{ this }} will be HTML-escaped, but {{{ that }}} will not. -``` diff --git a/docs/source/zh-cn/tags/render.md b/docs/source/zh-cn/tags/render.md deleted file mode 100644 index c6eb95a60..000000000 --- a/docs/source/zh-cn/tags/render.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: Render ---- - -{% since %}v9.2.0{% endsince %} - -## 基本使用 - -### 渲染一个模板 - -从模板 [根路径][root] 引入一个模板: - -```liquid -{% render 'footer.liquid' %} -``` - -设置 [extname][extname] 选项为 `".liquid"` 后上面的 `.liquid` 后缀就可以省略了,等价于: - -```liquid -{% render 'footer' %} -``` - -{% note info 变量作用域 %} -通过 `render` 渲染一个子模板时,它内部的代码不能访问父模板的变量,父模板中也不能访问它里面定义的变量。这个封装会让模板代码更容易理解和维护。{% endnote %} - -### 变量传递 - -父模板里定义的变量可以通过 `render` 标签的参数列表传递给子模板: - -```liquid -{% assign my_variable = 'apples' %} -{% render 'name', my_variable: my_variable, my_other_variable: 'oranges' %} -``` - -[全局变量][globals] 不需要传递,所有文件都可以访问它们。 - -## 参数 - -### `with` 参数 - -使用 `with...as` 语法可以给子模板传递一个变量: - -```liquid -{% assign featured_product = all_products['product_handle'] %} -{% render 'product' with featured_product as product %} -``` - -上面的例子中,子模板中 `product` 会保有父模板中的 `featured_product` 变量的值。 - -### `for` 参数 - -用 `for...as` 语法可以对可枚举对象的每一个值渲染一次子模板: - -```liquid -{% assign variants = product.variants %} -{% render 'variant' for variants as variant %} -``` - -上面的例子中,对 `product` 的每个 `variants` 是指都会渲染一次子模板。子模板中 `variant` 变量会保有父模板中的 `product.variants` 中对应元素的值。 - -{% note tip forloop 对象 %} 使用 for 参数时,在子模板中可以访问 forloop 对象。{% endnote %} - -[extname]: /api/interfaces/LiquidOptions.html#extname -[root]: /api/interfaces/LiquidOptions.html#root -[globals]: /api/interfaces/LiquidOptions.html#globals diff --git a/docs/source/zh-cn/tags/tablerow.md b/docs/source/zh-cn/tags/tablerow.md deleted file mode 100644 index 282223afb..000000000 --- a/docs/source/zh-cn/tags/tablerow.md +++ /dev/null @@ -1,130 +0,0 @@ ---- -title: Table Row ---- - -{% since %}v1.9.1{% endsince %} - -生成一个 HTML 表示,上下必须用 `` 和 `
` HTML 标签包裹起来。 - -## 基本使用 - -输入 -```liquid - -{% tablerow product in collection.products %} - {{ product.title }} -{% endtablerow %} -
-``` - -输出 -```html - - - - - - - - - -
- Cool Shirt - - Alien Poster - - Batman Poster - - Bullseye Shirt - - Another Classic Vinyl - - Awesome Jeans -
-``` - -## 参数 - -### cols - -定义表格的列数。 - -输入 -```liquid -{% tablerow product in collection.products cols:2 %} - {{ product.title }} -{% endtablerow %} -``` - -输出 -```html - - - - - - - - - - - - - -
- Cool Shirt - - Alien Poster -
- Batman Poster - - Bullseye Shirt -
- Another Classic Vinyl - - Awesome Jeans -
-``` - -### limit - -限制迭代次数。 - -```liquid -{% tablerow product in collection.products cols:2 limit:3 %} - {{ product.title }} -{% endtablerow %} -``` - -### offset - -从指定的下标处开始循环。 - -```liquid -{% tablerow product in collection.products cols:2 offset:3 %} - {{ product.title }} -{% endtablerow %} -``` - -### range - -定义一个用于循环的数字范围。可以用字面量定义范围,也可以用变量定义范围。 - -```liquid - - -{% assign num = 4 %} - -{% tablerow i in (1..num) %} - {{ i }} -{% endtablerow %} -
- - - - -{% tablerow i in (3..5) %} - {{ i }} -{% endtablerow %} -
-``` diff --git a/docs/source/zh-cn/tags/unless.md b/docs/source/zh-cn/tags/unless.md deleted file mode 100644 index a76ed3121..000000000 --- a/docs/source/zh-cn/tags/unless.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Unless ---- - -{% since %}v1.9.1{% endsince %} - -和 `if` 相反 —— 条件 **不满足** 时执行代码块。 - -输入 -```liquid -{% unless product.title == "Awesome Shoes" %} - These shoes are not awesome. -{% endunless %} -``` - -输出 -```text -These shoes are not awesome. -``` - -等价于执行下面的代码: - -```liquid -{% if product.title != "Awesome Shoes" %} - These shoes are not awesome. -{% endif %} -``` diff --git a/docs/source/zh-cn/tutorials/access-scope-in-filters.md b/docs/source/zh-cn/tutorials/access-scope-in-filters.md deleted file mode 100644 index e93d0f184..000000000 --- a/docs/source/zh-cn/tutorials/access-scope-in-filters.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: 过滤器里访问上下文 ---- - -在 [注册过滤器和标签][register-filters] 里介绍过,可以在函数参数里直接获得过滤器的参数: - -```javascript -// Usage: {{ 1 | add: 2, 3 }} -// Output: 6 -engine.registerFilter('add', (initial, arg1, arg2) => initial + arg1 + arg2) -``` - -但有些过滤器还需要访问当前上下文的变量,比如把 URL 路径转换为完整的 URL 时,需要访问上下文的 `origin` 变量: - -```javascript -// Usage: {{ '/index.html' | fullURL }} -// Scope: { origin: "https://liquidjs.com" } -// Output: https://liquidjs.com/index.html - -engine.registerFilter('fullURL', function (path) { - const origin = this.context.get(['origin']) - return new URL(path, origin).toString() -}) -``` - -见这个 JSFiddle:。 - -{% note warn 箭头函数 %} -在箭头函数里 `this` 会绑定到当前 JavaScript 上下文,你需要用 `function(){}` 来替代 `()=>{}` 语法,才能正确地访问 `this.context`。 -{% endnote %} - -[register-filters]: /tutorials/register-filters-tags.html diff --git a/docs/source/zh-cn/tutorials/caching.md b/docs/source/zh-cn/tutorials/caching.md deleted file mode 100644 index 290d9b165..000000000 --- a/docs/source/zh-cn/tutorials/caching.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: 缓存 ---- - -在典型的网站项目中,同一个模板文件可能会反复地用不同数据去渲染。在生产环境下模板文件的内容不太会发生变化(除非重新部署了服务),因此可以把从磁盘读取的文件内容和解析得到的模板结构(AST)缓存下来重复使用来节省渲染时间。 - -LiquidJS 在这一方面比较灵活,提供了多种不同的方式来达到提升性能的目的。 - -## 手动缓存 - -[.parse()][parse], [.parseFile()][parseFile], [.parseFileSync()][parseFileSync] API 可以用来把字符串或文件解析成模板。得到的模板可以用不同的数据去重复地渲染得到不同的 HTML。 - -从字符串解析: - -```javascript -var tpl = engine.parse('{{name | capitalize}}'); - -engine.renderSync(tpl, {name: 'alice'}) // 'Alice' -engine.renderSync(tpl, {name: 'bob'}) // 'Bob' -``` - -从文件解析: - -```javascript -var tpl = engine.parseFileSync('hello'); // contents of `hello.liquid`: {{name}} - -engine.renderSync(tpl, {name: 'alice'}) // 'Alice' -engine.renderSync(tpl, {name: 'bob'}) // 'Bob' -``` - -上述代码中字符串或文件只被解析了一次,可以反复利用去渲染不同的数据。有很多模板文件时可以把 `tpl` 变量存在 `Map` 中,后续再 `.render()` 时直接从 Map 中拿出解析好的模板去渲染。 - -## `cache` 选项 - -如果你只用 `.renderFile()` 和 `.renderFileSync()` 也可以直接设置 [cache][cache] 选项,LiquidJS 会帮你缓存。 - -```javascript -var { Liquid } = require('liquidjs'); -var engine = new Liquid({ - cache: true -}); - -// LiquidJS 将会解析 hello.liquid 然后用 {name: 'alice'} 渲染它 -engine.renderFileSync('hello', {name: 'alice'}) - -// LiquidJS 会找到上次 hello.liquid 解析的结果模板,再用 {name: 'bob'} 渲染它 -engine.renderFileSync('hello', {name: 'bob'}) -``` - -[parse]: /api/classes/Liquid.html#parse -[cache]: /api/interfaces/LiquidOptions.html#cache -[parseFile]: /api/classes/Liquid.html#parseFile -[parseFileSync]: /api/classes/Liquid.html#parseFileSync -[renderFile]: /api/classes/Liquid.html#renderFile -[renderFileSync]: /api/classes/Liquid.html#renderFileSync diff --git a/docs/source/zh-cn/tutorials/contribution-guidelines.md b/docs/source/zh-cn/tutorials/contribution-guidelines.md deleted file mode 100644 index b5bc98875..000000000 --- a/docs/source/zh-cn/tutorials/contribution-guidelines.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: 贡献指南 ---- - -## Star LiquidJS 👉👉👉 [![harttle/liquidjs](https://img.shields.io/github/stars/harttle/liquidjs?style=flat-square)][liquidjs] - -Star 是支持 LiquidJS 最重要的方式,也是最简单的方式:通过提升排名来让更多人了解 LiquidJS,让它得到更好的改进。 - -## 发起 Pull Request - -开发和构建描述在这篇文档里 [CONTRIBUTING.md](https://github.com/harttle/liquidjs/blob/master/CONTRIBUTING.md)。 - -**代码风格**:LiquidJS 采用 [standard](https://github.com/standard/eslint-config-standard) 和 [@typescript-eslint/recommended](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/src/configs/recommended.json) 规则。 - -**测试**:确保你改动之后测试仍然可以通过 `npm test` - -**提交消息**:请遵守 [Angular 提交消息规范](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#commits),尤其注意 [type 标识](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type),semantic-release 机器人依赖这个标识自动发布。 - -**向后兼容**:请考虑向后(之前的旧的版本)兼容。LiquidJS 被用于很多层的软件,包括底层库、编译器、站点生成器、 Web 服务器。对多数最终用户来说,驱动或请求整个系统做一次主版本升级是很难办到的。 - -## 资金支持 - -LiquidJS 是开源和免费的,但支持 [Open Collective][oc] 和 [Github Sponsors](https://github.com/sponsors/harttle) 赞助,请通过 Twitter (harttleharttle) 或邮件 (harttleharttle at gmail) 联系我,把您加到 [贡献者列表](https://github.com/harttle/liquidjs#contributors-) 中。 - -[oc]: https://opencollective.com/liquidjs/ -[shopify/liquid]: https://shopify.github.io/liquid/ -[caniuse-promises]: http://caniuse.com/#feat=promises -[pp]: https://github.com/taylorhakes/promise-polyfill -[tutorial]: https://shopify.github.io/liquid/basics/introduction/ -[liquidjs]: https://github.com/harttle/liquidjs diff --git a/docs/source/zh-cn/tutorials/differences.md b/docs/source/zh-cn/tutorials/differences.md deleted file mode 100644 index 9cdf3b22d..000000000 --- a/docs/source/zh-cn/tutorials/differences.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: 和 Shopify/liquid 的区别 ---- - -## 兼容性 - -LiquidJS 一直很重视兼容于 Ruby 版本的 Liquid。Liquid 模板语言最初由 [Ruby 实现][ruby-liquid],用于 Shopify,Jekyll 以及 Github Pages,它是 Ruby 里最流行的模板引擎之一。因此由很多人用 LiquidJS 来渲染他们的 Shopify 主题和 Jekyll 站点。 - -所以“兼容”意味着让这些开发者有很好的使用体验: - -- **LiquidJS 应当能够渲染语法正确的 Liquid 模板**。例如 `forloop.index` 应该是 1 开始的下表,`nil` 应该渲染成空字符串而不是 `undefined` 等。即使有些功能(例如 [#236][#236])用 JavaScript 很难实现,但至少 LiquidJS 会尝试实现所有的 Liquid 语义。 -- **所有 [shopify/liquid][ruby-liquid] 里的标签和过滤器 LiquidJS 都要实现**。这之外有些业务逻辑相关的标签/过滤器尤其是 Shopify 平台上的那些,应该维护在 [插件][plugins] 里。但是这其中有一些很有用的标签(比如 `{% layout %}`)LiquidJS 也会考虑实现,可以去开个 Issue 讨论一下。 - -同时,既然现在用 JavaScript 实现了,那 Liquid 应该有更强的功能: - -* **完全支持异步**。所有过滤器和标签都可以实现为异步,只需要返回 `Promise` 即可。 -* **同时支持同步**。对一些非 I/O 密集的场景,同步渲染会更快。只要模板包含的标签和过滤器都支持同步,你就可以调用类似 `.renderSync()` 这样的 API。所有内置标签和过滤器都同时支持同步和异步。 -* **[抽象文件系统][afs]**。和异步功能一起使用,LiquidJS 可以实现渲染数据库里的模板 [#414][#414],远程 HTTP 服务器上的模板 [#485][#485],等等。 -* **额外的标签和过滤器**。比如 `layout` 和 `json`。 - -## 区别 - -[Shopify/liquid][ruby-liquid] 中的所有标签和过滤器 LiquidJS 都支持,但不包括 Shopify 主题中业务逻辑相关的标签和过滤器(如果你在找这些标签可以参考 [插件列表][plugins],也欢迎把你的插件添加到列表中)。尽管原则上我们尽力兼容于 Shopify/liquid,但仍然存在一些区别: - -* 真和假。在 LiquidJS 中 `undefined`, `null`, `false` 是假,之外的都是真;在 Ruby 中 `nil` 和 `false` 是假,其他都是真。见 [#26][#26]。 -* 数字。JavaScript 不区分浮点数和整数,因此缺失一部分整数算术,见 [#59][#59]。此外 `size` 过滤器作用于数字时总是返回零,而不是 Ruby 中的浮点数或整数的内存大小。 -* 输出字符串。基本类型的输出已经和 Shopify/liquid 对齐,但是仍然存在一些区别。比如在 Shopify/liquid 中 `strip` 会返回 inspect 字符串,但 LiquidJS `strip` 只是简单地把输入转换为字符串 [#852][#852]。 -* Drop 中的 [.to_liquid()](https://github.com/Shopify/liquid/wiki/Introduction-to-Drops) 替换为 `.toLiquid()`。 -* 数据的 [.to_s()](https://www.rubydoc.info/gems/liquid/Liquid/Drop) 替换为 `.toString()`。 -* 对象的迭代顺序。JavaScript 对象的迭代顺序是插入顺序和数字键递增顺序的组合,但 Ruby Hash 中只是插入顺序(JavaScript 字面量 Object 和 Ruby 字面量 Hash 的插入顺序解释也不同)。 -* 排序稳定性。shopify/liquid 和 LiquidJS 都没有定义 [sort][sort] 过滤器的稳定性在,它取决于 Ruby/JavaScript 内置的排序算法,在 Node.js 12+ 和 Google Chrome 70+ LiquidJS 的排序是 [稳定的][stable-sort]。 -* shopify/liquid 允许过滤器尾部的未匹配字符,但 LiquidJS 不允许。这就是说如果过滤器参数前忘记写冒号比如 `{%raw%}{{ "a b" | split " "}}{%endraw%}` LiquidJS 会抛出异常。这是为了提升 Liquid 模板的易用性,参考 [#208][#208] 和 [#212][#212]。 -* LiquidJS 比 [Liquid 语言][liquid] 有更多的标签和过滤器: - * LiquidJS 自己定义的标签:[layout][layout]、[render][render] 和相应的 `block`。 - * LiquidJS 自己定义的过滤器:[json][json]。 - * 从 [Shopify][shopify-tags] 借来的不依赖 Shopify 平台的标签/过滤器。 - * 从 [Jekyll][jekyll-filters] 借来的不依赖 Jekyll 框架的标签/过滤器。 -* 有些过滤器和标签表现不同:比如 [date][date],非法的标签(比如重复的 `else`,`endif` 的多余参数)在 LiquidJS 中会抛出异常。 - -[layout]: ../tags/layout.html -[render]: ../tags/render.html -[json]: https://liquidjs.com/filters/json.html -[#26]: https://github.com/harttle/liquidjs/pull/26 -[#59]: https://github.com/harttle/liquidjs/issues/59 -[#208]: https://github.com/harttle/liquidjs/issues/208 -[#212]: https://github.com/harttle/liquidjs/issues/212 -[#236]: https://github.com/harttle/liquidjs/issues/236 -[#414]: https://github.com/harttle/liquidjs/discussions/414 -[#485]: https://github.com/harttle/liquidjs/discussions/485 -[#852]: https://github.com/harttle/liquidjs/discussions/852 -[sort]: https://liquidjs.com/filters/sort.html -[stable-sort]: https://v8.dev/features/stable-sort -[plugins]: ./plugins.html#插件列表 -[ruby-liquid]: https://github.com/Shopify/liquid -[afs]: https://liquidjs.com/tutorials/render-file.html#Abstract-File-System -[liquid]: https://shopify.github.io/liquid/basics/introduction/ -[shopify-tags]: https://shopify.dev/docs/api/liquid/tags -[jekyll-filters]: https://jekyllrb.com/docs/liquid/filters/ diff --git a/docs/source/zh-cn/tutorials/drops.md b/docs/source/zh-cn/tutorials/drops.md deleted file mode 100644 index 7f41c8bd9..000000000 --- a/docs/source/zh-cn/tutorials/drops.md +++ /dev/null @@ -1,201 +0,0 @@ ---- -title: Liquid Drop ---- - -LiquidJS 还提供了一种类似于 [Shopify Drop][shopify-drops] 的机制,用于为模板作者提供在自定义解析变量值的功能。 - -{% note info JavaScript 中的 Drop %} -Drop 接口在 LiquidJS 中实现方式与内置过滤器和其他模板功能不同。由于 LiquidJS 在 JavaScript 中运行,自定义 Drop 在 JavaScript 中一定需要重新实现。JavaScript 类与 Ruby 类之间没有兼容性可言。 -{% endnote %} - -## 基本用法 - -```javascript -import { Liquid, Drop } from 'liquidjs' - -class SettingsDrop extends Drop { - constructor() { - super() - this.foo = 'FOO' - } - bar() { - return 'BAR' - } -} - -const engine = new Liquid() -const template = `foo: {{settings.foo}}, bar: {{settings.bar}}` -const context = { settings: new SettingsDrop() } -// 输出: "foo: FOO, bar: BAR" -engine.parseAndRender(template, context).then(html => console.log(html)) -``` - -[Runkit 链接](https://runkit.com/embed/2is7di4mc7kk) - -如上所示,除了从上下文作用域中读取属性外,还可以调用方法。您只需创建一个继承自 `Drop` 的自定义类。 - -{% note tip 异步方法 %} -LiquidJS 完全支持异步,您可以在 Drop 的方法中安全地返回 Promise,或将 Drop 的方法定义为 `async`。 -{% endnote %} - -## liquidMethodMissing - -如果属性名不能静态地确定的情况下,可以利用 `liquidMethodMissing` 来动态解析变量的值。 - -```javascript -import { Liquid, Drop } from 'liquidjs' - -class SettingsDrop extends Drop { - liquidMethodMissing(key) { - return key.toUpperCase() - } -} - -const engine = new Liquid() -// 输出: "COO" -engine.parseAndRender("{{settings.coo}}", { settings: new SettingsDrop() }) - .then(html => console.log(html)) -``` - -`liquidMethodMissing` 支持 Promise,这意味着您可以在其中进行异步调用。一个更有用的例子是通过使用 Drop 动态地从数据库获取值。通过使用 Drop,您可以避免将每个属性都硬编码到上下文中。例如: - -```javascript -import { Liquid, Drop } from 'liquidjs' - -class DBDrop extends Drop { - async liquidMethodMissing(key) { - const record = await db.getRecordByKey(key) - return record.value - } -} - -const engine = new Liquid() -const context = { db: new DBDrop() } -engine.parseAndRender("{{db.coo}}", context).then(html => console.log(html)) -``` - -## valueOf - -Drop 可以实现一个 `valueOf()` 方法,用于在输出中替换自身。例如: - -```javascript -import { Liquid, Drop } from 'liquidjs' - -class ColorDrop extends Drop { - valueOf() { - return 'red' - } -} - -const engine = new Liquid() -const context = { color: new ColorDrop() } -// 输出: "red" -engine.parseAndRender("{{color}}", context).then(html => console.log(html)) -``` - -## toLiquid - -`toLiquid()` 不是 `Drop` 的方法,但它可以用于返回一个 `Drop`。在您有一个上下文中固定结构且不能更改其值的情况下,您可以实现 `toLiquid()`,以便让 LiquidJS 使用返回的值而不是自身来渲染模板。 - -```javascript -import { Liquid, Drop } from 'liquidjs' - -const context = { - person: { - firstName: "Jun", - lastName: "Yang", - name: "Jun Yang", - toLiquid: () => ({ - firstName: this.firstName, - lastName: this.lastName, - // 使用不同的 `name` - name: "Yang, Jun" - }) - } -} - -const engine = new Liquid() -// 输出: "Yang, Jun" -engine.parseAndRender("{{person.name}}", context).then(html => console.log(html)) -``` - -当然,您还可以在 `toLiquid()` 方法中返回一个 `PersonDrop` 实例,并在 `PersonDrop` 中实现此功能: - -```javascript -import { Liquid, Drop } from 'liquidjs' - -class PersonDrop extends Drop { - constructor(person) { - super() - this.person = person - } - name() { - return this.person.lastName + ", " + this.person.firstName - } -} - -const context = { - person: { - firstName: "Jun", - lastName: "Yang", - name: "Jun Yang", - toLiquid: function () { return new PersonDrop(this) } - } -} - -const engine = new Liquid() -// 输出: "Yang, Jun" -engine.parseAndRender("{{person.name}}", context).then(html => console.log(html)) -``` - -{% note info toLiquid()valueOf() 的区别 %} -
    -
  • valueOf() 通常用来定义当前变量如何渲染,toLiquid() 通常用来把一个对象转换为 Drop 或另一个提供给模板的 scope。
  • -
  • valueOf() 是 Drop 才有的方法;而 toLiquid() 可以用在任何 scope 对象上。
  • -
  • valueOf() 是在自己即将被渲染时,用来替代自己;而 toLiquid() 在即将读取它的属性时才会被调用。
  • -
-{% endnote %} - -## 特殊 Drop - -LiquidJS 本身实现了几个内置 Drop,以促进模板编写。此部分与 Shopify Liquid 兼容,因为我们需要模板具有可移植性。 - -### blank - -用于检查字符串变量是否为 `false`、`null`、`undefined`、空字符串或字符串仅包含空白字符。 - -```liquid -{% unless author == blank %} - {{author}} -{% endif %} -``` - -### empty - -用于检查数组、字符串或对象是否为空。 - -```liquid -{% if authors == empty %} - 作者列表为空 -{% endif %} -``` - -{% note info empty 的实现 %} -对于数组和字符串,LiquidJS 检查它们的 `.length` 属性。对于对象,LiquidJS 调用 `Object.keys()` 来检查它是否有键。 -{% endnote %} - -### nil - -`nil` Drop 用于检查变量是否未定义或定义为 `null` 或 `undefined`,本质上等同于 JavaScript 的 `== null` 检查。 - -```liquid -{% if notexist == nil %} - 空变量 -{% endif %} -``` - -### 其他 Drop - -仍然有一些特定标签的 Drop,例如 `forloop`、`tablerowloop`、`block`,这些在各自的标签文档中有详细介绍。 - -[shopify-drops]: https://github.com/Shopify/liquid/wiki/Introduction-to-Drops diff --git a/docs/source/zh-cn/tutorials/escaping.md b/docs/source/zh-cn/tutorials/escaping.md deleted file mode 100644 index 042bcc34e..000000000 --- a/docs/source/zh-cn/tutorials/escaping.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: 转义 ---- - -LiquidJS 种转义有两种含义: - -1. 输出语言的转义,即 HTML 转义。用来让输出的变量不包含 HTML 特殊字符,不影响 HTML 的结构,也就是输出 HTML 安全的字符串。 -2. 语言自己的转义,即 Liquid 转义。用来输出包含对于 Liquid 语言来说是特殊字符的字符串,比如你在使用 Liquid 模板语言来编写一篇介绍 Liquid 语法的文章时就会需要 Liquid 转义。 - -## HTML 转义 - -默认情况下输出是不转义的,但你可以用 [escape][escape] 过滤器来做 HTML 转义: - -输入 -```liquid -{{ "1 < 2" | escape }} -``` - -输出 -```text -1 < 2 -``` - -LiquidJS 也提供了其他过滤器来支持不同的转义需求:[escape_once][escape_once], [newline_to_br][newline_to_br], [strip_html][strip_html]。 - -当输出的变量不被信任时,可以把 [outputEscape][outputEscape] 参数设置为 `"escape"` 来启用默认 HTML 转义。这种情况下,如果你需要某个输出不被转义,则需要使用 [raw][raw] 过滤器: - -输入 -```liquid -{{ "1 < 2" }} -{{ "" | raw }} -``` - -输出 -```text -1 < 2 - -``` - -## Liquid 转义 - -为了输出 Liquid 的特殊字符比如 `{{` 和 `{%`,你需要 [raw][raw] 标签。 - -输入 -```liquid -{% raw %} - In LiquidJS, {{ this | escape }} will be HTML-escaped, but - {{{ that }}} will not. -{% endraw %} -``` - -输出 -```text -In LiquidJS, {{ this | escape }} will be HTML-escaped, but -{{{ that }}} will not. -``` - -Within strings literals in LiquidJS template, `\` can be used to escape special characters in string syntax. For example: - -输入 -```liquid -{{ "\"" }} -``` - -输出 -```liquid -" -``` - -[outputEscape]: ./options.html#outputEscape -[escape]: ../filters/escape.html -[raw]: ../filters/raw.html -[escape_once]: ../filters/escape.html -[strip_html]: ../filters/strip_html.html -[newline_to_br]: ../filters/newline_to_br.html -[raw]: ../tags/raw.html diff --git a/docs/source/zh-cn/tutorials/intro-to-liquid.md b/docs/source/zh-cn/tutorials/intro-to-liquid.md deleted file mode 100644 index 2e9586561..000000000 --- a/docs/source/zh-cn/tutorials/intro-to-liquid.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: Liquid 模板语言 -description: Liquid 模板语言的介绍,和一些示例代码 ---- - -LiquidJS 是一个简单的、安全的、兼容 Shopify 的、纯 JavaScript 编写的模板引擎。这个项目的目的是为 JavaScript 社区提供一个 Liquid 模板引擎的实现。Liquid 最初用 Ruby 实现并用于 Github Pages, Jekyll 和 Shopify,参考 [和 Shopify/liquid 的区别][diff]。 - -LiquidJS 语法相对简单。LiquidJS 中有两种标记: - -- **标签**。标签由标签名和参数构成,由 `{%raw%}{%{%endraw%}` 和 `%}` 包裹。 -- **输出**。输出由一个值和一组可选的过滤器构成,由 `{%raw%}{{{%endraw%}` 和 `}}` 包裹。 - -{% note info 在线示例 %} -在进一步了解细节之前,这里有一个在线示例:。 -{% endnote %} - -## 输出 - -**输出** 用于转换和输出变量到 HTML。下面的模板将会把 `username` 的值插入到 input 的 `value`: - -```liquid - -``` - -*输出* 里的值可以在输出之前经过若干个 **过滤器** 的转换。比如在变量后面追加一个字符串: - -```liquid -{{ username | append: ", welcome to LiquidJS!" }} -``` - -过滤器可以级联,用起来像管道一样: - -```liquid -{{ username | append: ", welcome to LiquidJS!" | capitalize }} -``` - -[这里](../filters/overview.html) 是 LiquidJS 支持的完整的过滤器列表。 - -## 标签 - -**标签** 用于控制模板渲染过程,操作模板变量,和其他模板交互等。例如 `assign` 可以用来定义一个模板中可以使用的变量: - -```liquid -{% assign foo = "FOO" %} -``` - -一般标签成对地出现,一个开始标签和一个对应的结束标签,比如: - -```liquid -{% if foo == "FOO" %} - Variable `foo` equals "FOO" -{% else %} - Variable `foo` not equals "FOO" -{% endif %} -``` - -[这里](../tags/overview.html) 是 LiquidJS 支持的完整的标签列表。 - -[shopify/liquid]: https://github.com/Shopify/liquid -[diff]: ./differences.html diff --git a/docs/source/zh-cn/tutorials/migrate-to-9.md b/docs/source/zh-cn/tutorials/migrate-to-9.md deleted file mode 100644 index 76950dbf7..000000000 --- a/docs/source/zh-cn/tutorials/migrate-to-9.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: 迁移到 LiquidJS 9 ---- - -LiquidJS 9 有一些基础性的改进,包括一些缺陷修复、新特性、性能提升,也有一些不兼容的变更。 - -## 新特性 - -* 同步渲染:新增了 renderSync, parseAndRenderSync, renderFileSync API -* 新的工具:Expression 和 Tokenizer - -## 修复 - -* 布尔逻辑运算顺序,见 [#130](https://github.com/harttle/liquidjs/issues/130); -* `break` 和 `continue` 会忽略它们之前的代码,见 [#123](https://github.com/harttle/liquidjs/issues/123); -* React.js 示例无法正确 yarn install,见 [#145](https://github.com/harttle/liquidjs/issues/145); -* 有时没有正确地等待 Promise 类型的 Drops。 - -## 性能 - -* 目标平台提升到 Node.js 8 引起的性能提升(去掉了一些 Polyfill),见 [#137](https://github.com/harttle/liquidjs/issues/137); -* 内存使用降低了 57.5%,见 [#202](https://github.com/harttle/liquidjs/pull/202); -* 渲染性能提升了 100.3%,见 [#205](https://github.com/harttle/liquidjs/pull/205)。 - -## 不兼容的变更 - -* LiquidJS 不再有默认导出了,以后要使用 `import {Liquid} from 'liquidjs'` 语法。使用 UMD 包里的 `window.Liquid` 也需要改为 `window.liquidjs.Liquid`; -* 移除了重复的静态方法 `Liquid.evalValue`,统一使用示例方法 `liquid.evalValue`; -* 支持的最低目标平台为 Node.js 8,CJS 包(Node.js 下的主入口)不再支持 Node.js ≤ 6 了,ESM(dist/liquid.browser.esm.js)和 UMD(dist/liquid.browser.umd.js, dist/liquid.browser.min.js)包不受影响。 \ No newline at end of file diff --git a/docs/source/zh-cn/tutorials/operators.md b/docs/source/zh-cn/tutorials/operators.md deleted file mode 100644 index 68fe1a4d0..000000000 --- a/docs/source/zh-cn/tutorials/operators.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: 运算符 ---- - -LiquidJS 运算符非常简单也很特别,只支持两类运算符: - -* 比较运算符:`==`, `!=`, `>`, `<`, `>=`, `<=` -* 逻辑运算符:`not`, `or`, `and`, `contains` - -因此普通的数学运算是不支持的,比如 `{% raw %}{{a + b}}{% endraw %}`。它的替代方案是过滤器 `{% raw %}{{ a | plus: b}}{% endraw %}`。事实上 `+` 在 LiquidJS 中是一个合法的变量名。 - -## 逻辑运算符 - -### not - -对条件取反。如果条件为假则返回 `true`,如果条件为真则返回 `false`。 - -输入 -```liquid -{% if not user.active %} - 用户未激活 -{% endif %} -``` - -### and - -当两个条件都为真时返回 `true`。 - -输入 -```liquid -{% if user.age >= 18 and user.verified %} - 允许访问 -{% endif %} -``` - -### or - -当至少一个条件为真时返回 `true`。 - -输入 -```liquid -{% if user.isAdmin or user.isModerator %} - 您拥有提升的权限 -{% endif %} -``` - -### contains - -检查字符串是否包含子字符串,或数组是否包含元素。 - -输入 -```liquid -{% if product.title contains "Pack" %} - 这是一个套装 -{% endif %} -``` - -## 优先级 - -1. 比较运算符和 `contains`。所有比较运算符和 `contains` 具有同样的(最高)优先级。 -2. `not` 运算符。它的优先级略高于 `or` 和 `and`。 -3. `or` 和 `and` 运算符。这些逻辑运算符具有同样的(最低)优先级。 - -## 结合性 - -逻辑运算符是右结合的,所以连续的逻辑运算时计算顺序是从右向左,参考 [Shopify][operator-order] 的文档。 - -[operator-order]: https://help.shopify.com/en/themes/liquid/basics/operators#order-of-operations diff --git a/docs/source/zh-cn/tutorials/options.md b/docs/source/zh-cn/tutorials/options.md deleted file mode 100644 index a69442039..000000000 --- a/docs/source/zh-cn/tutorials/options.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -title: 选项 ---- - -[Liquid][liquid] 构造函数接受一个参数对象,用来定义各种模板引擎行为。这些参数都是可选的,比如我可以指定其中一个参数 `cache`: - -```javascript -const { Liquid } = require('liquidjs') -const engine = new Liquid({ - cache: true -}) -``` - -{% note info API 文档 %} -下面的所有选项的概述,希望了解具体的类型和签名,请前往 LiquidOptions | API. -{% endnote %} - -## 缓存 - -**cache** 用来指定是否缓存曾经读取和处理过的模板来提升性能。在生产环境模板会重复渲染的情况会很有用。 - -默认是 `false`,当设置为 `true` 时会启用一个大小为 1024 的 LRU 缓存。当然也可以传一个数字来指定缓存大小。此外还可以是一个自定义的缓存实现,LiquidJS 会通过它来查找和读写文件。详情请参考 [Caching][caching]。 - -## 布局和片段 - -**root** 用来指定 LiquidJS 查找和读取模板的根目录。可以是单个字符串,也可以是一个数组 LiquidJS 会顺序查找。详情请参考 [Render Files][render-file]。 - -**layouts** 和 `root` 具有一样的格式,用来指定 `{% layout %}` 所使用的目录。没有指定时默认为 `root`。 - -**partials** 和 `root` 具有一样的格式,用来指定 `{% render %}` 和 `{% include %}` 所使用的目录。没有指定时默认为 `root`。 - -**relativeReference** 默认为 `true` 用来允许以相对路径引用其他文件。注意被引用的文件仍然需要在对应的 root 目录下。例如可以这样引用一个文件 `{% render ../foo/bar %}`,但需要确保 `../foo/bar` 处于 `partials` 目录下。 - -## 动态引用 - -> 注意由于历史原因这个选项叫做 dynamicPartials,但它对 layout 也起作用。 - -**dynamicPartials** 表示是否把传给 [include][include], [render][render], [layout][layout] 标签的文件名当做变量处理。默认为 `true`。例如用上下文 `{ file: 'foo.html' }` 渲染下面的模板将会引入文件 `foo.html`: - -```liquid -{% include file %} -``` - -设置 `dynamicPartials: false` 后 LiquidJS 将会尝试去读取 `file`。当你的模板之间都是静态引入关系时会很有用: - -```liquid -{% liquid foo.html %} -``` - -{% note warn 常见陷阱 %} -LiquidJS 把这个选项默认值设为 true 以兼容于 shopify/liquid,但如果你在使用 eleventy 它会设置默认值 false (参考 Quoted Include Paths)以兼容于 Jekyll。{% endnote %} - -## Jekyll include - -{% since %}v9.33.0{% endsince %} - -[jekyllInclude][jekyllInclude] 用来启用 Jekyll-like include 语法。默认为 `false`,当设置为 `true` 时: - -- 默认启用静态文件名:`dynamicPartials` 的默认值变为 `false`(而非 `true`)。但你也可以把它设置回 `true`。 -- 参数的键和值之间由 `=` 分隔(本来是 `:`)。 -- 参数放到了 `include` 变量下,而非当前作用域。 - -例如下面的模板中,`name.html` 没有带引号,`header` 和 `"HEADER"` 以 `=` 分隔,`header` 参数通过 `include.header` 来引用。更多详情请参考 [include][include]。 - -```liquid -// entry template -{% include article.html header="HEADER" content="CONTENT" %} - -// article.html -
-
{{include.header}}
- {{include.content}} -
-``` - -## extname - -**extname** 定义了默认的文件后缀,当传入文件名不包含后缀时自动追加。默认值是 `''` 也就是说默认是禁用的。如果设置为 `.liquid`: - -```liquid -{% render "foo" %} 没有后缀,添加 ".liquid" 并加载 foo.liquid -{% render "foo.html" %} 已经有后缀了,直接加载 foo.html -``` - -{% note info 旧版行为 %} -在 2.0.1 之前,extname 默认值为 `.liquid`。要禁用它需要明确设置为 extname: ''。详情参考 #41。 -{% endnote %} - -## fs - -**fs** 用来自定义文件系统实现,详情请参考 [Abstract File System][abstract-fs]。 - -## globals - -**globals** 用来定义对所有模板可见的全局变量。包括 [render tag][render] 引入的子模板,见 [3185][185]。 - -## jsTruthy - -**jsTruthy** 用来使用 Javascript 的真值判断,默认为 `false` 使用 Shopify 方式。 - -例如,空字符串在 JavaScript 中为假(`jsTruthy` 为 `true` 时),在 Shopify 真值表中为真。 - -## outputEscape - -[outputEscape][outputEscape] 用来自动转义输出。它的值可以是 `"escape"`、`"json"` 或 `(val: unknown) => string`,默认为 `undefined`。 - -- 如果被输出的变量不被信任,可以设置 `outputEscape: "escape"` 来自动把它们 HTML 转义。如果要直接输出则需要使用 [raw][raw] 过滤器。 -- 如果你在用 LiquidJS 来生产 JSON 文件,可以设置为 `"json"`。 -- `outputEscape` 甚至可以是函数,你可以借此控制整个 LiquidJS 的变量输出。注意函数的输入不一定是字符串,因为过滤器的返回值可以不是字符串,你的函数将会接到这个值。 - -## 时间日期和时区 - -**timezoneOffset** 用来指定一个和你当地时区不同的时区,所有日期和时间输出时都转换到这个指定的时区。例如设置 `timezoneOffset: 0` 将会把所有日期按照 UTC/GMT 00:00 来输出。 - -**preserveTimezones** 是一个布尔值,只影响时间戳字面量。当设置为 `true` 时,所有字面量的时间戳字符串会在输出时保持原状,即不论输入时采取怎样的时区,输出时仍然采用那一时区(和 Shopify Liquid 的行为一致)。注意这是一个解析器参数,渲染时传入的数据中的日期的输出不会受此参数影响。注意 `preserveTimezones` 比 `timezoneOffset` 的优先级更高。 - -**dateFormat** 用于指定输出日期的默认格式. `%A, %B %-e, %Y at %-l:%M %P %z` 如果未指定,将使用. 例如,设置 `dateFormat: %Y-%m-%dT%H:%M:%S:%LZ` 以输出 [JavaSrcipt Date.toJson()][https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON] 格式. - -## 换行和缩进 - -**greedy**, **trimOutputLeft**, **trimOutputRight**, **trimTagLeft**, **trimTagRight** 选项用来移除 Liquid 语法周围的换行和缩进,详情请参考 [Whitespace Control][wc]。 - -## 自定义分隔符 - -**outputDelimiterLeft**, **outputDelimiterRight**, **tagDelimiterLeft**, **tagDelimiterRight** 用来自定义 LiquidJS 中 [标签和过滤器][intro] 的分隔符。例如设置了 `outputDelimiterLeft: <%=, outputDelimiterRight: %>` 后我们可以避免跟其他模板引擎冲突: - -```ejs -<%= username | append: ", welcome to LiquidJS!" %> -``` - -## 严格模式 - -**strictFilters** 用来启用过滤器的严格模式,如果设置为 `true` 过滤器不存在时解析会抛出异常。默认为 `false`,这时会跳过不存在的过滤器。 - -**strictVariables** 用来启用变量严格模式。如果设置为 `true` 变量不存在时渲染会抛出异常,默认为 `false` 这时不存在的变量会被渲染为空字符串。 - -**ownPropertyOnly** 用来隐藏原型上的变量,如果你需要把未经处理过的对象传递给模板时,可以设置 `ownPropertyOnly` 为 `true`,默认为 `false`。 - -{% note info 不存在的标签 %} -不存在的标签总是会抛出一个解析异常,这一行为无法自定义。 -{% endnote %} - -## 参数顺序 - -默认会忽略参数出现的顺序,例如 `{% for i in (1..8) reversed limit:3 %}` 里总是会先执行 `limit` 再执行 `reversed`,虽然 `reversed` 先出现。为了让 LiquidJS 按顺序执行参数,需要设置 **orderedFilterParameters** 为 `true`。它的默认值为 `false`。 - -[liquid]: /api/classes/Liquid.html -[caching]: ./caching.html -[abstract-fs]: ./render-file.html#Abstract-File-System -[render-file]: ./render-file.html -[185]: https://github.com/harttle/liquidjs/issues/185 -[render]: ../tags/render.html -[include]: ../tags/include.html -[layout]: ../tags/layout.html -[wc]: ./whitespace-control.html -[intro]: ./intro-to-liquid.html -[jekyllInclude]: /api/interfaces/LiquidOptions.html#jekyllInclude -[raw]: ../filters/raw.html -[outputEscape]: /api/interfaces/LiquidOptions.html#outputEscape diff --git a/docs/source/zh-cn/tutorials/parse-parameters.md b/docs/source/zh-cn/tutorials/parse-parameters.md deleted file mode 100644 index 3f5cbaa65..000000000 --- a/docs/source/zh-cn/tutorials/parse-parameters.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: 参数解析 ---- - -## 访问原始参数 - -在 [注册过滤器和标签][register-tags] 中提到,可以通过 `tagToken.args` 来得到标签的原始参数字符串。例如: - -```javascript -// Usage: {% random foo bar coo %} -// Output: "foo", "bar" or "coo" -engine.registerTag('random', { - parse(tagToken) { - // tagToken.args === "foo bar coo" - this.items = tagToken.args.split(' ') - }, - render(context, emitter) { - // get a random index - const index = Math.floor(this.items.length * Math.random()) - // output that item - emitter.write(this.items[index]) - } -}) -``` - -见这个 JSFiddle:。 - -## 解析参数的值 - -除了静态的参数字符串之外,我们更希望把动态的值传递给标签。LiquidJS 中的值可以是字面量(字符串、数字等,也可以是当前上下文的变量。 - -下面是修改过的模板,也包含三个值用来随机。但它们表示的是值而不是静态的字符串。第一个是字符串字面量,第二个是标识符(表示变量),第三个是属性访问表达式,包含两个标识符。 - -```liquid -{% random "foo" bar obj.coo %} -``` - -解析这么多种情况会很麻烦,但 LiquidJS 提供了 [Tokenizer][Tokenizer] 类来处理这种情况。 - -```javascript -const { Liquid, Tokenizer, evalToken } = require('liquidjs') - -engine.registerTag('random', { - parse(tagToken) { - const tokenizer = new Tokenizer(tagToken.args) - this.items = [] - while (!tokenizer.end()) { - // here readValue() returns a LiteralToken or PropertyAccessToken - this.items.push(tokenizer.readValue()) - } - }, - * render(context, emitter) { - const index = Math.floor(this.items.length * Math.random()) - const token = this.items[index] - // in LiquidJS, we use yield to wait for async call - const value = yield evalToken(token, context) - emitter.write(value) - } -}) -``` - -用上下文 `{ bar: "bar", obj: { coo: "coo" } }` 来调用这个标签可以得到上第一个例子一样的效果。见这个 JSFiddle:. - -{% note info 异步和 Promise %} -在 LiquidJS 里异步用生成器实现,这样同样一份标签的实现也可以用于同步的 API 比如 `renderSync()`,`parseAndRenderSync()`,`renderFileSync()`。如果要在标签实现里等待 Promise,只需要把 `await somePromise` 换成 `yield somePromise`,并保留 `* render()` 不要改成 `async render()`。更多细节请参考 Sync and Async。 -{% endnote %} - -## 把键值对解析为命名参数 - -当参数很多时或者有可选参数时,使用命名参数语法会很方便。这时参数由无序的键值对构成,LiquidJS 中的 [Hash][Hash] 类就是来处理这种情况的。 - -```liquid -{% random from:2, to:max %} -``` - -上面的例子用来产生 [2, max] 范围内的随机数。我们要用 `Hash` 来解析 `from` 和 `to` 参数。 - -```javascript -const { Liquid, Hash } = require('liquidjs') - -engine.registerTag('random', { - parse(tagToken) { - // 解析参数结果,存到 `this.args` 里 - this.args = new Hash(tagToken.args) - }, - * render(context, emitter) { - // 在当前 `context` 下计算参数的值 - const {from, to} = yield this.args.render(context) - const length = to - from + 1 - const value = from + Math.floor(length * Math.random()) - emitter.write(value) - } -}) -``` - -在 `{ max: 10 }` 上下文上渲染 `{% raw %}{% random from:2, to:max %}{% endraw %}` 将会得到 [2, 10] 范围内的随机数。见这个 JSFiddle:。 - -[register-tags]: /tutorials/register-filters-tags.html -[Tokenizer]: /api/classes/Tokenizer.html -[Hash]: /api/classes/Hash.html diff --git a/docs/source/zh-cn/tutorials/partials-and-layouts.md b/docs/source/zh-cn/tutorials/partials-and-layouts.md deleted file mode 100644 index 531ef00cb..000000000 --- a/docs/source/zh-cn/tutorials/partials-and-layouts.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: 引用和继承 ---- - -## 引用模板片段 - -对于如下两个模板文件: - -``` -// 文件:color.liquid -color: '{{ color }}' shape: '{{ shape }}' - -// 文件:theme.liquid -{% assign shape = 'circle' %} -{% include 'color' %} -{% include 'color' with 'red' %} -{% include 'color', color: 'yellow', shape: 'square' %} -``` - -输出为: - -``` -color: '' shape: 'circle' -color: 'red' shape: 'circle' -color: 'yellow' shape: 'square' -``` - -{% note tip ".liquid" 文件扩展名 %} -如果设置了 `extname: ".liquid"` 选项,就可以省略 layout, renderinclude 里面文件名的 ".liquid" 后缀。详情请参考 extname 选项。 -{% endnote %} - -## 布局模板(模板继承) - -对于如下两个模板文件: - -``` -// 文件:default-layout.liquid -Header -{% block content %}My default content{% endblock %} -Footer - -// 文件:page.liquid -{% layout "default-layout" %} -{% block content %}My page content{% endblock %} -``` - -渲染 `page.liquid` 将会输出: - -``` -Header -My page content -Footer -``` - -{% note tip Block %} -
    -
  • 布局文件(父模板)中可以定义多个 block;
  • -
  • 只有一个 block 时,block 名字可以省略。
  • -
-{% endnote %} diff --git a/docs/source/zh-cn/tutorials/plugins.md b/docs/source/zh-cn/tutorials/plugins.md deleted file mode 100644 index 0f826e6f7..000000000 --- a/docs/source/zh-cn/tutorials/plugins.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: 插件 ---- - -一组标签和过滤器可以封装为一个 **插件**,通常发包到 NPM 来方便使用。本文介绍如何创建和使用插件。 - -## 编写插件 - -LiquidJS 插件就是一个简单的函数,它的第一个参数是 [Liquid 类][liquid],其中的 `this` 是它被注册到的 Liquid 实例。可以通过 `this` 来调用 Liquid API,比如 [注册标签和过滤器][register]。 - -现在我们来写一个插件并在其中注册一个过滤器,来把输入字符串转换为大写: - -```javascript -/** - * Inside the plugin function, `this` refers to the Liquid instance. - * - * @param Liquid: provides facilities to implement tags and filters. - */ -module.exports = function (Liquid) { - this.registerFilter('upup', x => x.toUpperCase()); -} -``` - -把上述代码保存为 `upup.js`。 - -## 使用插件 - -把插件传递给 `.plugin()` 方法即可注册插件,例如: - -```javascript -const engine = new Liquid() - -engine.plugin(require('./upup.js')); -engine.parseAndRender('{{ "foo" | upup }}').then(console.log) -``` - -上述代码将会输出 `"FOO"`。 - -## 插件列表 - -由于本仓库只包含 [Shopify/liquid](https://github.com/Shopify/liquid/) 核心仓库的标签和插件(参考 ),Shopify 平台上特有的插件只能通过插件来使用。 - -这里是一个插件列表,欢迎添加你的插件(点击右上角编辑按钮): - -* Sections 标签(开发中): https://github.com/harttle/liquidjs-section-tags -* 颜色过滤器: https://github.com/harttle/liquidjs-color-filters - -[liquid]: /api/classes/Liquid.html -[register]: ./register-filters-tags.html \ No newline at end of file diff --git a/docs/source/zh-cn/tutorials/register-filters-tags.md b/docs/source/zh-cn/tutorials/register-filters-tags.md deleted file mode 100644 index f7ff29230..000000000 --- a/docs/source/zh-cn/tutorials/register-filters-tags.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: 注册标签和过滤器 ---- - -## 注册标签 - -```javascript -// 使用方式: {% upper name %} -engine.registerTag('upper', { - parse: function(tagToken, remainTokens) { - this.value = new Value(token.args, liquid) - }, - render: function*(scope, hash) { - const str = yield this.value.value(ctx); // 'alice' - return str.toUpperCase() // 'Alice' - } -}); -``` - -* `parse`: 从 `remainTokens` 中读取后续的标签/输出/HTML,直到找到你期望的结束标签。 -* `render`: 把 scope 数据和此前解析得到的 Token 结合,输出 HTML 字符串。 - -对于更复杂的标签实现,可以提供一个继承自 `Tag` 的类: - -```typescript -// Usage: {% upper name:"alice" %} -import { Hash, Tag, TagToken, Context, Emitter, TopLevelToken, Liquid } from 'liquidjs' - -engine.registerTag('upper', class UpperTag extends Tag { - private hash: Hash - constructor(tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) { - super(tagToken, remainTokens, liquid) - this.hash = new Hash(tagToken.args) - } - * render(ctx: Context) { - const hash = yield this.hash.render(); - return hash.name.toUpperCase() // 'ALICE' - } -}); -``` - -可以参考已有的标签实现: - -## 注册过滤器 - -```javascript -// 使用方式: {{ name | upper }} -engine.registerFilter('upper', v => v.toUpperCase()) -``` - -过滤器的参数将会传递给上面注册的过滤器函数,从第二个参数开始(第一个参数是过滤器左侧的输入),例如: - -```javascript -// Usage: {{ 1 | add: 2, 3 }} -engine.registerFilter('add', (initial, arg1, arg2) => initial + arg1 + arg2) -``` - -查看已有的过滤器实现:。对于复杂的标签,也可以用一个类来实现: - -```typescript -// Usage: {% upper name:"alice" %} -import { Hash, Tag, TagToken, Context, Emitter, TopLevelToken, Liquid } from 'liquidjs' - -engine.registerTag('upper', class UpperTag extends Tag { - private hash: Hash - constructor(tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) { - super(tagToken, remainTokens, liquid) - this.hash = new Hash(tagToken.args) - } - * render(ctx: Context) { - const hash = yield this.hash.render(); - return hash.name.toUpperCase() // 'ALICE' - } -}); -``` - -## 反注册标签/过滤器 - -有时可能需要禁用一些标签/过滤器(比如 [#324](https://github.com/harttle/liquidjs/issues/324)),注册一个假的标签/过滤器并在里面抛出相应的错误即可。 - -```javascript -// 禁用标签 -const disabledTag = { - parse: function(token) { - throw new Error(`tag "${token.name}" disabled`); - } -} -engine.registerTag('include', disabledTag); - -// 禁用过滤器 -function disabledFilter(name) { - return function () { - throw new Error(`filter "${name}" disabled`); - } -} -engine.registerFilter('plus', disabledFilter('plus')); -``` diff --git a/docs/source/zh-cn/tutorials/render-file.md b/docs/source/zh-cn/tutorials/render-file.md deleted file mode 100644 index 4d5c6283c..000000000 --- a/docs/source/zh-cn/tutorials/render-file.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: 渲染文件 ---- - -一个典型的项目会有一个目录下都是模板,最方便的方式就是设置 LiquidJS 的 [root][root] 然后调用 [.renderFile()][renderFile] 或 [.renderFileSync()][renderFileSync] 来渲染其中的一个模板文件。 - -## 渲染一个文件 - -例如你有如下的目录结构: - -``` -. -├── index.js -└── views/ - ├── hello.liquid - └── world.liquid -``` - -其中 `hello.liquid` 内容为: - -```liquid -name: {{name}} -``` - -在 `index.js` 中可以这样渲染 `hello.liquid`: - -```javascript -var engine = new Liquid({ - root: path.resolve(__dirname, 'views/'), // 设置模板查找目录 - extname: '.liquid' // 添加后缀,默认为 "" 表示不添加后缀 -}); -// 将会读取并渲染 `views/hello.liquid` -engine.renderFile("hello", {name: 'alice'}).then(console.log) -``` - -执行 `node index.js` 你将会得到类似这样的输出: - -``` -name: alice -``` - -## 模板查找 - -传递给 [.renderFile()][renderFile], [.parseFile()][parseFile] [.renderFileSync()][renderFileSync], [.parseFileSync()][parseFileSync] 这些 API 的模板名, -以及传递给 [include][include], [layout][layout] 这些标签的模板名,将会根据 [root][root] 选项来查找。 - -`root` 可以设置为 `string` 类型的路径(见上面的例子), 也可以设置为一个字符串数组表示路径列表,这时 LiquidJS 将会按顺序去查找。例如: - -```javascript -var engine = new Liquid({ - root: ['views/', 'views/partials/'], - extname: '.liquid' -}); -``` - -{% note tip 相对路径 %}root 中使用相对路径将会被解释为相对于 cwd()(当前工作目录)。{% endnote %} - -当模板中引入子模板时(`{% raw %}{% render "foo" %}{% endraw %}`),或者调用 `.renderFile('foo')` 时,LiquidJS 会依次查看如下几个文件,并渲染第一个存在的文件: - -- `cwd()`/views/foo.liquid -- `cwd()`/views/partials/foo.liquid - -如果上述文件都不存在,将会抛出一个 `ENOENT` 错误。 - -{% note info 示例 %} 在 Node.js 示例中展示了怎么渲染一个文件 liquidjs/demo/nodejs/。{% endnote %} - -在浏览器中使用 LiquidJS 时,比如当前路径为 ,只会去 `root` 数组中的第一个路径下获取,也就是这个文件: - -- - -如果获取失败(比如得到一个 404/500 错误)或网络错误,将会抛出一个 `ENOENT` 错误。 - -{% note info 示例 %} 在这个示例中展示了如何从网络获取并渲染一个模板文件 liquidjs/demo/browser/。{% endnote %} - -## 文件系统接口 - -LiquidJS 定义了一个[文件系统接口][ifs],在 Node.js 下的默认实现是 [src/fs/node.ts][fs-node],在浏览器打包文件中的默认实现是 [src/fs/browser.ts][fs-browser]。 -你可以通过创建 `Liquid` 时的 [fs][fs] 参数来指定一个自定义实现来指定如何读取模板文件。比如从数据库里读取: - -```javascript -const engine = new Liquid({ - fs: { - readFileSync (file) { - return db.model('Template').findByIdSync(file).text - }, - await readFile (file) { - const template = await db.model('Template').findById(file) - return template.text - }, - existsSync () { - return true - }, - await exists () { - return true - }, - resolve(root, file, ext) { - return file - } - } -}); -``` - -[fs]: /api/interfaces/LiquidOptions.html#fs -[ifs]: /api/interfaces/FS.html -[fs-node]: https://github.com/harttle/liquidjs/blob/master/src/fs/fs-impl.ts -[fs-browser]: https://github.com/harttle/liquidjs/blob/master/src/fs/fs-impl-browser.ts -[layout]: https://help.shopify.com/en/themes/liquid/tags/theme-tags#layout -[include]: https://help.shopify.com/themes/liquid/tags/theme-tags#include -[renderFile]: /api/classes/Liquid.html#renderFile -[renderFileSync]: /api/classes/Liquid.html#renderFileSync -[parseFile]: /api/classes/Liquid.html#parseFile -[parseFileSync]: /api/classes/Liquid.html#parseFileSync -[root]: /api/interfaces/LiquidOptions.html#root diff --git a/docs/source/zh-cn/tutorials/render-tag-content.md b/docs/source/zh-cn/tutorials/render-tag-content.md deleted file mode 100644 index 76968556a..000000000 --- a/docs/source/zh-cn/tutorials/render-tag-content.md +++ /dev/null @@ -1,137 +0,0 @@ ---- -title: 渲染标签内容 ---- - -自定义标签可以有内容,也可以嵌套使用。本文描述了如何实现一个由*开始标签*,*结束标签*和之间的*标签内容*的自定义标签。 - -## 渲染标签内容 - -我们先实现一个简单的 `wrap` 标签,它会把内容包装在 `
` 元素里: - -```liquid -{% wrap %} - {{ "hello world!" | capitalize }} -{% endwrap %} -``` - -期望输出: - -```html -
- Hello world! -
-``` - -首先 [注册][register-tags] 一个名为 `wrap` 的标签,把内容解析到 `this.tpls` 数组里。`parse(tagToken, remainTokens)` 中, - -- `tagToken` 是当前 *Token* `{%raw%}{% wrap %}{%endraw%}`, -- `remainTokens` 是当前模板中后续所有 *Token* 的数组。 - -我们要做的是从 `remainTokens` 里拿出来/`.shift()` 足够的标签直到遇到 `endwrap`(其实可以是任意名字,但按照惯例应该叫 `endwrap`)。如果到模板结尾都没遇到 `endwrap`,需要抛出一个标签未关闭的 `Error`。 - -```javascript -engine.registerTag('wrap', { - parse(tagToken, remainTokens) { - this.tpls = [] - let closed = false - while(remainTokens.length) { - let token = remainTokens.shift() - // 得到了结束标签,停止解析 - if (token.name === 'endwrap') { - closed = true - break - } - // 把 Token 解析成 Template - // parseToken() 可能会消耗多个 Token - // 例如 {% if %}...{% endif %} - let tpl = this.liquid.parser.parseToken(token, remainTokens) - this.tpls.push(tpl) - } - if (!closed) throw new Error(`tag ${tagToken.getText()} not closed`) - }, - * render(context, emitter) { - emitter.write("
") - yield this.liquid.renderer.renderTemplates(this.tpls, context, emitter) - emitter.write("
") - } -}) -``` - -`.renderTemplates()` 可能是异步的,因此需要 `yield` 来等它完成。更多关于 LiquidJS 异步的信息可以参考 [同步和异步][async]。`render()` 的其他部分比较直观,这是 JSFiddle 版本:。 - -## 使用 ParseStream - -对于像 [for][for] 和 [if][if] 这样的复杂标签,`parse()` 会变得很复杂。使用 [ParseStream][ParseStream] 工具可以按事件风格来组织 `parse()` 的逻辑。下面是用 `ParseStream` 重写过的 `parse()`,实现了和上面例子中完全一样的功能。 - -```javascript -parse(tagToken, remainTokens) { - this.tpls = [] - this.liquid.parser.parseStream(remainTokens) - .on('template', tpl => this.tpls.push(tpl)) - // 注意这里不能用箭头函数,因为我们需要 `this` - .on('tag:endwrap', function () { this.stop() }) - .on('end', () => { throw new Error(`tag ${tagToken.getText()} not closed`) }) - .start() -} -``` - -这是 JSFiddle 链接:。简单起见,下面的例子都借助 `ParseStream` 来实现。 - -## 操作上下文 - -上面的 `wrap` 标签看起来没什么用,反正没它也可以很容易地渲染那部分内容。我们现在来实现一个 `repeat` 标签,把内容渲染两次(还可以[加个参数][parameter]让它渲染任意次): - -```liquid -{% repeat %} - {{ repeat.i }}. {{ "hello world!" | capitalize }} -{% endrepeat %}` -``` - -期望输出: - -```html -1. Hello world! -2. Hello world! -``` - -你可能注意到了在 `repeat` 上下文里有个额外的变量 `repeat.i`,这就需要我们操作 *上下文*。 - -{% note info 上下文 %} -上下文 定义了 Liquid 模板中每个变量的值。在 LiquidJS 中,`Context` 由一个 `Scope` 的栈组成。*Scope* 就是一个普通对象,就像传给 `engine.render(tpl, scope)` 的 `scope` 一样。 -{% endnote %} - -每次进入新的 *上下文* 时,我们需要 `push` 一个新的 `Scope`。当结束渲染并退出 *上下文* 时,再把 `Scope` 从 *上下文* `pop` 出来。见下面的实现: - -```javascript -engine.registerTag('repeat', { - parse(tagToken, remainTokens) { - this.tpls = [] - this.liquid.parser.parseStream(remainTokens) - .on('template', tpl => this.tpls.push(tpl)) - .on('tag:endrepeat', function () { this.stop() }) - .on('end', () => { throw new Error(`tag ${tagToken.getText()} not closed`) }) - .start() - }, - * render(context, emitter) { - const repeat = { i: 1 } - context.push({ repeat }) - yield this.liquid.renderer.renderTemplates(this.tpls, context, emitter) - repeat.i++ - yield this.liquid.renderer.renderTemplates(this.tpls, context, emitter) - context.pop() - } -}) -``` - -`parse()` 部分和 `wrap` 标签完全相同,在 `render()` 部分我们通过调用两次 `.renderTemplates(this.tpls)` 来重复渲染内容。这是 JSFiddle 链接:。 - -{% note warn 成对使用 Push 和 Pop %} -必须成对地使用 `context.push()` 和 `context.pop()`。如果忘记 `pop()` 会导致 `Scope` 泄露给后面的模板内容,也可能损坏 *上下文* 栈。. -{% endnote %} - -[register-tags]: ./register-filters-tags.html -[async]: ./sync-and-async.html -[for]: ../tags/for.html -[if]: ../tags/if.html -[ParseStream]: /api/classes/ParseStream.html -[parameter]: ./parse-parameters.html diff --git a/docs/source/zh-cn/tutorials/security-model.md b/docs/source/zh-cn/tutorials/security-model.md deleted file mode 100644 index a859370e8..000000000 --- a/docs/source/zh-cn/tutorials/security-model.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: 安全模型 ---- - -LiquidJS 提供了面向 DoS 的限制选项(`parseLimit`、`renderLimit`、`memoryLimit`)来降低风险。本文概述这些限制、[`ownPropertyOnly`][ownPropertyOnly]、自定义 [`Drop`][drop] 的注意事项,以及生产环境应采用的安全边界。 - -## 安全边界 - -内置限制是协作式防护,不是严格的运行时隔离。 - -- 它**不等于**进程的 RSS/heap 实际占用。 -- 它**不是** JavaScript 沙箱。 -- 在生产环境中应结合进程/容器资源限制和请求超时做分层防护。 - -## 限制速览 - -- [parseLimit][parseLimit]:限制每次 `parse()` 的模板总长度。 -- [renderLimit][renderLimit]:限制每次 `render()` 的总渲染时间。 -- [memoryLimit][memoryLimit]:协作式限制 LiquidJS 已记账的内存敏感分配。 - -## 限制详解 - -### parseLimit - -[parseLimit][parseLimit] 限制每次 `.parse()` 调用中解析的模板大小(字符长度),包括引用的 partials 和 layouts。由于 LiquidJS 解析模板字符串的时间复杂度接近 O(n),限制模板总长度通常就足够了。 - -普通电脑可以很容易处理 `1e8`(100M)个字符的模板。 - -### renderLimit - -仅限制模板大小是不够的,因为在渲染时可能会出现动态的数组和循环。[renderLimit][renderLimit] 通过限制每次 `render()` 调用的时间来缓解这些问题。 - -```liquid -{%- for i in (1..10000000) -%} - order: {{i}} -{%- endfor -%} -``` - -渲染时间是在渲染每个模板之前检查的。在上面的例子中,循环中有两个模板:`order: ` 和 `{{i}}`,因此会检查 2x10000000 次。 - -`renderLimit` 不是硬性的 CPU 限制器。它是在模板渲染边界做检查,因此检查点之间的高计算开销过滤器/标签/用户自定义函数,或深层模板嵌套,仍可能导致 DoS。 - -### memoryLimit - -`memoryLimit` 只限制 LiquidJS 显式记账到的操作。 - -- 会被统计:LiquidJS 内部调用了内存记账逻辑的内存敏感操作。 -- 不保证被统计:任意用户对象行为(例如自定义 `toValue()` / `toString()` 链)以及其他发生在 LiquidJS 记账点之外的宿主侧分配。 - -换句话说,`memoryLimit` 限制的是 LiquidJS 的“已记账分配”,而不是进程里每一个字节的分配。 - -即使模板和迭代次数较少,内存使用量也可能呈指数增长。在下面的示例中,内存会在每次迭代中翻倍: - -```liquid -{% assign array = "1,2,3" | split: "," %} -{% for i in (1..32) %} - {% assign array = array | concat: array %} -{% endfor %} -``` - -由于 [JavaScript 使用 GC 来管理内存](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_management),`memoryLimit` 可能无法反映实际的内存占用。 - -## `ownPropertyOnly` 与作用域数据 - -将 [`ownPropertyOnly`][ownPropertyOnly] 设为 `true` 时,普通作用域对象只暴露**自有**属性(不包含继承链与 `Object.prototype` 上的键)。默认 `false` 与常规 JavaScript 属性访问一致。对不可信或可能被污染的对象应使用 `true`;若缺少路径需报错,可配合 [`strictVariables`][strictVariables]。单次渲染可通过 [`RenderOptions`][renderOwnPropertyOnly] 覆盖。该选项只约束作用域数据的读取,不是过滤器、标签或宿主代码的沙箱。 - -## 自定义 `Drop` 类 - -[`Drop`][drop] 与普通对象处理不同:即使开启 [`ownPropertyOnly`][ownPropertyOnly],LiquidJS 仍可能沿原型链读取属性,并在未解析时调用 [`liquidMethodMissing`][liquidMethodMissing]。**你**对 Drop 暴露的能力负责:收窄 API,勿向 Drop 传入不安全数据,除非该类明确为模板访问而设计。仅靠 `ownPropertyOnly` 无法硬化自定义 Drop,应像审计其他特权代码一样审查其实现。 - -## 在线服务建议 - -如果你运行在线服务,建议尽量避免渲染完全由用户定义的模板。 - -- 优先使用受控模板或受限模板子集。 -- 如果必须支持用户自定义模板,请隔离渲染(worker/进程/容器),并同时配置操作系统或容器级的内存/CPU 限额与请求限流。 -- 将 `parseLimit` / `renderLimit` / `memoryLimit` 视为 DoS 防护体系中的一层,而不是唯一防线。 - -对于单个模板中的重型操作,仍建议使用进程级隔离(例如 [paralleljs][paralleljs])。 - -[paralleljs]: https://www.npmjs.com/package/paralleljs -[parseLimit]: /api/interfaces/LiquidOptions.html#parseLimit -[renderLimit]: /api/interfaces/LiquidOptions.html#renderLimit -[memoryLimit]: /api/interfaces/LiquidOptions.html#memoryLimit -[ownPropertyOnly]: /api/interfaces/LiquidOptions.html#ownPropertyOnly -[renderOwnPropertyOnly]: /api/interfaces/RenderOptions.html#ownPropertyOnly -[strictVariables]: /api/interfaces/LiquidOptions.html#strictVariables -[drop]: /api/classes/Drop.html -[liquidMethodMissing]: /api/classes/Drop.html#liquidMethodMissing diff --git a/docs/source/zh-cn/tutorials/setup.md b/docs/source/zh-cn/tutorials/setup.md deleted file mode 100644 index 26ee81540..000000000 --- a/docs/source/zh-cn/tutorials/setup.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: 安装和使用 ---- - -如果你还不了解 Liquid 模板语言,请参考 [Liquid 模板语言简介][intro]。 - -## 在 Node.js 里使用 - -通过 NPM 安装: - -```bash -npm install --save liquidjs -``` - -```javascript -var { Liquid } = require('liquidjs'); -var engine = new Liquid(); - -engine - .parseAndRender('{{name | capitalize}}', {name: 'alice'}) - .then(console.log); // 输出 'Alice' -``` - -{% note info 示例 %} 这里有一个 LiquidJS 在 Node.js 里使用的例子:liquidjs/demo/nodejs/.{% endnote %} - -LiquidJS 的类型定义也导出并发布到了 NPM 包里,写 TypeScript 的项目可以直接这样使用: - -```typescript -import { Liquid } from 'liquidjs'; -const engine = new Liquid(); - -engine - .parseAndRender('{{name | capitalize}}', {name: 'alice'}) - .then(console.log); // 输出 'Alice' -``` - -{% note info 示例 %} 这里有一个 LiquidJS 在 TypeScript 下的例子:liquidjs/demo/typescript/.{% endnote %} - -## 在浏览器里使用 - -LiquidJS 预先构建了 UMD Bundle,可以通过 jsDelivr CDN 来引用: - -```html - - -``` - -{% note info 示例 %} 这里有一个 jsFiddle 上的在线例子:jsfiddle.net/x43eb0z6,其源码也可以在 liquidjs/demo/browser/ 找到。{% endnote %} - -{% note warn 兼容性 %} 在类似 IE 和 Android UC 这样的浏览器中,你可能需要引入 Promise polyfill,参看 caniuse 的统计。 {% endnote %} - -## 在命令行里使用 - -你还可以在命令行里使用 LiquidJS: - -```bash -echo '{{"hello" | capitalize}}' | npx liquidjs -``` - -模板来自标准输入,数据则来自参数,这个参数可以是一个 JSON 文件的路径,也可以是一个 JSON 字符串: - -```bash -echo 'Hello, {{ name }}.' | npx liquidjs '{"name": "Snake"}' -``` - -## 其他 - -[@stevenanthonyrevo](https://github.com/stevenanthonyrevo) 还提供了一个 ReactJS demo,请参考 [liquidjs/demo/reactjs/](https://github.com/harttle/liquidjs/blob/master/demo/reactjs/)。 - -[intro]: ./intro-to-liquid.html \ No newline at end of file diff --git a/docs/source/zh-cn/tutorials/static-analysis.md b/docs/source/zh-cn/tutorials/static-analysis.md deleted file mode 100644 index ed6d39cd1..000000000 --- a/docs/source/zh-cn/tutorials/static-analysis.md +++ /dev/null @@ -1,292 +0,0 @@ ---- -title: 静态模板分析 ---- - -{% since %}v10.20.0{% endsince %} - -{% note warn 实验性功能 %} -这是一个实验性功能,未来的 API 可能会发生变化,返回的内部结构也可能在不进行主要版本更新的情况下更改。 -{% endnote %} - -{% note info 同步与异步 %} -本文中的每种方法都提供了同步和异步版本。请参阅 [Liquid API][liquid-api] 了解完整的参考信息。 -{% endnote %} - -## 变量 - -可以使用 `Liquid.variables(template)` 方法获取模板中使用的变量名称。它会返回一个字符串数组,每个字符串代表一个不同的变量,不包括其属性。 - -```javascript -import { Liquid } from 'liquidjs' - -const engine = new Liquid() - -const template = engine.parse(` -

- {% assign title = user.title | capitalize %} - {{ title }} {{ user.first_name | default: user.name }} {{ user.last_name }} - {% if user.address %} - {{ user.address.line1 }} - {% else %} - {{ user.email_addresses[0] }} - {% for email in user.email_addresses %} - - {{ email }} - {% endfor %} - {% endif %} - {{ a[b.c].d }} -

-`) - -console.log(engine.variablesSync(template)) -``` - -**输出** - -```javascript -[ 'user', 'title', 'email', 'a', 'b' ] -``` - -可以看到,标签和过滤器参数中的变量也会包含在内,例如示例中的嵌套变量 `b`。 -另外,可以使用 `Liquid.fullVariables(template)` 方法获取包含其属性的完整变量列表。 - -```javascript -// 上例继续 -engine.fullVariables(template).then(console.log) -``` - -**输出** - -```javascript -[ - 'user.title', - 'user.first_name', - 'user.name', - 'user.last_name', - 'user.address', - 'user.address.line1', - 'user.email_addresses[0]', - 'user.email_addresses', - 'title', - 'email', - 'a[b.c].d', - 'b.c' -] -``` - -或者,使用 `Liquid.variableSegments(template)` 获取每个变量路径的字符串和数字数组。 - -```javascript -// 上例继续 -engine.variableSegments(template).then(console.log) -``` - -**输出** - -```javascript -[ - [ 'user', 'title' ], - [ 'user', 'first_name' ], - [ 'user', 'name' ], - [ 'user', 'last_name' ], - [ 'user', 'address' ], - [ 'user', 'address', 'line1' ], - [ 'user', 'email_addresses', 0 ], - [ 'user', 'email_addresses' ], - [ 'title' ], - [ 'email' ], - [ 'a', [ 'b', 'c' ], 'd' ], - [ 'b', 'c' ] -] -``` - -### 全局变量 - -注意在上述示例中,`title` 和 `email` 被包含在结果中。通常你可能希望排除 `{% assign %}` 标签中定义的变量名,以及由 `{% for %}` 标签引入的临时变量。 - -为了获取 _全局_ 变量(即由应用开发者提供,而不是模板作者定义的变量)的名称,可以使用 `globalVariables`、`globalFullVariables` 或 `globalVariableSegments` 方法(及其同步版本)。 - -```javascript -// 上例继续 -engine.globalVariableSegments(template).then(console.log) -``` - -**输出** - -```javascript -[ - [ 'user', 'title' ], - [ 'user', 'first_name' ], - [ 'user', 'name' ], - [ 'user', 'last_name' ], - [ 'user', 'address' ], - [ 'user', 'address', 'line1' ], - [ 'user', 'email_addresses', 0 ], - [ 'user', 'email_addresses' ], - [ 'a', [ 'b', 'c' ], 'd' ], - [ 'b', 'c' ] -] -``` - -### 部分模板 - -默认情况下,LiquidJS 还会尝试加载和分析任何被包含和渲染的模板。 - -```javascript -import { Liquid } from 'liquidjs' - -const footer = ` -

-

© {{ "now" | date: "%Y" }} {{ site_name }}

-

{{ site_description }}

-
` - -const engine = new Liquid({ templates: { footer } }) - -const template = engine.parse(` - -

Hi, {{ you | default: 'World' }}!

- {% assign some = 'thing' %} - {% include 'footer' %} - -`) - -engine.globalVariables(template).then(console.log) -``` - -**输出** - -```javascript -[ 'you', 'site_name', 'site_description' ] -``` - -可以通过将 `partials` 选项设置为 `false` 来禁用部分模板的分析。 - -```javascript -// 上例继续 -engine.globalVariables(template, { partials: false }).then(console.log) -``` - -**输出** - -```javascript -[ 'you' ] -``` - -如果 `{% include %}` 标签使用了动态模板名称(无法在渲染模板之前确定的模板名称),即使 `partials` 设置为 `true`,也会被忽略。 - -### 高级用法 - -上述示例使用的是 `Liquid` 类的便捷方法,适用于最常见的使用场景。 -如果需要更详细的信息,可以直接处理 [分析结果][static-analysis-interface],其中每个变量的每次出现都会记录行、列和文件名等信息。 - -此处是对 [部分模板](#部分模板) 中模板进行 `Liquid.analyze()` 调用后返回的对象示例。 - -```javascript -{ - variables: { - you: [ - [String (Variable): 'you'] { - segments: [ 'you' ], - location: { row: 2, col: 14, file: undefined } - } - ], - site_name: [ - [String (Variable): 'site_name'] { - segments: [ 'site_name' ], - location: { row: 2, col: 41, file: 'footer' } - } - ], - site_description: [ - [String (Variable): 'site_description'] { - segments: [ 'site_description' ], - location: { row: 3, col: 9, file: 'footer' } - } - ] - }, - globals: { - you: [ - [String (Variable): 'you'] { - segments: [ 'you' ], - location: { row: 2, col: 14, file: undefined } - } - ], - site_name: [ - [String (Variable): 'site_name'] { - segments: [ 'site_name' ], - location: { row: 2, col: 41, file: 'footer' } - } - ], - site_description: [ - [String (Variable): 'site_description'] { - segments: [ 'site_description' ], - location: { row: 3, col: 9, file: 'footer' } - } - ] - }, - locals: { - some: [ - [String (Variable): 'some'] { - segments: [ 'some' ], - location: { row: 3, col: 13, file: undefined } - } - ] - } -} -``` - -### 自定义标签的分析 - -为了在静态分析中包含自定义标签的结果,这些标签必须实现 [Template 接口]( /api/interfaces/Template.html) 中定义的一些附加方法。LiquidJS 会使用这些方法返回的信息来遍历模板并报告变量使用情况。 - -并非所有方法都是必须的,这取决于标签的类型。如果标签是一个块标签,具有起始标签、结束标签以及内容,那么它需要实现 [`children()`](/api/interfaces/Template.html#children) 方法。`children()` 需要返回一个生成器,这是为了像 `render()` 一样既可以同步也可以异步调用。该方法应返回当前标签的子节点,例如 HTML 内容、输出语句和标签。 - -[`blockScope()`](/api/interfaces/Template.html#blockScope) 方法用于告知 LiquidJS 在标签块的持续时间内哪些名称会处于作用域中。这些名称可能依赖于标签的参数,也可能是固定的,例如 `{% for %}` 标签生成的 `forloop`。 - -无论标签是行内标签还是块标签,如果它接受参数,则应实现 [`arguments()`](/api/interfaces/Template.html#arguments) 方法,该方法负责将标签的参数作为 [`Value`](/api/classes/Value.html) 实例或类型为 [`ValueToken`](/api/types/ValueToken.html) 的标记序列返回。 - -以下示例展示了块标签如何实现这些方法。有关更多示例,请参见 LiquidJS 的[内置标签][built-in]。 - -```javascript -import { Liquid, Tag, Hash } from 'liquidjs' - -class ExampleTag extends Tag { - args - templates - - constructor (token, remainTokens, liquid, parser) { - super(token, remainTokens, liquid) - this.args = new Hash(token.tokenizer) - this.templates = [] - - const stream = parser.parseStream(remainTokens) - .on('tag:endexample', () => { stream.stop() }) - .on('template', (tpl) => this.templates.push(tpl)) - .on('end', () => { throw new Error(`tag ${token.getText()} not closed`) }) - - stream.start() - } - - * render (ctx, emitter) { - const scope = (yield this.args.render(ctx)) - ctx.push(scope) - yield this.liquid.renderer.renderTemplates(this.templates, ctx, emitter) - ctx.pop() - } - - * children () { - return this.templates - } - - * arguments () { - yield * Object.values(this.args.hash).filter((el) => el !== undefined) - } - - blockScope () { - return Object.keys(this.args.hash) - } -} -``` - -[liquid-api]: /api/classes/Liquid.html -[static-analysis-interface]: /api/interfaces/StaticAnalysis.html -[built-in]: https://github.com/harttle/liquidjs/tree/master/src/tags diff --git a/docs/source/zh-cn/tutorials/sync-and-async.md b/docs/source/zh-cn/tutorials/sync-and-async.md deleted file mode 100644 index caaf4c9a4..000000000 --- a/docs/source/zh-cn/tutorials/sync-and-async.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -title: 同步和异步 ---- - -LiquidJS 支持同步调用也支持异步调用,支持 Promise。为了同异步复用一套标签和过滤器,LiquidJS 标签用生成器来实现。 - -## 同异步 API - -[Liquid][Liquid] 上主要的方法都支持同步和异步,下面这些方法返回 `Promise`: - -- `render()` -- `renderFile()` -- `parseFile()` -- `parseAndRender()` -- `evalValue()` - -它们的同步版本带一个 `Sync` 后缀: - -- `renderSync()` -- `renderFileSync()` -- `parseFileSync()` -- `parseAndRenderSync()` -- `evalValueSync()` - -## 如何实现兼容同步的标签 - -LiquidJS 使用基于生成器的异步实现,来让同一份代码支持同步和异步调用。例如下面的 `UpperTag` 既可以用于 `engine.renderSync()` 也可以用于 `engine.render()`: - -```typescript -import { TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid } from 'liquidjs' - -// Usage: {% upper "alice" %} -// Output: ALICE -engine.registerTag('upper', class UpperTag extends Tag { - private value: Value - constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) { - super(token, remainTokens, liquid) - this.value = new Value(token.args, liquid) - } - * render (ctx: Context, emitter: Emitter) { - const title = yield this.value.value(ctx) - emitter.write(title.toUpperCase()) - } -}) -``` - -所有内置标签都兼容同步,可以安全地用于同步或异步 API。实现同时支持同异步的标签,需要: - -- render 函数声明成 `* render()`,并且在里面 -- 不能直接 `return `, -- 不能调用会返回 Promise 的函数。 - -## 调用返回 Promise 的函数 - -但 LiquidJS 是支持 `Promise` 的,你仍然可以调用返回 `Promise` 的方法并等它 resolve。只需要把 `await` 换成 `yield`。例如: - -```typescript - * render (ctx: Context, emitter: Emitter) { - const file = yield this.value.value(ctx) - const title = yield fs.readFile(file, 'utf8') - emitter.write(title.toUpperCase()) - } -``` - -现在 `* render()` 调用了一个返回 Promise 的 API,它就不再兼容同步了。不兼容同步的标签也仍然是合法标签,在异步 API 下也会正常运行。被同步调用时,返回 Promise 的标签会被渲染成 [object Promise]。 - -## 把 LiquidJS 生成器转换成 Promise - -有些 LiquidJS API 会返回 `Promise`,有些会返回生成器。你可以用 [toPromise][toPromise] 来把生成器转换为 `Promise`,比如: - -```typescript -import { TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid, toPromise } from 'liquidjs' - -// Usage: {% upper "alice" %} -// Output: ALICE -engine.registerTag('upper', class UpperTag extends Tag { - private value: Value - constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) { - super(token, remainTokens, liquid) - this.value = new Value(token.args, liquid) - } - async render (ctx: Context, emitter: Emitter) { - const title = await toPromise(this.value.value(ctx)) - emitter.write(title.toUpperCase()) - } -}) -``` - -## 纯异步标签 - -如果你的标签就不打算支持同步,可以干脆实现成 `async render()`,这样就可以使用更熟悉的 `await` 了: - -```typescript -import { toPromise, TagToken, Context, Emitter, TopLevelToken, Value, Tag, Liquid } from 'liquidjs' - -// Usage: {% upper "alice" %} -// Output: ALICE -engine.registerTag('upper', class UpperTag extends Tag { - private value: Value - constructor (token: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) { - super(token, remainTokens, liquid) - this.value = new Value(token.args, liquid) - } - async render (ctx: Context, emitter: Emitter) { - const title = await toPromise(this.value.value(ctx)) - emitter.write(`

${title}

`) - } -}) -``` - -[Liquid]: /api/classes/Liquid.html -[toPromise]: /api/functions/toPromise.html diff --git a/docs/source/zh-cn/tutorials/truthy-and-falsy.md b/docs/source/zh-cn/tutorials/truthy-and-falsy.md deleted file mode 100644 index b7571af32..000000000 --- a/docs/source/zh-cn/tutorials/truthy-and-falsy.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: 真和假 ---- - -虽然我们希望 [Liquid][sl] 是平台无关的,但 JavaScript 版本和 [Ruby 版本][ruby] 仍然有[很多区别][diff],真值就是其中之一。 - -## 真值表 - -根据 [Shopify 的文档](https://shopify.github.io/liquid/basics/truthy-and-falsy/),Ruby 版本除了 `false` 和 `nil` 之外的所有值都是真,但 JavaScript 有完全不同的类型系统,比如我们有 `undefined` 类型,以及不区分 `integer` 和 `float`,因此有些不同: - -值 | 真 | 假 ---- | --- | --- -`true` | ✔️ | -`false` | | ✔️ -`null` | | ✔️ -`undefined` | | ✔️ -`string` | ✔️ | -`empty string` | ✔️ | -`0` | ✔️ | -`integer` | ✔️ | -`float` | ✔️ | -`array` | ✔️ | -`empty array` | ✔️ | - -## 使用 JavaScript 真值 - -liquidjs 默认使用 Shopify 的真值表,但可以通过设置 **jsTruthy** 选项为 `true` 来使用标准的 JavaScript 真值。 - -值 | 真 | 假 ---- | --- | --- -`true` | ✔️ | -`false` | | ✔️ -`null` | | ✔️ -`undefined` | | ✔️ -`string` | ✔️ | -`empty string` | | ✔️ -`0` | | ✔️ -`integer` | ✔️ | -`float` | ✔️ | -`array` | ✔️ | -`empty array` | ✔️ | - -[ruby]: https://shopify.github.io/liquid -[sl]: https://www.npmjs.com/package/liquidjs -[diff]: https://github.com/harttle/liquidjs#differences-and-limitations \ No newline at end of file diff --git a/docs/source/zh-cn/tutorials/use-in-expressjs.md b/docs/source/zh-cn/tutorials/use-in-expressjs.md deleted file mode 100644 index 09d40bee4..000000000 --- a/docs/source/zh-cn/tutorials/use-in-expressjs.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: 在 Express.js 里使用 ---- - -LiquidJS 可以用来作为 [Express 的模板引擎](https://expressjs.com/en/resources/template-engines.html)。可以把 Liquid 设置到 [view engine][express-views] 选项上即可: - -```javascript -var { Liquid } = require('liquidjs'); -var engine = new Liquid(); - -// 注册为 liquid 文件的模板引擎 -app.engine('liquid', engine.express()); -app.set('views', './views'); // 指定模板目录 -app.set('view engine', 'liquid'); // 把 liquid 文件设为默认模板 -``` - -{% note info 示例 %} 这是一个在 Express.js 中使用 LiquidJS 的例子:liquidjs/demo/express/.{% endnote %} - -## 模板查找 - -LiquidJS 仍然会去 [root][root] 指定的目录查找(参考 [Render A Template File][render-a-file]),也会去 Express.js 的 [`views`][express-views] 选项指定的目录里(上述例子中是 `./views`)去查找。例如你有这样的目录结构: - -``` -. -├── views1/ -│ └── hello.liquid -└── views2/ - └── world.liquid -``` - -LiquidJS 的模板 root 设置到了 `views1`,Express.js 的 views 设置到了 `views2`: - -```javascript -var { Liquid } = require('liquidjs'); -var engine = new Liquid({ - root: './views1/' -}); - -app.engine('liquid', engine.express()); -app.set('views', './views2'); -app.set('view engine', 'liquid'); -``` - -`hello.liquid` 和 `world.liquid` 两个文件都可以找到并且成功渲染: - -```javascript -res.render('hello') -res.render('world') -``` - -## 缓存 - -直接把 [cache 选项][cache] 设为 `true` 即可开启模板缓存,参考 [缓存][Caching] 一文。推荐在生产环境中开启缓存,可以用如下代码: - -```javascript -var { Liquid } = require('liquidjs'); -var engine = new Liquid({ - cache: process.env.NODE_ENV === 'production' -}); -``` - -`cache` 还可以是一个数字表示最大缓存的模板数量,也可以是一个自定义的缓存实现,详情请参考 [cache 选项][cache]。 - -[cache]: /api/interfaces/LiquidOptions.html#cache -[express-views]: http://expressjs.com/en/guide/using-template-engines.html -[parseFile]: /api/classes/Liquid.html#parseFile -[parseFileSync]: /api/classes/Liquid.html#parseFileSync -[layout]: https://help.shopify.com/en/themes/liquid/tags/theme-tags#layout -[include]: https://help.shopify.com/themes/liquid/tags/theme-tags#include -[root]: /api/interfaces/LiquidOptions.html#root -[render-a-file]: ./render-a-file.html -[Caching]: ./caching.html diff --git a/docs/source/zh-cn/tutorials/whitespace-control.md b/docs/source/zh-cn/tutorials/whitespace-control.md deleted file mode 100644 index 402c43dad..000000000 --- a/docs/source/zh-cn/tutorials/whitespace-control.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: 空白字符控制 ---- - -为了让源代码缩进好看,我们会加很多空白字符比如把不会产生输出的标签也单独一行。LiquidJS 提供了空白字符控制机制,可以避免这些多余的空白字符输出到 HTML 中。 - -## 通过标记的方式 - -默认所有标签和输出的行,都会在行尾产生一个换行(`\n`),如果有缩进的话还会产生很多前导空格。例如: - -```liquid -{% author = "harttle" %} -{{ author }} -``` - -将会输出(注意前面的空行): - -``` - -harttle -``` - -可以在标签和输出的标记里面加横线(`{% raw %}{{-{% endraw %}`, `-}}`, `{% raw %}{%-{% endraw %}`, `-%}`)来移除左侧/右侧的空白。例如: - -```liquid -{% assign author = "harttle" -%} -{{ author }} -``` - -将会输出: - -``` -harttle -``` - -这个例子中 `-%}` 移除了 `assign` 标签右侧的空白。 - -## 通过选项 - -此外 LiquidJS 还提供了一系列选项来帮助扫代码式地移除空白: - -* `trimTagLeft` -* `trimTagRight` -* `trimValueRight` -* `trimValueRight` - -[LiquidJS][liquidjs] 默认 **不会** 移除任何空白字符,也就是说上面几个选项的默认值都为 `false`。这几个选项的详情请参考 [LiquidJS 选项][options]。 - -## 贪婪模式 - -上述几个设置默认情况下会跨越换行(`\n`),如果你希望保留上下空行可以把 [greedy 选项][liquidjs] 关掉,这样遇到 `\n` 就会停止。为了和 [shopify/liquid][shopify/liquid] 一致该选项默认是打开的。 - -[shopify/liquid]: https://github.com/Shopify/liquid -[liquidjs]: https://github.com/harttle/liquidjs -[options]: /api/interfaces/LiquidOptions.html -[greedy]: /api/interfaces/LiquidOptions.html#greedy \ No newline at end of file diff --git a/docs/themes/navy/languages/en.yml b/docs/themes/navy/languages/en.yml index e75e09d00..f8a787a34 100644 --- a/docs/themes/navy/languages/en.yml +++ b/docs/themes/navy/languages/en.yml @@ -10,7 +10,7 @@ index: get_started: Get Started contributors: title: Contributors - description: 'LiquidJS follows the all-contributors specification, see guidelines here! Thanks goes to these wonderful people:' + description: 'Thanks to these wonderful people! See contribution guidelines if you'd like to help.' sponsors: title: Sponsors description: 'If you personally love LiquidJS or it's benefiting your business, please sponsor us!' diff --git a/docs/themes/navy/languages/zh-cn.yml b/docs/themes/navy/languages/zh-cn.yml deleted file mode 100644 index e5ea5d3b2..000000000 --- a/docs/themes/navy/languages/zh-cn.yml +++ /dev/null @@ -1,68 +0,0 @@ -menu: - tutorials: 教程 - tags: 标签 - filters: 过滤器 - playground: 演示 - api: API - search: 搜索 - -index: - get_started: 开始使用 - contributors: - title: 贡献 - description: 'LiquidJS 欢迎任何形式的贡献,可以从 阅读贡献指南 开始!感谢这些参与过 LiquidJS 项目的人:' - sponsors: - title: 赞助 - description: '如果你喜欢 LiquidJS 或你的公司在使用 LiquidJS,请考虑 赞助 LiquidJS!' - -playground: - title: 演示 - loading: 加载中... - -page: - contents: 目录 - back_to_top: 回到顶部 - improve: 改进这篇文档 - report: 报告问题 - prev: 上一页 - next: 下一页 - last_updated: 上次更新:%s - -sidebar: - tutorials: - getting_started: 开始使用 - intro: Liquid 简介 - setup: 安装 - options: 选项 - render_file: 文件渲染 - partials: 引用/继承 - express: Express.js 中使用 - - advanced: 高级主题 - caching: 缓存 - escaping: 转义 - registration: 注册标签/过滤器 - access_scope_in_filters: 过滤器里访问上下文 - parse_parameters: 参数解析 - render_tag_content: 渲染标签内容 - drops: Liquid Drop - sync_and_async: 同步和异步 - whitespace: 换行和缩进 - plugins: 插件 - operators: 运算符 - truth: 真和假 - security_model: 安全模型 - static_analysis: 静态分析 - - miscellaneous: 其他 - migration9: '迁移到 LiquidJS 9' - contribution_guidelines: '贡献指南' - differences: 与 Shopify/liquid 的不同 - changelog: '更新日志' - filters: - overview: 概述 - tags: - overview: 概述 - -footer: - license: '本文档通过 CC BY 4.0 授权。' \ No newline at end of file diff --git a/docs/themes/navy/layout/index.swig b/docs/themes/navy/layout/index.swig index df3d895ee..7b30eeabf 100644 --- a/docs/themes/navy/layout/index.swig +++ b/docs/themes/navy/layout/index.swig @@ -1,34 +1,28 @@ -
-
-
-
- {% for news in site.data.news %} - -
{{news.date}}
-
{{news.title[page.lang]}}
-
- {% endfor %} -
-
-
-
{{ page.content }} -
import { Liquid } from 'liquidjs'
const engine = new Liquid()
const tpl = engine.parse('Welcome to {% raw %}{{v}}{% endraw %}!')
engine.render(tpl, {v: "Liquid"}).then(console.log)
// Outputs "Welcome to Liquid!"
- +
+
+
+
+
+
+

{{__('index.contributors.title')}}

+

{{__('index.contributors.description')}}

+
+
+ {{ partial('partial/all-contributors') }}
@@ -36,22 +30,13 @@
-

{{__('index.sponsors.title')}}

-

{{__('index.sponsors.description')}}

+
+

{{__('index.sponsors.title')}}

+

{{__('index.sponsors.description')}}

+
{{ partial('partial/financial-contributors') }}
-
-
-
-

{{__('index.contributors.title')}}

-

{{__('index.contributors.description')}}

-
- {{ partial('partial/all-contributors') }} -
-
-
-
diff --git a/docs/themes/navy/layout/partial/after_footer.swig b/docs/themes/navy/layout/partial/after_footer.swig index 2525251b3..68e981045 100644 --- a/docs/themes/navy/layout/partial/after_footer.swig +++ b/docs/themes/navy/layout/partial/after_footer.swig @@ -5,7 +5,6 @@ {{ js('js/main') }} -