Files
liquidjs/zh-cn/tutorials/differences.html
T

204 lines
18 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-cn">
<head prefix="og: http://ogp.me/ns#">
<meta charset="utf-8">
<title>和 Shopify/liquid 的区别 | LiquidJS</title>
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="LiquidJS is a simple, expressive and safe Shopify / Github Pages compatible template engine in pure JavaScript.">
<link rel="dns-prefetch" href="https://cdn.jsdelivr.net/">
<link rel="manifest" href="/zh-cn/manifest.json">
<!-- Canonical links -->
<link rel="canonical" href="https://liquidjs.com/zh-cn/tutorials/differences.html">
<!-- Alternative links -->
<link rel="alternative" hreflang="en" href="https://liquidjs.com/zh-cn/tutorials/differences">
<link rel="alternative" hreflang="zh-cn" href="https://liquidjs.com/zh-cn/zh-cn/tutorials/differences">
<!-- Icon -->
<link rel="apple-touch-icon" sizes="57x57" href="../../icon/apple-touch-icon-57x57.png">
<link rel="apple-touch-icon" sizes="114x114" href="../../icon/apple-touch-icon-114x114.png">
<link rel="apple-touch-icon" sizes="72x72" href="../../icon/apple-touch-icon-72x72.png">
<link rel="apple-touch-icon" sizes="144x144" href="../../icon/apple-touch-icon-144x144.png">
<link rel="apple-touch-icon" sizes="60x60" href="../../icon/apple-touch-icon-60x60.png">
<link rel="apple-touch-icon" sizes="120x120" href="../../icon/apple-touch-icon-120x120.png">
<link rel="apple-touch-icon" sizes="76x76" href="../../icon/apple-touch-icon-76x76.png">
<link rel="apple-touch-icon" sizes="152x152" href="../../icon/apple-touch-icon-152x152.png">
<link rel="icon" type="image/png" href="../../icon/favicon-196x196.png" sizes="196x196">
<link rel="icon" type="image/png" href="../../icon/favicon-160x160.png" sizes="160x160">
<link rel="icon" type="image/png" href="../../icon/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="../../icon/favicon-16x16.png" sizes="16x16">
<link rel="icon" type="image/png" href="../../icon/favicon-32x32.png" sizes="32x32">
<meta name="msapplication-TileColor" content="#2f83cd">
<meta name="msapplication-TileImage" content="../../icon/mstile-144x144.png">
<link rel="stylesheet" href="../../css/navy.css">
<link rel="alternate" href="../../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<body>
<div id="container">
<header id="header" class="wrapper">
<div id="header-inner" class="inner">
<h1 id="logo-wrap">
<a href="/zh-cn/" id="logo">LiquidJS</a>
</h1>
<nav id="main-nav">
<a href="intro-to-liquid.html" class="main-nav-link">教程</a><a href="../tags/overview.html" class="main-nav-link">标签</a><a href="../filters/overview.html" class="main-nav-link">过滤器</a><a href="../playground.html" class="main-nav-link">演示</a><a href="../api/classes/Liquid.html" class="main-nav-link">API</a>
<div id="search-input-wrap">
<i id="search-input-icon" class="icon-search"></i>
<input type="search" id="search-input" placeholder="搜索...">
</div>
</nav>
<div class="main-nav-link icon-nav-link">
<label><i class="icon-network"></i> <span class="icon-nav-title">简体中文</span></label>
<select id="lang-select" data-canonical="tutorials/differences.html">
<option value="en">English</option>
<option value="zh-cn" selected>简体中文</option>
</select>
</div>
<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs" class="main-nav-link icon-nav-link"><i class="icon-github"></i> <span class="icon-nav-title">Github</span></a>
<a target="_blank" rel="noopener external nofollow noreferrer" href="https://opencollective.com/liquidjs" class="main-nav-link icon-nav-link"><i class="icon-opencollective"></i> <span class="icon-nav-title">Support</span></a>
<a id="mobile-nav-toggle">
<span class="mobile-nav-toggle-bar"></span>
<span class="mobile-nav-toggle-bar"></span>
<span class="mobile-nav-toggle-bar"></span>
</a>
</div>
</header>
<div id="content-wrap">
<div id="content" class="wrapper">
<div id="content-inner">
<aside id="sidebar" role="navigation">
<div class="inner">
<strong class="sidebar-title">开始使用</strong><a href="intro-to-liquid.html" class="sidebar-link">Liquid 简介</a><a href="setup.html" class="sidebar-link">安装</a><a href="options.html" class="sidebar-link">选项</a><a href="render-file.html" class="sidebar-link">文件渲染</a><a href="partials-and-layouts.html" class="sidebar-link">引用/继承</a><a href="use-in-expressjs.html" class="sidebar-link">Express.js 中使用</a><strong class="sidebar-title">高级主题</strong><a href="caching.html" class="sidebar-link">缓存</a><a href="register-filters-tags.html" class="sidebar-link">注册标签/过滤器</a><a href="access-scope-in-filters.html" class="sidebar-link">过滤器里访问上下文</a><a href="parse-parameters.html" class="sidebar-link">参数解析</a><a href="render-tag-content.html" class="sidebar-link">渲染标签内容</a><a href="sync-and-async.html" class="sidebar-link">同步和异步</a><a href="whitespace-control.html" class="sidebar-link">换行和缩进</a><a href="plugins.html" class="sidebar-link">插件</a><a href="operators.html" class="sidebar-link">运算符</a><a href="truthy-and-falsy.html" class="sidebar-link">真和假</a><strong class="sidebar-title">其他</strong><a href="migrate-to-9.html" class="sidebar-link">迁移到 LiquidJS 9</a><a href="changelog.html" class="sidebar-link">更新日志</a><a href="differences.html" class="sidebar-link current">与 Shopify/liquid 的不同</a><a href="contribution-guidelines.html" class="sidebar-link">贡献指南</a>
</div>
</aside>
<article class="article-container" itemscope itemtype="http://schema.org/Article">
<div class="article-inner">
<div class="article">
<div class="inner">
<header class="article-header">
<h1 class="article-title" itemprop="name">和 Shopify/liquid 的区别</h1>
<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/edit/master/docs/source/zh-cn/tutorials/differences.md" class="article-edit-link" title="改进这篇文档"><i class="icon-pencil"></i></a>
</header>
<div class="article-content" itemprop="articleBody">
<h2 id="兼容性" class="article-heading"><a href="#兼容性" class="headerlink" title="兼容性"></a>兼容性<a class="article-anchor" href="#兼容性" aria-hidden="true"></a></h2><p>LiquidJS 一直很重视兼容于 Ruby 版本的 Liquid。Liquid 模板语言最初由 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/Shopify/liquid">Ruby 实现</a>,用于 ShopifyJekyll 以及 Github Pages,它是 Ruby 里最流行的模板引擎之一。因此由很多人用 LiquidJS 来渲染他们的 Shopify 主题和 Jekyll 站点。</p>
<p>所以“兼容”意味着让这些开发者有很好的使用体验:</p>
<ul>
<li><strong>LiquidJS 应当能够渲染语法正确的 Liquid 模板</strong>。例如 <code>forloop.index</code> 应该是 1 开始的下表,<code>nil</code> 应该渲染成空字符串而不是 <code>undefined</code> 等。即使有些功能(例如 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/236">#236</a>)用 JavaScript 很难实现,但至少 LiquidJS 会尝试实现所有的 Liquid 语义。</li>
<li><strong>所有 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/Shopify/liquid">shopify/liquid</a> 里的标签和过滤器 LiquidJS 都要实现</strong>。这之外有些业务逻辑相关的标签/过滤器尤其是 Shopify 平台上的那些,应该维护在 <a href="./plugins.html#插件列表">插件</a> 里。但是这其中有一些很有用的标签(比如 <code>&#123;% layout %&#125;</code>)LiquidJS 也会考虑实现,可以去开个 Issue 讨论一下。</li>
</ul>
<p>同时,既然现在用 JavaScript 实现了,那 Liquid 应该有更强的功能:</p>
<ul>
<li><strong>完全支持异步</strong>。所有过滤器和标签都可以实现为异步,只需要返回 <code>Promise</code> 即可。</li>
<li><strong>同时支持同步</strong>。对一些非 I/O 密集的场景,同步渲染会更快。只要模板包含的标签和过滤器都支持同步,你就可以调用类似 <code>.renderSync()</code> 这样的 API。所有内置标签和过滤器都同时支持同步和异步。</li>
<li><strong><a href="https://liquidjs.com/tutorials/render-file.html#Abstract-File-System">抽象文件系统</a></strong>。和异步功能一起使用,LiquidJS 可以实现渲染数据库里的模板 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/discussions/414">#414</a>,远程 HTTP 服务器上的模板 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/discussions/485">#485</a>,等等。</li>
<li><strong>额外的标签和过滤器</strong>。比如 <code>layout</code><code>json</code></li>
</ul>
<h2 id="区别" class="article-heading"><a href="#区别" class="headerlink" title="区别"></a>区别<a class="article-anchor" href="#区别" aria-hidden="true"></a></h2><p><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/Shopify/liquid">Shopify/liquid</a> 中的所有标签和过滤器 LiquidJS 都支持,但不包括 Shopify 主题中业务逻辑相关的标签和过滤器(如果你在找这些标签可以参考 <a href="./plugins.html#插件列表">插件列表</a>,也欢迎把你的插件添加到列表中)。尽管原则上我们尽力兼容于 Shopify/liquid,但仍然存在一些区别:</p>
<ul>
<li>真和假。在 LiquidJS 中 <code>undefined</code>, <code>null</code>, <code>false</code> 是假,之外的都是真;在 Ruby 中 <code>nil</code><code>false</code> 是假,其他都是真。见 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/pull/26">#26</a></li>
<li>数字。JavaScript 不区分浮点数和整数,因此缺失一部分整数算术,见 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/59">#59</a>。此外 <code>size</code> 过滤器作用于数字时总是返回零,而不是 Ruby 中的浮点数或整数的内存大小。</li>
<li>Drop 中的 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/Shopify/liquid/wiki/Introduction-to-Drops">.to_liquid()</a> 替换为 <code>.toLiquid()</code></li>
<li>数据的 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.rubydoc.info/gems/liquid/Liquid/Drop">.to_s()</a> 替换为 <code>.toString()</code></li>
<li>对象的迭代顺序。JavaScript 对象的迭代顺序是插入顺序和数字键递增顺序的组合,但 Ruby Hash 中只是插入顺序(JavaScript 字面量 Object 和 Ruby 字面量 Hash 的插入顺序解释也不同)。</li>
<li>排序稳定性。shopify/liquid 和 LiquidJS 都没有定义 <a href="https://liquidjs.com/filters/sort.html">sort</a> 过滤器的稳定性在,它取决于 Ruby/JavaScript 内置的排序算法,在 Node.js 12+ 和 Google Chrome 70+ LiquidJS 的排序是 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://v8.dev/features/stable-sort">稳定的</a></li>
<li>shopify/liquid 允许过滤器尾部的未匹配字符,但 LiquidJS 不允许。这就是说如果过滤器参数前忘记写冒号比如 <code>{{ "a b" | split " "}}</code> LiquidJS 会抛出异常。这是为了提升 Liquid 模板的易用性,参考 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/208">#208</a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/212">#212</a></li>
<li>LiquidJS 有额外的标签:<a href="https://liquidjs.com/tags/layout.html">layout</a> 和相应的 <code>block</code></li>
<li>LiquidJS 有额外的过滤器:<a href="https://liquidjs.com/filters/json.html">json</a></li>
</ul>
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2023-04-24T17:29:11.090Z" itemprop="dateModified">上次更新:2023-04-24</time>
<a href="changelog.html" class="article-footer-prev" title="更新日志"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="contribution-guidelines.html" class="article-footer-next" title="贡献指南"><span>下一页</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
</div>
<aside id="article-toc" role="navigation">
<div id="article-toc-inner">
<div id="article-toc-inner-list">
<strong class="sidebar-title">目录</strong>
<ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%BC%E5%AE%B9%E6%80%A7"><span class="toc-text">兼容性</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8C%BA%E5%88%AB"><span class="toc-text">区别</span></a></li></ol>
</div>
<a href="#" id="article-toc-top">回到顶部</a>
</div>
</aside>
</div>
</article>
</div>
</div>
</div>
<footer id="footer" class="wrapper">
<div class="inner">
<div id="footer-copyright">
&copy; 2023 <a href="https://github.com/harttle/liquidjs/graphs/contributors" rel="external nofollow noreferrer" target="_blank">Harttle</a><br>
本文档通过 <a href="http://creativecommons.org/licenses/by/4.0/" rel="external nofollow noreferrer" target="_blank">CC BY 4.0</a> 授权。
</div>
<div id="footer-links">
<a href="https://twitter.com/harttleharttle" rel="external nofollow noreferrer" class="footer-link" target="_blank"><i class="icon-twitter"></i></a>
<a href="https://www.patreon.com/harttle" rel="external nofollow noreferrer" class="footer-link" target="_blank"><i class="icon-patreon"></i></a>
<a href="https://opencollective.com/liquidjs" rel="external nofollow noreferrer" class="footer-link" target="_blank"><i class="icon-opencollective"></i></a>
<a href="https://github.com/harttle/liquidjs" rel="external nofollow noreferrer" class="footer-link" target="_blank"><i class="icon-github"></i></a>
</div>
</div>
</footer>
</div>
<div id="mobile-nav-dimmer"></div>
<nav id="mobile-nav">
<div id="mobile-nav-inner">
<ul id="mobile-nav-list">
<a href="intro-to-liquid.html" class="mobile-nav-link">教程</a><a href="../tags/overview.html" class="mobile-nav-link">标签</a><a href="../filters/overview.html" class="mobile-nav-link">过滤器</a><a href="../playground.html" class="mobile-nav-link">演示</a><a href="../api/classes/Liquid.html" class="mobile-nav-link">API</a>
</ul>
<div class="mobile-sidebar-list">
<strong class="mobile-nav-title">开始使用</strong><a href="intro-to-liquid.html" class="mobile-nav-link">Liquid 简介</a><a href="setup.html" class="mobile-nav-link">安装</a><a href="options.html" class="mobile-nav-link">选项</a><a href="render-file.html" class="mobile-nav-link">文件渲染</a><a href="partials-and-layouts.html" class="mobile-nav-link">引用/继承</a><a href="use-in-expressjs.html" class="mobile-nav-link">Express.js 中使用</a><strong class="mobile-nav-title">高级主题</strong><a href="caching.html" class="mobile-nav-link">缓存</a><a href="register-filters-tags.html" class="mobile-nav-link">注册标签/过滤器</a><a href="access-scope-in-filters.html" class="mobile-nav-link">过滤器里访问上下文</a><a href="parse-parameters.html" class="mobile-nav-link">参数解析</a><a href="render-tag-content.html" class="mobile-nav-link">渲染标签内容</a><a href="sync-and-async.html" class="mobile-nav-link">同步和异步</a><a href="whitespace-control.html" class="mobile-nav-link">换行和缩进</a><a href="plugins.html" class="mobile-nav-link">插件</a><a href="operators.html" class="mobile-nav-link">运算符</a><a href="truthy-and-falsy.html" class="mobile-nav-link">真和假</a><strong class="mobile-nav-title">其他</strong><a href="migrate-to-9.html" class="mobile-nav-link">迁移到 LiquidJS 9</a><a href="changelog.html" class="mobile-nav-link">更新日志</a><a href="differences.html" class="mobile-nav-link current">与 Shopify/liquid 的不同</a><a href="contribution-guidelines.html" class="mobile-nav-link">贡献指南</a>
</div>
</div>
<div id="mobile-button-list">
<a href="https://github.com/harttle/liquidjs" class="mobile-nav-link" rel="external" target="_blank"><i class="icon-github"></i></a>
<a href="https://opencollective.com/liquidjs" class="mobile-nav-link" rel="external" target="_blank"><i class="icon-opencollective"></i></a>
<div id="mobile-lang-select-wrap" class="mobile-nav-link">
<label for="mobile-lang-select"><i class="icon-network"></i></label>
<select id="mobile-lang-select" data-canonical="tutorials/differences.html">
<option value="en">English</option>
<option value="zh-cn" selected>简体中文</option>
</select>
</div>
</div>
</nav>
<script src="../../js/main.js"></script>
<script src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js"></script>
<script>
document.getElementById('search-input-wrap').classList.add('on');
docsearch({
apiKey: '01f36cc168657a26a385308b9e721bc6',
indexName: 'liquidjs',
inputSelector: '#search-input',
debug: false
});
</script>
</body>
</html>