mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-17 05:10:40 -07:00
Deploying to gh-pages from @ harttle/liquidjs@292a93b738 🚀
This commit is contained in:
@@ -93,10 +93,19 @@
|
||||
</header>
|
||||
<div class="article-content" itemprop="articleBody">
|
||||
<p>在 <a href="/tutorials/register-filters-tags.html">注册过滤器和标签</a> 里介绍过,可以在函数参数里直接获得过滤器的参数:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Usage: {{ 1 | add: 2, 3 }}</span></span><br><span class="line"><span class="comment">// Output: 6</span></span><br><span class="line">engine.<span class="title function_">registerFilter</span>(<span class="string">'add'</span>, <span class="function">(<span class="params">initial, arg1, arg2</span>) =></span> initial + arg1 + arg2)</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// Usage: {{ 1 | add: 2, 3 }}</span>
|
||||
<span class="token comment">// Output: 6</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">registerFilter</span><span class="token punctuation">(</span><span class="token string">'add'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">initial<span class="token punctuation">,</span> arg1<span class="token punctuation">,</span> arg2</span><span class="token punctuation">)</span> <span class="token operator">=></span> initial <span class="token operator">+</span> arg1 <span class="token operator">+</span> arg2<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>但有些过滤器还需要访问当前上下文的变量,比如把 URL 路径转换为完整的 URL 时,需要访问上下文的 <code>origin</code> 变量:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Usage: {{ '/index.html' | fullURL }}</span></span><br><span class="line"><span class="comment">// Scope: { origin: "https://liquidjs.com" }</span></span><br><span class="line"><span class="comment">// Output: https://liquidjs.com/index.html</span></span><br><span class="line"></span><br><span class="line">engine.<span class="title function_">registerFilter</span>(<span class="string">'fullURL'</span>, <span class="keyword">function</span> (<span class="params">path</span>) {</span><br><span class="line"> <span class="keyword">const</span> origin = <span class="variable language_">this</span>.<span class="property">context</span>.<span class="title function_">get</span>([<span class="string">'origin'</span>])</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="title function_">URL</span>(path, origin).<span class="title function_">toString</span>() </span><br><span class="line">})</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// Usage: {{ '/index.html' | fullURL }}</span>
|
||||
<span class="token comment">// Scope: { origin: "https://liquidjs.com" }</span>
|
||||
<span class="token comment">// Output: https://liquidjs.com/index.html</span>
|
||||
|
||||
engine<span class="token punctuation">.</span><span class="token function">registerFilter</span><span class="token punctuation">(</span><span class="token string">'fullURL'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">path</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">const</span> origin <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>context<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">'origin'</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
|
||||
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">URL</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> origin<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>见这个 JSFiddle:<a target="_blank" rel="noopener external nofollow noreferrer" href="http://jsfiddle.net/ctj364up/1/">http://jsfiddle.net/ctj364up/1/</a>。</p>
|
||||
<blockquote class="note warn"><strong class="note-title">箭头函数</strong><p>在箭头函数里 <code>this</code> 会绑定到当前 JavaScript 上下文,你需要用 <code>function(){}</code> 来替代 <code>()=>{}</code> 语法,才能正确地访问 <code>this.context</code>。</p>
|
||||
@@ -105,7 +114,7 @@
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="register-filters-tags.html" class="article-footer-prev" title="注册标签/过滤器"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="parse-parameters.html" class="article-footer-next" title="参数解析"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -96,19 +96,34 @@
|
||||
<p>LiquidJS 在这一方面比较灵活,提供了多种不同的方式来达到提升性能的目的。</p>
|
||||
<h2 id="手动缓存" class="article-heading"><a href="#手动缓存" class="headerlink" title="手动缓存"></a>手动缓存<a class="article-anchor" href="#手动缓存" aria-hidden="true"></a></h2><p><a href="/api/classes/Liquid.html#parse">.parse()</a>, <a href="/api/classes/Liquid.html#parseFile">.parseFile()</a>, <a href="/api/classes/Liquid.html#parseFileSync">.parseFileSync()</a> API 可以用来把字符串或文件解析成模板。得到的模板可以用不同的数据去重复地渲染得到不同的 HTML。</p>
|
||||
<p>从字符串解析:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> tpl = engine.<span class="title function_">parse</span>(<span class="string">'{{name | capitalize}}'</span>);</span><br><span class="line"></span><br><span class="line">engine.<span class="title function_">renderSync</span>(tpl, {<span class="attr">name</span>: <span class="string">'alice'</span>}) <span class="comment">// 'Alice'</span></span><br><span class="line">engine.<span class="title function_">renderSync</span>(tpl, {<span class="attr">name</span>: <span class="string">'bob'</span>}) <span class="comment">// 'Bob'</span></span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> tpl <span class="token operator">=</span> engine<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span><span class="token string">'{{name | capitalize}}'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
|
||||
engine<span class="token punctuation">.</span><span class="token function">renderSync</span><span class="token punctuation">(</span>tpl<span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'alice'</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment">// 'Alice'</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">renderSync</span><span class="token punctuation">(</span>tpl<span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'bob'</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment">// 'Bob'</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>从文件解析:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> tpl = engine.<span class="title function_">parseFileSync</span>(<span class="string">'hello'</span>); <span class="comment">// contents of `hello.liquid`: {{name}}</span></span><br><span class="line"></span><br><span class="line">engine.<span class="title function_">renderSync</span>(tpl, {<span class="attr">name</span>: <span class="string">'alice'</span>}) <span class="comment">// 'Alice'</span></span><br><span class="line">engine.<span class="title function_">renderSync</span>(tpl, {<span class="attr">name</span>: <span class="string">'bob'</span>}) <span class="comment">// 'Bob'</span></span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> tpl <span class="token operator">=</span> engine<span class="token punctuation">.</span><span class="token function">parseFileSync</span><span class="token punctuation">(</span><span class="token string">'hello'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// contents of `hello.liquid`: {{name}}</span>
|
||||
|
||||
engine<span class="token punctuation">.</span><span class="token function">renderSync</span><span class="token punctuation">(</span>tpl<span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'alice'</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment">// 'Alice'</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">renderSync</span><span class="token punctuation">(</span>tpl<span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'bob'</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment">// 'Bob'</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>上述代码中字符串或文件只被解析了一次,可以反复利用去渲染不同的数据。有很多模板文件时可以把 <code>tpl</code> 变量存在 <code>Map</code> 中,后续再 <code>.render()</code> 时直接从 Map 中拿出解析好的模板去渲染。</p>
|
||||
<h2 id="cache-选项" class="article-heading"><a href="#cache-选项" class="headerlink" title="cache 选项"></a><code>cache</code> 选项<a class="article-anchor" href="#cache-选项" aria-hidden="true"></a></h2><p>如果你只用 <code>.renderFile()</code> 和 <code>.renderFileSync()</code> 也可以直接设置 <a href="/api/interfaces/LiquidOptions.html#cache">cache</a> 选项,LiquidJS 会帮你缓存。</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> { <span class="title class_">Liquid</span> } = <span class="built_in">require</span>(<span class="string">'liquidjs'</span>);</span><br><span class="line"><span class="keyword">var</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>({</span><br><span class="line"> <span class="attr">cache</span>: <span class="literal">true</span></span><br><span class="line">});</span><br><span class="line"></span><br><span class="line"><span class="comment">// LiquidJS 将会解析 hello.liquid 然后用 {name: 'alice'} 渲染它</span></span><br><span class="line">engine.<span class="title function_">renderFileSync</span>(<span class="string">'hello'</span>, {<span class="attr">name</span>: <span class="string">'alice'</span>})</span><br><span class="line"></span><br><span class="line"><span class="comment">// LiquidJS 会找到上次 hello.liquid 解析的结果模板,再用 {name: 'bob'} 渲染它</span></span><br><span class="line">engine.<span class="title function_">renderFileSync</span>(<span class="string">'hello'</span>, {<span class="attr">name</span>: <span class="string">'bob'</span>})</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> <span class="token punctuation">{</span> Liquid <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'liquidjs'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
<span class="token keyword">var</span> engine <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Liquid</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
|
||||
<span class="token literal-property property">cache</span><span class="token operator">:</span> <span class="token boolean">true</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
|
||||
<span class="token comment">// LiquidJS 将会解析 hello.liquid 然后用 {name: 'alice'} 渲染它</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">renderFileSync</span><span class="token punctuation">(</span><span class="token string">'hello'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'alice'</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||||
|
||||
<span class="token comment">// LiquidJS 会找到上次 hello.liquid 解析的结果模板,再用 {name: 'bob'} 渲染它</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">renderFileSync</span><span class="token punctuation">(</span><span class="token string">'hello'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'bob'</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="use-in-expressjs.html" class="article-footer-prev" title="Express.js 中使用"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="escaping.html" class="article-footer-next" title="转义"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -746,7 +746,7 @@
|
||||
</script></li></ul>
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:37:03.734Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:42.372Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="migrate-to-9.html" class="article-footer-prev" title="迁移到 LiquidJS 9"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="differences.html" class="article-footer-next" title="与 Shopify/liquid 的不同"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="differences.html" class="article-footer-prev" title="与 Shopify/liquid 的不同"><i class="icon-chevron-left"></i><span>上一页</span></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</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>
|
||||
|
||||
@@ -94,23 +94,32 @@
|
||||
<div class="article-content" itemprop="articleBody">
|
||||
<p>当模板或数据上下文不可信时,启用DoS预防选项至关重要。LiquidJS 提供了三个选项用于此目的:<code>parseLimit</code>、<code>renderLimit</code> 和 <code>memoryLimit</code>。</p>
|
||||
<h2 id="TL-DR" class="article-heading"><a href="#TL-DR" class="headerlink" title="TL;DR"></a>TL;DR<a class="article-anchor" href="#TL-DR" aria-hidden="true"></a></h2><p>设置这些选项可以在很大程度上确保你的 LiquidJS 实例不会长时间挂起或消耗过多内存。这些限制基于可用的 JavaScript API,因此它们不是精确的硬性限制,而是确保你的进程不会失败或挂起的阈值。</p>
|
||||
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> liquid = <span class="keyword">new</span> <span class="title class_">Liquid</span>({</span><br><span class="line"> <span class="attr">parseLimit</span>: <span class="number">1e8</span>, <span class="comment">// 每次渲染的模板的典型大小</span></span><br><span class="line"> <span class="attr">renderLimit</span>: <span class="number">1000</span>, <span class="comment">// 每次渲染最多 1s</span></span><br><span class="line"> <span class="attr">memoryLimit</span>: <span class="number">1e9</span>, <span class="comment">// LiquidJS 可用的内存(1e9 对应 1GB)</span></span><br><span class="line">})</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token keyword">const</span> liquid <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Liquid</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
|
||||
parseLimit<span class="token operator">:</span> <span class="token number">1e8</span><span class="token punctuation">,</span> <span class="token comment">// 每次渲染的模板的典型大小</span>
|
||||
renderLimit<span class="token operator">:</span> <span class="token number">1000</span><span class="token punctuation">,</span> <span class="token comment">// 每次渲染最多 1s</span>
|
||||
memoryLimit<span class="token operator">:</span> <span class="token number">1e9</span><span class="token punctuation">,</span> <span class="token comment">// LiquidJS 可用的内存(1e9 对应 1GB)</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<h2 id="parseLimit" class="article-heading"><a href="#parseLimit" class="headerlink" title="parseLimit"></a>parseLimit<a class="article-anchor" href="#parseLimit" aria-hidden="true"></a></h2><p><a href="/api/interfaces/LiquidOptions.html#parseLimit">parseLimit</a> 限制每次 <code>.parse()</code> 调用中解析的模板大小(字符长度),包括引用的 partials 和 layouts。由于 LiquidJS 解析模板字符串的时间复杂度接近 O(n),限制模板总长度通常就足够了。</p>
|
||||
<p>普通电脑可以很容易处理 <code>1e8</code>(100M)个字符的模板。</p>
|
||||
<h2 id="renderLimit" class="article-heading"><a href="#renderLimit" class="headerlink" title="renderLimit"></a>renderLimit<a class="article-anchor" href="#renderLimit" aria-hidden="true"></a></h2><p>仅限制模板大小是不够的,因为在渲染时可能会出现动态的数组和循环。<a href="/api/interfaces/LiquidOptions.html#renderLimit">renderLimit</a> 通过限制每次 <code>render()</code> 调用的时间来缓解这些问题。</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">{%- for i in (1..10000000) -%}</span><br><span class="line"> order: {{i}}</span><br><span class="line">{%- endfor -%}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%-</span> <span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token range operator">..</span><span class="token number">10000000</span><span class="token punctuation">)</span> <span class="token delimiter punctuation">-%}</span></span>
|
||||
order: <span class="token liquid language-liquid"><span class="token delimiter punctuation">{{</span>i<span class="token delimiter punctuation">}}</span></span>
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{%-</span> <span class="token keyword">endfor</span> <span class="token delimiter punctuation">-%}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>渲染时间是在渲染每个模板之前检查的。在上面的例子中,循环中有两个模板:<code>order:</code> 和 <code>{{i}}</code>,因此会检查 2x10000000 次。</p>
|
||||
<p>单个模板内的标签和过滤器仍然可能把进程挂起。要完全控制渲染过程,建议使用类似 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.npmjs.com/package/paralleljs">paralleljs</a> 的进程管理器。</p>
|
||||
<h2 id="memoryLimit" class="article-heading"><a href="#memoryLimit" class="headerlink" title="memoryLimit"></a>memoryLimit<a class="article-anchor" href="#memoryLimit" aria-hidden="true"></a></h2><p>即使模板和迭代次数较少,内存使用量也可能呈指数增长。在下面的示例中,内存会在每次迭代中翻倍:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">{% assign array = "1,2,3" | split: "," %}</span><br><span class="line">{% for i in (1..32) %}</span><br><span class="line"> {% assign array = array | concat: array %}</span><br><span class="line">{% endfor %}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">assign</span> array <span class="token operator">=</span> <span class="token string">"1,2,3"</span> <span class="token operator">|</span> <span class="token function filter">split</span><span class="token operator">:</span> <span class="token string">","</span> <span class="token delimiter punctuation">%}</span></span>
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token range operator">..</span><span class="token number">32</span><span class="token punctuation">)</span> <span class="token delimiter punctuation">%}</span></span>
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">assign</span> array <span class="token operator">=</span> array <span class="token operator">|</span> <span class="token function filter">concat</span><span class="token operator">:</span> array <span class="token delimiter punctuation">%}</span></span>
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">endfor</span> <span class="token delimiter punctuation">%}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p><a href="/api/interfaces/LiquidOptions.html#memoryLimit">memoryLimit</a> 限制内存敏感的过滤器,以防止过度的内存分配。由于 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_management">JavaScript 使用 GC 来管理内存</a>,<code>memoryLimit</code> 仅限制 LiquidJS 中内存敏感过滤器分配的对象总数,因此可能无法反映实际的内存占用。</p>
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="truthy-and-falsy.html" class="article-footer-prev" title="真和假"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="migrate-to-9.html" class="article-footer-next" title="迁移到 LiquidJS 9"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
+106
-10
@@ -96,7 +96,23 @@
|
||||
<blockquote class="note info"><strong class="note-title">JavaScript 中的 Drop</strong><p><em>Drop</em> 接口在 LiquidJS 中实现方式与内置过滤器和其他模板功能不同。由于 LiquidJS 在 JavaScript 中运行,自定义 Drop 在 JavaScript 中一定需要重新实现。JavaScript 类与 Ruby 类之间没有兼容性可言。</p>
|
||||
</blockquote>
|
||||
|
||||
<h2 id="基本用法" class="article-heading"><a href="#基本用法" class="headerlink" title="基本用法"></a>基本用法<a class="article-anchor" href="#基本用法" aria-hidden="true"></a></h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">Liquid</span>, <span class="title class_">Drop</span> } <span class="keyword">from</span> <span class="string">'liquidjs'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">SettingsDrop</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Drop</span> {</span><br><span class="line"> <span class="title function_">constructor</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="variable language_">super</span>()</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">foo</span> = <span class="string">'FOO'</span></span><br><span class="line"> }</span><br><span class="line"> <span class="title function_">bar</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'BAR'</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>()</span><br><span class="line"><span class="keyword">const</span> template = <span class="string">`foo: {{settings.foo}}, bar: {{settings.bar}}`</span></span><br><span class="line"><span class="keyword">const</span> context = { <span class="attr">settings</span>: <span class="keyword">new</span> <span class="title class_">SettingsDrop</span>() }</span><br><span class="line"><span class="comment">// 输出: "foo: FOO, bar: BAR"</span></span><br><span class="line">engine.<span class="title function_">parseAndRender</span>(template, context).<span class="title function_">then</span>(<span class="function"><span class="params">html</span> =></span> <span class="variable language_">console</span>.<span class="title function_">log</span>(html))</span><br></pre></td></tr></table></figure>
|
||||
<h2 id="基本用法" class="article-heading"><a href="#基本用法" class="headerlink" title="基本用法"></a>基本用法<a class="article-anchor" href="#基本用法" aria-hidden="true"></a></h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">import</span> <span class="token punctuation">{</span> Liquid<span class="token punctuation">,</span> Drop <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'liquidjs'</span>
|
||||
|
||||
<span class="token keyword">class</span> <span class="token class-name">SettingsDrop</span> <span class="token keyword">extends</span> <span class="token class-name">Drop</span> <span class="token punctuation">{</span>
|
||||
<span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">super</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>foo <span class="token operator">=</span> <span class="token string">'FOO'</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token function">bar</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">return</span> <span class="token string">'BAR'</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span>
|
||||
|
||||
<span class="token keyword">const</span> engine <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Liquid</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||||
<span class="token keyword">const</span> template <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">foo: {{settings.foo}}, bar: {{settings.bar}}</span><span class="token template-punctuation string">`</span></span>
|
||||
<span class="token keyword">const</span> context <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">settings</span><span class="token operator">:</span> <span class="token keyword">new</span> <span class="token class-name">SettingsDrop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span>
|
||||
<span class="token comment">// 输出: "foo: FOO, bar: BAR"</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">parseAndRender</span><span class="token punctuation">(</span>template<span class="token punctuation">,</span> context<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">html</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>html<span class="token punctuation">)</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p><a target="_blank" rel="noopener external nofollow noreferrer" href="https://runkit.com/embed/2is7di4mc7kk">Runkit 链接</a></p>
|
||||
<p>如上所示,除了从上下文作用域中读取属性外,还可以调用方法。您只需创建一个继承自 <code>Drop</code> 的自定义类。</p>
|
||||
@@ -104,19 +120,93 @@
|
||||
</blockquote>
|
||||
|
||||
<h2 id="liquidMethodMissing" class="article-heading"><a href="#liquidMethodMissing" class="headerlink" title="liquidMethodMissing"></a>liquidMethodMissing<a class="article-anchor" href="#liquidMethodMissing" aria-hidden="true"></a></h2><p>如果属性名不能静态地确定的情况下,可以利用 <code>liquidMethodMissing</code> 来动态解析变量的值。</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">Liquid</span>, <span class="title class_">Drop</span> } <span class="keyword">from</span> <span class="string">'liquidjs'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">SettingsDrop</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Drop</span> {</span><br><span class="line"> <span class="title function_">liquidMethodMissing</span>(<span class="params">key</span>) {</span><br><span class="line"> <span class="keyword">return</span> key.<span class="title function_">toUpperCase</span>()</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>()</span><br><span class="line"><span class="comment">// 输出: "COO"</span></span><br><span class="line">engine.<span class="title function_">parseAndRender</span>(<span class="string">"{{settings.coo}}"</span>, { <span class="attr">settings</span>: <span class="keyword">new</span> <span class="title class_">SettingsDrop</span>() })</span><br><span class="line"> .<span class="title function_">then</span>(<span class="function"><span class="params">html</span> =></span> <span class="variable language_">console</span>.<span class="title function_">log</span>(html))</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">import</span> <span class="token punctuation">{</span> Liquid<span class="token punctuation">,</span> Drop <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'liquidjs'</span>
|
||||
|
||||
<span class="token keyword">class</span> <span class="token class-name">SettingsDrop</span> <span class="token keyword">extends</span> <span class="token class-name">Drop</span> <span class="token punctuation">{</span>
|
||||
<span class="token function">liquidMethodMissing</span><span class="token punctuation">(</span><span class="token parameter">key</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">return</span> key<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span>
|
||||
|
||||
<span class="token keyword">const</span> engine <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Liquid</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||||
<span class="token comment">// 输出: "COO"</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">parseAndRender</span><span class="token punctuation">(</span><span class="token string">"{{settings.coo}}"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">settings</span><span class="token operator">:</span> <span class="token keyword">new</span> <span class="token class-name">SettingsDrop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">html</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>html<span class="token punctuation">)</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p><code>liquidMethodMissing</code> 支持 Promise,这意味着您可以在其中进行异步调用。一个更有用的例子是通过使用 Drop 动态地从数据库获取值。通过使用 Drop,您可以避免将每个属性都硬编码到上下文中。例如:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">Liquid</span>, <span class="title class_">Drop</span> } <span class="keyword">from</span> <span class="string">'liquidjs'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">DBDrop</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Drop</span> {</span><br><span class="line"> <span class="keyword">async</span> <span class="title function_">liquidMethodMissing</span>(<span class="params">key</span>) {</span><br><span class="line"> <span class="keyword">const</span> record = <span class="keyword">await</span> db.<span class="title function_">getRecordByKey</span>(key)</span><br><span class="line"> <span class="keyword">return</span> record.<span class="property">value</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>()</span><br><span class="line"><span class="keyword">const</span> context = { <span class="attr">db</span>: <span class="keyword">new</span> <span class="title class_">DBDrop</span>() }</span><br><span class="line">engine.<span class="title function_">parseAndRender</span>(<span class="string">"{{db.coo}}"</span>, context).<span class="title function_">then</span>(<span class="function"><span class="params">html</span> =></span> <span class="variable language_">console</span>.<span class="title function_">log</span>(html))</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">import</span> <span class="token punctuation">{</span> Liquid<span class="token punctuation">,</span> Drop <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'liquidjs'</span>
|
||||
|
||||
<span class="token keyword">class</span> <span class="token class-name">DBDrop</span> <span class="token keyword">extends</span> <span class="token class-name">Drop</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">async</span> <span class="token function">liquidMethodMissing</span><span class="token punctuation">(</span><span class="token parameter">key</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">const</span> record <span class="token operator">=</span> <span class="token keyword">await</span> db<span class="token punctuation">.</span><span class="token function">getRecordByKey</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span>
|
||||
<span class="token keyword">return</span> record<span class="token punctuation">.</span>value
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span>
|
||||
|
||||
<span class="token keyword">const</span> engine <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Liquid</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||||
<span class="token keyword">const</span> context <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">db</span><span class="token operator">:</span> <span class="token keyword">new</span> <span class="token class-name">DBDrop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">parseAndRender</span><span class="token punctuation">(</span><span class="token string">"{{db.coo}}"</span><span class="token punctuation">,</span> context<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">html</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>html<span class="token punctuation">)</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<h2 id="valueOf-NaN" class="article-heading"><a href="#valueOf-NaN" class="headerlink" title="valueOf"></a>valueOf<a class="article-anchor" href="#valueOf-NaN" aria-hidden="true"></a></h2><p>Drop 可以实现一个 <code>valueOf()</code> 方法,用于在输出中替换自身。例如:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">Liquid</span>, <span class="title class_">Drop</span> } <span class="keyword">from</span> <span class="string">'liquidjs'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">ColorDrop</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Drop</span> {</span><br><span class="line"> <span class="title function_">valueOf</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'red'</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>()</span><br><span class="line"><span class="keyword">const</span> context = { <span class="attr">color</span>: <span class="keyword">new</span> <span class="title class_">ColorDrop</span>() }</span><br><span class="line"><span class="comment">// 输出: "red"</span></span><br><span class="line">engine.<span class="title function_">parseAndRender</span>(<span class="string">"{{color}}"</span>, context).<span class="title function_">then</span>(<span class="function"><span class="params">html</span> =></span> <span class="variable language_">console</span>.<span class="title function_">log</span>(html))</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">import</span> <span class="token punctuation">{</span> Liquid<span class="token punctuation">,</span> Drop <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'liquidjs'</span>
|
||||
|
||||
<span class="token keyword">class</span> <span class="token class-name">ColorDrop</span> <span class="token keyword">extends</span> <span class="token class-name">Drop</span> <span class="token punctuation">{</span>
|
||||
<span class="token function">valueOf</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">return</span> <span class="token string">'red'</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span>
|
||||
|
||||
<span class="token keyword">const</span> engine <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Liquid</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||||
<span class="token keyword">const</span> context <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token keyword">new</span> <span class="token class-name">ColorDrop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span>
|
||||
<span class="token comment">// 输出: "red"</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">parseAndRender</span><span class="token punctuation">(</span><span class="token string">"{{color}}"</span><span class="token punctuation">,</span> context<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">html</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>html<span class="token punctuation">)</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<h2 id="toLiquid" class="article-heading"><a href="#toLiquid" class="headerlink" title="toLiquid"></a>toLiquid<a class="article-anchor" href="#toLiquid" aria-hidden="true"></a></h2><p><code>toLiquid()</code> 不是 <code>Drop</code> 的方法,但它可以用于返回一个 <code>Drop</code>。在您有一个上下文中固定结构且不能更改其值的情况下,您可以实现 <code>toLiquid()</code>,以便让 LiquidJS 使用返回的值而不是自身来渲染模板。</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">Liquid</span>, <span class="title class_">Drop</span> } <span class="keyword">from</span> <span class="string">'liquidjs'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> context = {</span><br><span class="line"> <span class="attr">person</span>: {</span><br><span class="line"> <span class="attr">firstName</span>: <span class="string">"Jun"</span>,</span><br><span class="line"> <span class="attr">lastName</span>: <span class="string">"Yang"</span>,</span><br><span class="line"> <span class="attr">name</span>: <span class="string">"Jun Yang"</span>,</span><br><span class="line"> <span class="attr">toLiquid</span>: <span class="function">() =></span> ({</span><br><span class="line"> <span class="attr">firstName</span>: <span class="variable language_">this</span>.<span class="property">firstName</span>,</span><br><span class="line"> <span class="attr">lastName</span>: <span class="variable language_">this</span>.<span class="property">lastName</span>,</span><br><span class="line"> <span class="comment">// 使用不同的 `name`</span></span><br><span class="line"> <span class="attr">name</span>: <span class="string">"Yang, Jun"</span></span><br><span class="line"> })</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>()</span><br><span class="line"><span class="comment">// 输出: "Yang, Jun"</span></span><br><span class="line">engine.<span class="title function_">parseAndRender</span>(<span class="string">"{{person.name}}"</span>, context).<span class="title function_">then</span>(<span class="function"><span class="params">html</span> =></span> <span class="variable language_">console</span>.<span class="title function_">log</span>(html))</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">import</span> <span class="token punctuation">{</span> Liquid<span class="token punctuation">,</span> Drop <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'liquidjs'</span>
|
||||
|
||||
<span class="token keyword">const</span> context <span class="token operator">=</span> <span class="token punctuation">{</span>
|
||||
<span class="token literal-property property">person</span><span class="token operator">:</span> <span class="token punctuation">{</span>
|
||||
<span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Jun"</span><span class="token punctuation">,</span>
|
||||
<span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Yang"</span><span class="token punctuation">,</span>
|
||||
<span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Jun Yang"</span><span class="token punctuation">,</span>
|
||||
<span class="token function-variable function">toLiquid</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
|
||||
<span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>firstName<span class="token punctuation">,</span>
|
||||
<span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>lastName<span class="token punctuation">,</span>
|
||||
<span class="token comment">// 使用不同的 `name`</span>
|
||||
<span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Yang, Jun"</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span>
|
||||
|
||||
<span class="token keyword">const</span> engine <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Liquid</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||||
<span class="token comment">// 输出: "Yang, Jun"</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">parseAndRender</span><span class="token punctuation">(</span><span class="token string">"{{person.name}}"</span><span class="token punctuation">,</span> context<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">html</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>html<span class="token punctuation">)</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>当然,您还可以在 <code>toLiquid()</code> 方法中返回一个 <code>PersonDrop</code> 实例,并在 <code>PersonDrop</code> 中实现此功能:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">Liquid</span>, <span class="title class_">Drop</span> } <span class="keyword">from</span> <span class="string">'liquidjs'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">PersonDrop</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Drop</span> {</span><br><span class="line"> <span class="title function_">constructor</span>(<span class="params">person</span>) {</span><br><span class="line"> <span class="variable language_">super</span>()</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">person</span> = person</span><br><span class="line"> }</span><br><span class="line"> <span class="title function_">name</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">person</span>.<span class="property">lastName</span> + <span class="string">", "</span> + <span class="variable language_">this</span>.<span class="property">person</span>.<span class="property">firstName</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> context = {</span><br><span class="line"> <span class="attr">person</span>: {</span><br><span class="line"> <span class="attr">firstName</span>: <span class="string">"Jun"</span>,</span><br><span class="line"> <span class="attr">lastName</span>: <span class="string">"Yang"</span>,</span><br><span class="line"> <span class="attr">name</span>: <span class="string">"Jun Yang"</span>,</span><br><span class="line"> <span class="attr">toLiquid</span>: <span class="keyword">function</span> (<span class="params"></span>) { <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">PersonDrop</span>(<span class="variable language_">this</span>) }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>()</span><br><span class="line"><span class="comment">// 输出: "Yang, Jun"</span></span><br><span class="line">engine.<span class="title function_">parseAndRender</span>(<span class="string">"{{person.name}}"</span>, context).<span class="title function_">then</span>(<span class="function"><span class="params">html</span> =></span> <span class="variable language_">console</span>.<span class="title function_">log</span>(html))</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">import</span> <span class="token punctuation">{</span> Liquid<span class="token punctuation">,</span> Drop <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'liquidjs'</span>
|
||||
|
||||
<span class="token keyword">class</span> <span class="token class-name">PersonDrop</span> <span class="token keyword">extends</span> <span class="token class-name">Drop</span> <span class="token punctuation">{</span>
|
||||
<span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">person</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">super</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>person <span class="token operator">=</span> person
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token function">name</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>person<span class="token punctuation">.</span>lastName <span class="token operator">+</span> <span class="token string">", "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>person<span class="token punctuation">.</span>firstName
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span>
|
||||
|
||||
<span class="token keyword">const</span> context <span class="token operator">=</span> <span class="token punctuation">{</span>
|
||||
<span class="token literal-property property">person</span><span class="token operator">:</span> <span class="token punctuation">{</span>
|
||||
<span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Jun"</span><span class="token punctuation">,</span>
|
||||
<span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Yang"</span><span class="token punctuation">,</span>
|
||||
<span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Jun Yang"</span><span class="token punctuation">,</span>
|
||||
<span class="token function-variable function">toLiquid</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">PersonDrop</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span> <span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span>
|
||||
|
||||
<span class="token keyword">const</span> engine <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Liquid</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||||
<span class="token comment">// 输出: "Yang, Jun"</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">parseAndRender</span><span class="token punctuation">(</span><span class="token string">"{{person.name}}"</span><span class="token punctuation">,</span> context<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">html</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>html<span class="token punctuation">)</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<blockquote class="note info"><strong class="note-title"><code>toLiquid()</code> 和 <code>valueOf()</code> 的区别</strong><ul>
|
||||
<li><code>valueOf()</code> 通常用来定义当前变量如何渲染,<code>toLiquid()</code> 通常用来把一个对象转换为 Drop 或另一个提供给模板的 scope。</li>
|
||||
@@ -126,22 +216,28 @@
|
||||
|
||||
<h2 id="特殊-Drop" class="article-heading"><a href="#特殊-Drop" class="headerlink" title="特殊 Drop"></a>特殊 Drop<a class="article-anchor" href="#特殊-Drop" aria-hidden="true"></a></h2><p>LiquidJS 本身实现了几个内置 Drop,以促进模板编写。此部分与 Shopify Liquid 兼容,因为我们需要模板具有可移植性。</p>
|
||||
<h3 id="blank" class="article-heading"><a href="#blank" class="headerlink" title="blank"></a>blank<a class="article-anchor" href="#blank" aria-hidden="true"></a></h3><p>用于检查字符串变量是否为 <code>false</code>、<code>null</code>、<code>undefined</code>、空字符串或字符串仅包含空白字符。</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">{% unless author == blank %}</span><br><span class="line"> {{author}}</span><br><span class="line">{% endif %}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">unless</span> author <span class="token operator">==</span> blank <span class="token delimiter punctuation">%}</span></span>
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{{</span>author<span class="token delimiter punctuation">}}</span></span>
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">endif</span> <span class="token delimiter punctuation">%}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<h3 id="empty" class="article-heading"><a href="#empty" class="headerlink" title="empty"></a>empty<a class="article-anchor" href="#empty" aria-hidden="true"></a></h3><p>用于检查数组、字符串或对象是否为空。</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">{% if authors == empty %}</span><br><span class="line"> 作者列表为空</span><br><span class="line">{% endif %}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">if</span> authors <span class="token operator">==</span> <span class="token empty keyword">empty</span> <span class="token delimiter punctuation">%}</span></span>
|
||||
作者列表为空
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">endif</span> <span class="token delimiter punctuation">%}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<blockquote class="note info"><strong class="note-title"><code>empty</code> 的实现</strong><p>对于数组和字符串,LiquidJS 检查它们的 <code>.length</code> 属性。对于对象,LiquidJS 调用 <code>Object.keys()</code> 来检查它是否有键。</p>
|
||||
</blockquote>
|
||||
|
||||
<h3 id="nil" class="article-heading"><a href="#nil" class="headerlink" title="nil"></a>nil<a class="article-anchor" href="#nil" aria-hidden="true"></a></h3><p><code>nil</code> Drop 用于检查变量是否未定义或定义为 <code>null</code> 或 <code>undefined</code>,本质上等同于 JavaScript 的 <code>== null</code> 检查。</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">{% if notexist == nil %}</span><br><span class="line"> 空变量</span><br><span class="line">{% endif %}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">if</span> notexist <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token delimiter punctuation">%}</span></span>
|
||||
空变量
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">endif</span> <span class="token delimiter punctuation">%}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<h3 id="其他-Drop" class="article-heading"><a href="#其他-Drop" class="headerlink" title="其他 Drop"></a>其他 Drop<a class="article-anchor" href="#其他-Drop" aria-hidden="true"></a></h3><p>仍然有一些特定标签的 Drop,例如 <code>forloop</code>、<code>tablerowloop</code>、<code>block</code>,这些在各自的标签文档中有详细介绍。</p>
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="render-tag-content.html" class="article-footer-prev" title="渲染标签内容"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="sync-and-async.html" class="article-footer-next" title="同步和异步"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -99,37 +99,43 @@
|
||||
</ol>
|
||||
<h2 id="HTML-转义" class="article-heading"><a href="#HTML-转义" class="headerlink" title="HTML 转义"></a>HTML 转义<a class="article-anchor" href="#HTML-转义" aria-hidden="true"></a></h2><p>默认情况下输出是不转义的,但你可以用 <a href="../filters/escape.html">escape</a> 过滤器来做 HTML 转义:</p>
|
||||
<p>输入</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">{{ "1 < 2" | escape }}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{{</span> <span class="token string">"1 < 2"</span> <span class="token operator">|</span> <span class="token function filter">escape</span> <span class="token delimiter punctuation">}}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
<p>输出</p>
|
||||
<figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">1 &lt; 2</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-text" data-language="text"><code class="language-text">1 &lt; 2<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
<p>LiquidJS 也提供了其他过滤器来支持不同的转义需求:<a href="../filters/escape.html">escape_once</a>, <a href="../filters/newline_to_br.html">newline_to_br</a>, <a href="../filters/strip_html.html">strip_html</a>。</p>
|
||||
<p>当输出的变量不被信任时,可以把 <a href="./options.html#outputEscape">outputEscape</a> 参数设置为 <code>"escape"</code> 来启用默认 HTML 转义。这种情况下,如果你需要某个输出不被转义,则需要使用 <a href="../filters/raw.html">raw</a> 过滤器:</p>
|
||||
<p>输入</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">{{ "1 < 2" }}</span><br><span class="line">{{ "<button>OK</button>" | raw }}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{{</span> <span class="token string">"1 < 2"</span> <span class="token delimiter punctuation">}}</span></span>
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{{</span> <span class="token string">"<button>OK</button>"</span> <span class="token operator">|</span> <span class="token keyword">raw</span> <span class="token delimiter punctuation">}}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>输出</p>
|
||||
<figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">1 &lt; 2</span><br><span class="line"><button>OK</button></span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-text" data-language="text"><code class="language-text">1 &lt; 2
|
||||
<button>OK</button><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
|
||||
|
||||
<h2 id="Liquid-转义" class="article-heading"><a href="#Liquid-转义" class="headerlink" title="Liquid 转义"></a>Liquid 转义<a class="article-anchor" href="#Liquid-转义" aria-hidden="true"></a></h2><p>为了输出 Liquid 的特殊字符比如 <code>{{</code> 和 <code>{%</code>,你需要 <a href="../filters/raw.html">raw</a> 标签。</p>
|
||||
<p>输入</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">{% raw %}</span><br><span class="line"> In LiquidJS, {{ this | escape }} will be HTML-escaped, but</span><br><span class="line"> {{{ that }}} will not.</span><br><span class="line">{% endraw %}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">raw</span> <span class="token delimiter punctuation">%}</span></span>
|
||||
In LiquidJS, {{ this | escape }} will be HTML-escaped, but
|
||||
{{{ that }}} will not.
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">endraw</span> <span class="token delimiter punctuation">%}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>输出</p>
|
||||
<figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">In LiquidJS, {{ this | escape }} will be HTML-escaped, but</span><br><span class="line">{{{ that }}} will not.</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-text" data-language="text"><code class="language-text">In LiquidJS, {{ this | escape }} will be HTML-escaped, but
|
||||
{{{ that }}} will not.<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>Within strings literals in LiquidJS template, <code>\</code> can be used to escape special characters in string syntax. For example:</p>
|
||||
<p>输入</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">{{ "\"" }}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{{</span> <span class="token string">"\"</span>" <span class="token delimiter punctuation">}}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
<p>输出</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">"</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid">"<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="caching.html" class="article-footer-prev" title="缓存"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="register-filters-tags.html" class="article-footer-next" title="注册标签/过滤器"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -102,26 +102,30 @@
|
||||
</blockquote>
|
||||
|
||||
<h2 id="输出" class="article-heading"><a href="#输出" class="headerlink" title="输出"></a>输出<a class="article-anchor" href="#输出" aria-hidden="true"></a></h2><p><strong>输出</strong> 用于转换和输出变量到 HTML。下面的模板将会把 <code>username</code> 的值插入到 input 的 <code>value</code>:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><input type="text" name="user" value="{{username}}"></span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>text<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>user<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token liquid language-liquid"><span class="token delimiter punctuation">{{</span>username<span class="token delimiter punctuation">}}</span></span><span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
<p><em>输出</em> 里的值可以在输出之前经过若干个 <strong>过滤器</strong> 的转换。比如在变量后面追加一个字符串:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">{{ username | append: ", welcome to LiquidJS!" }}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{{</span> username <span class="token operator">|</span> <span class="token function filter">append</span><span class="token operator">:</span> <span class="token string">", welcome to LiquidJS!"</span> <span class="token delimiter punctuation">}}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
<p>过滤器可以级联,用起来像管道一样:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">{{ username | append: ", welcome to LiquidJS!" | capitalize }}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{{</span> username <span class="token operator">|</span> <span class="token function filter">append</span><span class="token operator">:</span> <span class="token string">", welcome to LiquidJS!"</span> <span class="token operator">|</span> <span class="token function filter">capitalize</span> <span class="token delimiter punctuation">}}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
<p><a href="../filters/overview.html">这里</a> 是 LiquidJS 支持的完整的过滤器列表。</p>
|
||||
<h2 id="标签" class="article-heading"><a href="#标签" class="headerlink" title="标签"></a>标签<a class="article-anchor" href="#标签" aria-hidden="true"></a></h2><p><strong>标签</strong> 用于控制模板渲染过程,操作模板变量,和其他模板交互等。例如 <code>assign</code> 可以用来定义一个模板中可以使用的变量:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">{% assign foo = "FOO" %}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">assign</span> foo <span class="token operator">=</span> <span class="token string">"FOO"</span> <span class="token delimiter punctuation">%}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
<p>一般标签成对地出现,一个开始标签和一个对应的结束标签,比如:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">{% if foo == "FOO" %}</span><br><span class="line"> Variable `foo` equals "FOO"</span><br><span class="line">{% else %}</span><br><span class="line"> Variable `foo` not equals "FOO"</span><br><span class="line">{% endif %}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">if</span> foo <span class="token operator">==</span> <span class="token string">"FOO"</span> <span class="token delimiter punctuation">%}</span></span>
|
||||
Variable `foo` equals "FOO"
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">else</span> <span class="token delimiter punctuation">%}</span></span>
|
||||
Variable `foo` not equals "FOO"
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">endif</span> <span class="token delimiter punctuation">%}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p><a href="../tags/overview.html">这里</a> 是 LiquidJS 支持的完整的标签列表。</p>
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="setup.html" class="article-footer-next" title="安装"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="dos.html" class="article-footer-prev" title="DoS"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="changelog.html" class="article-footer-next" title="更新日志"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="plugins.html" class="article-footer-prev" title="插件"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="truthy-and-falsy.html" class="article-footer-next" title="真和假"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -93,7 +93,10 @@
|
||||
</header>
|
||||
<div class="article-content" itemprop="articleBody">
|
||||
<p><a href="/api/classes/Liquid.html">Liquid</a> 构造函数接受一个参数对象,用来定义各种模板引擎行为。这些参数都是可选的,比如我可以指定其中一个参数 <code>cache</code>:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> { <span class="title class_">Liquid</span> } = <span class="built_in">require</span>(<span class="string">'liquidjs'</span>)</span><br><span class="line"><span class="keyword">const</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>({</span><br><span class="line"> <span class="attr">cache</span>: <span class="literal">true</span></span><br><span class="line">})</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token punctuation">{</span> Liquid <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'liquidjs'</span><span class="token punctuation">)</span>
|
||||
<span class="token keyword">const</span> engine <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Liquid</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
|
||||
<span class="token literal-property property">cache</span><span class="token operator">:</span> <span class="token boolean">true</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<blockquote class="note info"><strong class="note-title">API 文档</strong><p>下面的所有选项的概述,希望了解具体的类型和签名,请前往 <a href="https://liquidjs.com/api/interfaces/LiquidOptions.html" target="_self">LiquidOptions | API</a>.</p>
|
||||
</blockquote>
|
||||
@@ -108,10 +111,10 @@
|
||||
<p>注意由于历史原因这个选项叫做 dynamicPartials,但它对 layout 也起作用。</p>
|
||||
</blockquote>
|
||||
<p><strong>dynamicPartials</strong> 表示是否把传给 <a href="../tags/include.html">include</a>, <a href="../tags/render.html">render</a>, <a href="../tags/layout.html">layout</a> 标签的文件名当做变量处理。默认为 <code>true</code>。例如用上下文 <code>{ file: 'foo.html' }</code> 渲染下面的模板将会引入文件 <code>foo.html</code>:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">{% include file %}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">include</span> file <span class="token delimiter punctuation">%}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
<p>设置 <code>dynamicPartials: false</code> 后 LiquidJS 将会尝试去读取 <code>file</code>。当你的模板之间都是静态引入关系时会很有用:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">{% liquid foo.html %}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">liquid</span> foo<span class="token punctuation">.</span>html <span class="token delimiter punctuation">%}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
<blockquote class="note warn"><strong class="note-title">常见陷阱</strong><p>LiquidJS 把这个选项默认值设为 <code>true</code> 以兼容于 shopify/liquid,但如果你在使用 <a href="https://github.com/11ty/eleventy" rel="external nofollow noreferrer" target="_blank">eleventy</a> 它会设置默认值 <code>false</code> (参考 <a href="https://www.11ty.dev/docs/languages/liquid/#quoted-include-paths" rel="external nofollow noreferrer" target="_blank">Quoted Include Paths</a>)以兼容于 Jekyll。</p>
|
||||
</blockquote>
|
||||
@@ -125,10 +128,18 @@
|
||||
<li>参数放到了 <code>include</code> 变量下,而非当前作用域。</li>
|
||||
</ul>
|
||||
<p>例如下面的模板中,<code>name.html</code> 没有带引号,<code>header</code> 和 <code>"HEADER"</code> 以 <code>=</code> 分隔,<code>header</code> 参数通过 <code>include.header</code> 来引用。更多详情请参考 <a href="../tags/include.html">include</a>。</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">// entry template</span><br><span class="line">{% include article.html header="HEADER" content="CONTENT" %}</span><br><span class="line"></span><br><span class="line">// article.html</span><br><span class="line"><article></span><br><span class="line"> <header>{{include.header}}</header></span><br><span class="line"> {{include.content}}</span><br><span class="line"></article></span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid">// entry template
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">include</span> <span class="token object">article</span><span class="token punctuation">.</span>html header<span class="token operator">=</span><span class="token string">"HEADER"</span> content<span class="token operator">=</span><span class="token string">"CONTENT"</span> <span class="token delimiter punctuation">%}</span></span>
|
||||
|
||||
// article.html
|
||||
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>article</span><span class="token punctuation">></span></span>
|
||||
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>header</span><span class="token punctuation">></span></span><span class="token liquid language-liquid"><span class="token delimiter punctuation">{{</span><span class="token keyword">include</span><span class="token punctuation">.</span>header<span class="token delimiter punctuation">}}</span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>header</span><span class="token punctuation">></span></span>
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{{</span><span class="token keyword">include</span><span class="token punctuation">.</span>content<span class="token delimiter punctuation">}}</span></span>
|
||||
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>article</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<h2 id="extname" class="article-heading"><a href="#extname" class="headerlink" title="extname"></a>extname<a class="article-anchor" href="#extname" aria-hidden="true"></a></h2><p><strong>extname</strong> 定义了默认的文件后缀,当传入文件名不包含后缀时自动追加。默认值是 <code>''</code> 也就是说默认是禁用的。如果设置为 <code>.liquid</code>:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">{% render "foo" %} 没有后缀,添加 ".liquid" 并加载 foo.liquid</span><br><span class="line">{% render "foo.html" %} 已经有后缀了,直接加载 foo.html</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">render</span> <span class="token string">"foo"</span> <span class="token delimiter punctuation">%}</span></span> 没有后缀,添加 ".liquid" 并加载 foo.liquid
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">render</span> <span class="token string">"foo.html"</span> <span class="token delimiter punctuation">%}</span></span> 已经有后缀了,直接加载 foo.html<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
|
||||
|
||||
<blockquote class="note info"><strong class="note-title">旧版行为</strong><p>在 2.0.1 之前,<code>extname</code> 默认值为 <code>.liquid</code>。要禁用它需要明确设置为 <code>extname: ''</code>。详情参考 <a href="https://github.com/harttle/liquidjs/issues/41" rel="external nofollow noreferrer" target="_blank">#41</a>。</p>
|
||||
</blockquote>
|
||||
@@ -148,7 +159,7 @@
|
||||
<p><strong>dateFormat</strong> 用于指定输出日期的默认格式. <code>%A, %B %-e, %Y at %-l:%M %P %z</code> 如果未指定,将使用. 例如,设置 <code>dateFormat: %Y-%m-%dT%H:%M:%S:%LZ</code> 以输出 [JavaSrcipt Date.toJson()][<a target="_blank" rel="noopener external nofollow noreferrer" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON]">https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON]</a> 格式.</p>
|
||||
<h2 id="换行和缩进" class="article-heading"><a href="#换行和缩进" class="headerlink" title="换行和缩进"></a>换行和缩进<a class="article-anchor" href="#换行和缩进" aria-hidden="true"></a></h2><p><strong>greedy</strong>, <strong>trimOutputLeft</strong>, <strong>trimOutputRight</strong>, <strong>trimTagLeft</strong>, <strong>trimTagRight</strong> 选项用来移除 Liquid 语法周围的换行和缩进,详情请参考 <a href="./whitespace-control.html">Whitespace Control</a>。</p>
|
||||
<h2 id="自定义分隔符" class="article-heading"><a href="#自定义分隔符" class="headerlink" title="自定义分隔符"></a>自定义分隔符<a class="article-anchor" href="#自定义分隔符" aria-hidden="true"></a></h2><p><strong>outputDelimiterLeft</strong>, <strong>outputDelimiterRight</strong>, <strong>tagDelimiterLeft</strong>, <strong>tagDelimiterRight</strong> 用来自定义 LiquidJS 中 <a href="./intro-to-liquid.html">标签和过滤器</a> 的分隔符。例如设置了 <code>outputDelimiterLeft: <%=, outputDelimiterRight: %></code> 后我们可以避免跟其他模板引擎冲突:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><%= username | append: ", welcome to LiquidJS!" %></span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-ejs" data-language="ejs"><code class="language-ejs"><span class="token ejs language-ejs"><span class="token delimiter punctuation"><%=</span><span class="token language-javascript"> username <span class="token operator">|</span> append<span class="token operator">:</span> <span class="token string">", welcome to LiquidJS!"</span> </span><span class="token delimiter punctuation">%></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
<h2 id="严格模式" class="article-heading"><a href="#严格模式" class="headerlink" title="严格模式"></a>严格模式<a class="article-anchor" href="#严格模式" aria-hidden="true"></a></h2><p><strong>strictFilters</strong> 用来启用过滤器的严格模式,如果设置为 <code>true</code> 过滤器不存在时解析会抛出异常。默认为 <code>false</code>,这时会跳过不存在的过滤器。</p>
|
||||
<p><strong>strictVariables</strong> 用来启用变量严格模式。如果设置为 <code>true</code> 变量不存在时渲染会抛出异常,默认为 <code>false</code> 这时不存在的变量会被渲染为空字符串。</p>
|
||||
@@ -160,7 +171,7 @@
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="setup.html" class="article-footer-prev" title="安装"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="render-file.html" class="article-footer-next" title="文件渲染"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -93,31 +93,76 @@
|
||||
</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>在 <a href="/tutorials/register-filters-tags.html">注册过滤器和标签</a> 中提到,可以通过 <code>tagToken.args</code> 来得到标签的原始参数字符串。例如:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Usage: {% random foo bar coo %}</span></span><br><span class="line"><span class="comment">// Output: "foo", "bar" or "coo"</span></span><br><span class="line">engine.<span class="title function_">registerTag</span>(<span class="string">'random'</span>, {</span><br><span class="line"> <span class="title function_">parse</span>(<span class="params">tagToken</span>) {</span><br><span class="line"> <span class="comment">// tagToken.args === "foo bar coo"</span></span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">items</span> = tagToken.<span class="property">args</span>.<span class="title function_">split</span>(<span class="string">' '</span>)</span><br><span class="line"> },</span><br><span class="line"> <span class="title function_">render</span>(<span class="params">context, emitter</span>) {</span><br><span class="line"> <span class="comment">// get a random index</span></span><br><span class="line"> <span class="keyword">const</span> index = <span class="title class_">Math</span>.<span class="title function_">floor</span>(<span class="variable language_">this</span>.<span class="property">items</span>.<span class="property">length</span> * <span class="title class_">Math</span>.<span class="title function_">random</span>())</span><br><span class="line"> <span class="comment">// output that item</span></span><br><span class="line"> emitter.<span class="title function_">write</span>(<span class="variable language_">this</span>.<span class="property">items</span>[index])</span><br><span class="line"> }</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// Usage: {% random foo bar coo %}</span>
|
||||
<span class="token comment">// Output: "foo", "bar" or "coo"</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">registerTag</span><span class="token punctuation">(</span><span class="token string">'random'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
|
||||
<span class="token function">parse</span><span class="token punctuation">(</span><span class="token parameter">tagToken</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token comment">// tagToken.args === "foo bar coo"</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>items <span class="token operator">=</span> tagToken<span class="token punctuation">.</span>args<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">' '</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||||
<span class="token function">render</span><span class="token punctuation">(</span><span class="token parameter">context<span class="token punctuation">,</span> emitter</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token comment">// get a random index</span>
|
||||
<span class="token keyword">const</span> index <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>items<span class="token punctuation">.</span>length <span class="token operator">*</span> Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
|
||||
<span class="token comment">// output that item</span>
|
||||
emitter<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>items<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>见这个 JSFiddle:<a target="_blank" rel="noopener external nofollow noreferrer" href="http://jsfiddle.net/ctj364up/2/">http://jsfiddle.net/ctj364up/2/</a>。</p>
|
||||
<h2 id="解析参数的值" class="article-heading"><a href="#解析参数的值" class="headerlink" title="解析参数的值"></a>解析参数的值<a class="article-anchor" href="#解析参数的值" aria-hidden="true"></a></h2><p>除了静态的参数字符串之外,我们更希望把动态的值传递给标签。LiquidJS 中的值可以是字面量(字符串、数字等,也可以是当前上下文的变量。</p>
|
||||
<p>下面是修改过的模板,也包含三个值用来随机。但它们表示的是值而不是静态的字符串。第一个是字符串字面量,第二个是标识符(表示变量),第三个是属性访问表达式,包含两个标识符。</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">{% random "foo" bar obj.coo %}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> random <span class="token string">"foo"</span> bar obj<span class="token punctuation">.</span>coo <span class="token delimiter punctuation">%}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
<p>解析这么多种情况会很麻烦,但 LiquidJS 提供了 <a href="/api/classes/Tokenizer.html">Tokenizer</a> 类来处理这种情况。</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> { <span class="title class_">Liquid</span>, <span class="title class_">Tokenizer</span>, evalToken } = <span class="built_in">require</span>(<span class="string">'liquidjs'</span>)</span><br><span class="line"></span><br><span class="line">engine.<span class="title function_">registerTag</span>(<span class="string">'random'</span>, {</span><br><span class="line"> <span class="title function_">parse</span>(<span class="params">tagToken</span>) {</span><br><span class="line"> <span class="keyword">const</span> tokenizer = <span class="keyword">new</span> <span class="title class_">Tokenizer</span>(tagToken.<span class="property">args</span>)</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">items</span> = []</span><br><span class="line"> <span class="keyword">while</span> (!tokenizer.<span class="title function_">end</span>()) {</span><br><span class="line"> <span class="comment">// here readValue() returns a LiteralToken or PropertyAccessToken</span></span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">items</span>.<span class="title function_">push</span>(tokenizer.<span class="title function_">readValue</span>())</span><br><span class="line"> }</span><br><span class="line"> },</span><br><span class="line"> * <span class="title function_">render</span>(<span class="params">context, emitter</span>) {</span><br><span class="line"> <span class="keyword">const</span> index = <span class="title class_">Math</span>.<span class="title function_">floor</span>(<span class="variable language_">this</span>.<span class="property">items</span>.<span class="property">length</span> * <span class="title class_">Math</span>.<span class="title function_">random</span>())</span><br><span class="line"> <span class="keyword">const</span> token = <span class="variable language_">this</span>.<span class="property">items</span>[index]</span><br><span class="line"> <span class="comment">// in LiquidJS, we use yield to wait for async call</span></span><br><span class="line"> <span class="keyword">const</span> value = <span class="keyword">yield</span> <span class="title function_">evalToken</span>(token, context)</span><br><span class="line"> emitter.<span class="title function_">write</span>(value)</span><br><span class="line"> }</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token punctuation">{</span> Liquid<span class="token punctuation">,</span> Tokenizer<span class="token punctuation">,</span> evalToken <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'liquidjs'</span><span class="token punctuation">)</span>
|
||||
|
||||
engine<span class="token punctuation">.</span><span class="token function">registerTag</span><span class="token punctuation">(</span><span class="token string">'random'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
|
||||
<span class="token function">parse</span><span class="token punctuation">(</span><span class="token parameter">tagToken</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">const</span> tokenizer <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Tokenizer</span><span class="token punctuation">(</span>tagToken<span class="token punctuation">.</span>args<span class="token punctuation">)</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>items <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
|
||||
<span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token operator">!</span>tokenizer<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token comment">// here readValue() returns a LiteralToken or PropertyAccessToken</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>items<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>tokenizer<span class="token punctuation">.</span><span class="token function">readValue</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||||
<span class="token operator">*</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token parameter">context<span class="token punctuation">,</span> emitter</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">const</span> index <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>items<span class="token punctuation">.</span>length <span class="token operator">*</span> Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
|
||||
<span class="token keyword">const</span> token <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>items<span class="token punctuation">[</span>index<span class="token punctuation">]</span>
|
||||
<span class="token comment">// in LiquidJS, we use yield to wait for async call</span>
|
||||
<span class="token keyword">const</span> value <span class="token operator">=</span> <span class="token keyword">yield</span> <span class="token function">evalToken</span><span class="token punctuation">(</span>token<span class="token punctuation">,</span> context<span class="token punctuation">)</span>
|
||||
emitter<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>用上下文 <code>{ bar: "bar", obj: { coo: "coo" } }</code> 来调用这个标签可以得到上第一个例子一样的效果。见这个 JSFiddle:<a target="_blank" rel="noopener external nofollow noreferrer" href="http://jsfiddle.net/ctj364up/3/">http://jsfiddle.net/ctj364up/3/</a>.</p>
|
||||
<blockquote class="note info"><strong class="note-title">异步和 Promise</strong><p>在 LiquidJS 里异步用生成器实现,这样同样一份标签的实现也可以用于同步的 API 比如 <code>renderSync()</code>,<code>parseAndRenderSync()</code>,<code>renderFileSync()</code>。如果要在标签实现里等待 Promise,只需要把 <code>await somePromise</code> 换成 <code>yield somePromise</code>,并保留 <code>* render()</code> 不要改成 <code>async render()</code>。更多细节请参考 <a href="/tutorials/sync-and-async.html">Sync and Async</a>。</p>
|
||||
</blockquote>
|
||||
|
||||
<h2 id="把键值对解析为命名参数" class="article-heading"><a href="#把键值对解析为命名参数" class="headerlink" title="把键值对解析为命名参数"></a>把键值对解析为命名参数<a class="article-anchor" href="#把键值对解析为命名参数" aria-hidden="true"></a></h2><p>当参数很多时或者有可选参数时,使用命名参数语法会很方便。这时参数由无序的键值对构成,LiquidJS 中的 <a href="/api/classes/Hash.html">Hash</a> 类就是来处理这种情况的。</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">{% random from:2, to:max %}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> random from<span class="token operator">:</span><span class="token number">2</span><span class="token punctuation">,</span> to<span class="token operator">:</span>max <span class="token delimiter punctuation">%}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
<p>上面的例子用来产生 [2, max] 范围内的随机数。我们要用 <code>Hash</code> 来解析 <code>from</code> 和 <code>to</code> 参数。</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> { <span class="title class_">Liquid</span>, <span class="title class_">Hash</span> } = <span class="built_in">require</span>(<span class="string">'liquidjs'</span>)</span><br><span class="line"></span><br><span class="line">engine.<span class="title function_">registerTag</span>(<span class="string">'random'</span>, {</span><br><span class="line"> <span class="title function_">parse</span>(<span class="params">tagToken</span>) {</span><br><span class="line"> <span class="comment">// 解析参数结果,存到 `this.args` 里</span></span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">args</span> = <span class="keyword">new</span> <span class="title class_">Hash</span>(tagToken.<span class="property">args</span>)</span><br><span class="line"> },</span><br><span class="line"> * <span class="title function_">render</span>(<span class="params">context, emitter</span>) {</span><br><span class="line"> <span class="comment">// 在当前 `context` 下计算参数的值</span></span><br><span class="line"> <span class="keyword">const</span> {<span class="keyword">from</span>, to} = <span class="keyword">yield</span> <span class="variable language_">this</span>.<span class="property">args</span>.<span class="title function_">render</span>(context)</span><br><span class="line"> <span class="keyword">const</span> length = to - <span class="keyword">from</span> + <span class="number">1</span></span><br><span class="line"> <span class="keyword">const</span> value = <span class="keyword">from</span> + <span class="title class_">Math</span>.<span class="title function_">floor</span>(length * <span class="title class_">Math</span>.<span class="title function_">random</span>())</span><br><span class="line"> emitter.<span class="title function_">write</span>(value)</span><br><span class="line"> }</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token punctuation">{</span> Liquid<span class="token punctuation">,</span> Hash <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'liquidjs'</span><span class="token punctuation">)</span>
|
||||
|
||||
engine<span class="token punctuation">.</span><span class="token function">registerTag</span><span class="token punctuation">(</span><span class="token string">'random'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
|
||||
<span class="token function">parse</span><span class="token punctuation">(</span><span class="token parameter">tagToken</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token comment">// 解析参数结果,存到 `this.args` 里</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>args <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Hash</span><span class="token punctuation">(</span>tagToken<span class="token punctuation">.</span>args<span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||||
<span class="token operator">*</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token parameter">context<span class="token punctuation">,</span> emitter</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token comment">// 在当前 `context` 下计算参数的值</span>
|
||||
<span class="token keyword">const</span> <span class="token punctuation">{</span>from<span class="token punctuation">,</span> to<span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">yield</span> <span class="token keyword">this</span><span class="token punctuation">.</span>args<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span>
|
||||
<span class="token keyword">const</span> length <span class="token operator">=</span> to <span class="token operator">-</span> from <span class="token operator">+</span> <span class="token number">1</span>
|
||||
<span class="token keyword">const</span> value <span class="token operator">=</span> from <span class="token operator">+</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span>length <span class="token operator">*</span> Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
|
||||
emitter<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>在 <code>{ max: 10 }</code> 上下文上渲染 <code>{% random from:2, to:max %}</code> 将会得到 [2, 10] 范围内的随机数。见这个 JSFiddle:<a target="_blank" rel="noopener external nofollow noreferrer" href="http://jsfiddle.net/ctj364up/4/">http://jsfiddle.net/ctj364up/4/</a>。</p>
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="access-scope-in-filters.html" class="article-footer-prev" title="过滤器里访问上下文"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="render-tag-content.html" class="article-footer-next" title="渲染标签内容"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -93,19 +93,37 @@
|
||||
</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>对于如下两个模板文件:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">// 文件:color.liquid</span><br><span class="line">color: '{{ color }}' shape: '{{ shape }}'</span><br><span class="line"></span><br><span class="line">// 文件:theme.liquid</span><br><span class="line">{% assign shape = 'circle' %}</span><br><span class="line">{% include 'color' %}</span><br><span class="line">{% include 'color' with 'red' %}</span><br><span class="line">{% include 'color', color: 'yellow', shape: 'square' %}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-none"><code class="language-none">// 文件:color.liquid
|
||||
color: '{{ color }}' shape: '{{ shape }}'
|
||||
|
||||
// 文件:theme.liquid
|
||||
{% assign shape = 'circle' %}
|
||||
{% include 'color' %}
|
||||
{% include 'color' with 'red' %}
|
||||
{% include 'color', color: 'yellow', shape: 'square' %}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>输出为:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">color: '' shape: 'circle'</span><br><span class="line">color: 'red' shape: 'circle'</span><br><span class="line">color: 'yellow' shape: 'square'</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-none"><code class="language-none">color: '' shape: 'circle'
|
||||
color: 'red' shape: 'circle'
|
||||
color: 'yellow' shape: 'square'<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<blockquote class="note tip"><strong class="note-title">".liquid" 文件扩展名</strong><p>如果设置了 <code>extname: ".liquid"</code> 选项,就可以省略 <code>layout</code>, <code>render</code> 和 <code>include</code> 里面文件名的 “.liquid” 后缀。详情请参考 <a href="./options.html#extname">extname 选项</a>。</p>
|
||||
</blockquote>
|
||||
|
||||
<h2 id="布局模板(模板继承)" class="article-heading"><a href="#布局模板(模板继承)" class="headerlink" title="布局模板(模板继承)"></a>布局模板(模板继承)<a class="article-anchor" href="#布局模板(模板继承)" aria-hidden="true"></a></h2><p>对于如下两个模板文件:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">// 文件:default-layout.liquid</span><br><span class="line">Header</span><br><span class="line">{% block content %}My default content{% endblock %}</span><br><span class="line">Footer</span><br><span class="line"></span><br><span class="line">// 文件:page.liquid</span><br><span class="line">{% layout "default-layout" %}</span><br><span class="line">{% block content %}My page content{% endblock %}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-none"><code class="language-none">// 文件:default-layout.liquid
|
||||
Header
|
||||
{% block content %}My default content{% endblock %}
|
||||
Footer
|
||||
|
||||
// 文件:page.liquid
|
||||
{% layout "default-layout" %}
|
||||
{% block content %}My page content{% endblock %}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>渲染 <code>page.liquid</code> 将会输出:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Header</span><br><span class="line">My page content</span><br><span class="line">Footer</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-none"><code class="language-none">Header
|
||||
My page content
|
||||
Footer<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<blockquote class="note tip"><strong class="note-title">Block</strong><ul>
|
||||
<li>布局文件(父模板)中可以定义多个 block;</li>
|
||||
@@ -114,7 +132,7 @@
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="render-file.html" class="article-footer-prev" title="文件渲染"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="use-in-expressjs.html" class="article-footer-next" title="Express.js 中使用"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -95,11 +95,21 @@
|
||||
<p>一组标签和过滤器可以封装为一个 <strong>插件</strong>,通常发包到 NPM 来方便使用。本文介绍如何创建和使用插件。</p>
|
||||
<h2 id="编写插件" class="article-heading"><a href="#编写插件" class="headerlink" title="编写插件"></a>编写插件<a class="article-anchor" href="#编写插件" aria-hidden="true"></a></h2><p>LiquidJS 插件就是一个简单的函数,它的第一个参数是 <a href="/api/classes/Liquid.html">Liquid 类</a>,其中的 <code>this</code> 是它被注册到的 Liquid 实例。可以通过 <code>this</code> 来调用 Liquid API,比如 <a href="./register-filters-tags.html">注册标签和过滤器</a>。</p>
|
||||
<p>现在我们来写一个插件并在其中注册一个过滤器,来把输入字符串转换为大写:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Inside the plugin function, `this` refers to the Liquid instance.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> Liquid: provides facilities to implement tags and filters.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = <span class="keyword">function</span> (<span class="params">Liquid</span>) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="title function_">registerFilter</span>(<span class="string">'upup'</span>, <span class="function"><span class="params">x</span> =></span> x.<span class="title function_">toUpperCase</span>());</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">/**
|
||||
* Inside the plugin function, `this` refers to the Liquid instance.
|
||||
*
|
||||
* @param Liquid: provides facilities to implement tags and filters.
|
||||
*/</span>
|
||||
module<span class="token punctuation">.</span><span class="token function-variable function">exports</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">Liquid</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">registerFilter</span><span class="token punctuation">(</span><span class="token string">'upup'</span><span class="token punctuation">,</span> <span class="token parameter">x</span> <span class="token operator">=></span> x<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
<span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>把上述代码保存为 <code>upup.js</code>。</p>
|
||||
<h2 id="使用插件" class="article-heading"><a href="#使用插件" class="headerlink" title="使用插件"></a>使用插件<a class="article-anchor" href="#使用插件" aria-hidden="true"></a></h2><p>把插件传递给 <code>.plugin()</code> 方法即可注册插件,例如:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>()</span><br><span class="line"></span><br><span class="line">engine.<span class="title function_">plugin</span>(<span class="built_in">require</span>(<span class="string">'./upup.js'</span>));</span><br><span class="line">engine.<span class="title function_">parseAndRender</span>(<span class="string">'{{ "foo" | upup }}'</span>).<span class="title function_">then</span>(<span class="variable language_">console</span>.<span class="property">log</span>)</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> engine <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Liquid</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||||
|
||||
engine<span class="token punctuation">.</span><span class="token function">plugin</span><span class="token punctuation">(</span><span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./upup.js'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">parseAndRender</span><span class="token punctuation">(</span><span class="token string">'{{ "foo" | upup }}'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>上述代码将会输出 <code>"FOO"</code>。</p>
|
||||
<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> 核心仓库的标签和插件(参考 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs#differences-and-limitations">https://github.com/harttle/liquidjs#differences-and-limitations</a>),Shopify 平台上特有的插件只能通过插件来使用。</p>
|
||||
@@ -111,7 +121,7 @@
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="whitespace-control.html" class="article-footer-prev" title="换行和缩进"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="operators.html" class="article-footer-next" title="运算符"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -92,30 +92,81 @@
|
||||
|
||||
</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><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 使用方式: {% upper name %}</span></span><br><span class="line">engine.<span class="title function_">registerTag</span>(<span class="string">'upper'</span>, {</span><br><span class="line"> <span class="attr">parse</span>: <span class="keyword">function</span>(<span class="params">tagToken, remainTokens</span>) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">value</span> = <span class="keyword">new</span> <span class="title class_">Value</span>(token.<span class="property">args</span>, liquid)</span><br><span class="line"> },</span><br><span class="line"> <span class="attr">render</span>: <span class="keyword">function</span>*(scope, hash) {</span><br><span class="line"> <span class="keyword">const</span> str = <span class="keyword">yield</span> <span class="variable language_">this</span>.<span class="property">value</span>.<span class="title function_">value</span>(ctx); <span class="comment">// 'alice'</span></span><br><span class="line"> <span class="keyword">return</span> str.<span class="title function_">toUpperCase</span>() <span class="comment">// 'Alice'</span></span><br><span class="line"> }</span><br><span class="line">});</span><br></pre></td></tr></table></figure>
|
||||
<h2 id="注册标签" class="article-heading"><a href="#注册标签" class="headerlink" title="注册标签"></a>注册标签<a class="article-anchor" href="#注册标签" aria-hidden="true"></a></h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 使用方式: {% upper name %}</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">registerTag</span><span class="token punctuation">(</span><span class="token string">'upper'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
|
||||
<span class="token function-variable function">parse</span><span class="token operator">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">tagToken<span class="token punctuation">,</span> remainTokens</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>value <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Value</span><span class="token punctuation">(</span>token<span class="token punctuation">.</span>args<span class="token punctuation">,</span> liquid<span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||||
<span class="token function-variable function">render</span><span class="token operator">:</span> <span class="token keyword">function</span><span class="token operator">*</span><span class="token punctuation">(</span>scope<span class="token punctuation">,</span> hash<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">const</span> str <span class="token operator">=</span> <span class="token keyword">yield</span> <span class="token keyword">this</span><span class="token punctuation">.</span>value<span class="token punctuation">.</span><span class="token function">value</span><span class="token punctuation">(</span>ctx<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 'alice'</span>
|
||||
<span class="token keyword">return</span> str<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// 'Alice'</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<ul>
|
||||
<li><code>parse</code>: 从 <code>remainTokens</code> 中读取后续的标签/输出/HTML,直到找到你期望的结束标签。</li>
|
||||
<li><code>render</code>: 把 scope 数据和此前解析得到的 Token 结合,输出 HTML 字符串。</li>
|
||||
</ul>
|
||||
<p>对于更复杂的标签实现,可以提供一个继承自 <code>Tag</code> 的类:</p>
|
||||
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Usage: {% upper name:"alice" %}</span></span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">Hash</span>, <span class="title class_">Tag</span>, <span class="title class_">TagToken</span>, <span class="title class_">Context</span>, <span class="title class_">Emitter</span>, <span class="title class_">TopLevelToken</span>, <span class="title class_">Liquid</span> } <span class="keyword">from</span> <span class="string">'liquidjs'</span></span><br><span class="line"></span><br><span class="line">engine.<span class="title function_">registerTag</span>(<span class="string">'upper'</span>, <span class="keyword">class</span> <span class="title class_">UpperTag</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Tag</span> {</span><br><span class="line"> <span class="keyword">private</span> <span class="attr">hash</span>: <span class="title class_">Hash</span></span><br><span class="line"> <span class="title function_">constructor</span>(<span class="params"><span class="attr">tagToken</span>: <span class="title class_">TagToken</span>, <span class="attr">remainTokens</span>: <span class="title class_">TopLevelToken</span>[], <span class="attr">liquid</span>: <span class="title class_">Liquid</span></span>) {</span><br><span class="line"> <span class="variable language_">super</span>(tagToken, remainTokens, liquid)</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">hash</span> = <span class="keyword">new</span> <span class="title class_">Hash</span>(tagToken.<span class="property">args</span>)</span><br><span class="line"> }</span><br><span class="line"> * <span class="title function_">render</span>(<span class="params"><span class="attr">ctx</span>: <span class="title class_">Context</span></span>) {</span><br><span class="line"> <span class="keyword">const</span> hash = <span class="keyword">yield</span> <span class="variable language_">this</span>.<span class="property">hash</span>.<span class="title function_">render</span>();</span><br><span class="line"> <span class="keyword">return</span> hash.<span class="property">name</span>.<span class="title function_">toUpperCase</span>() <span class="comment">// 'ALICE'</span></span><br><span class="line"> }</span><br><span class="line">});</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token comment">// Usage: {% upper name:"alice" %}</span>
|
||||
<span class="token keyword">import</span> <span class="token punctuation">{</span> Hash<span class="token punctuation">,</span> Tag<span class="token punctuation">,</span> TagToken<span class="token punctuation">,</span> Context<span class="token punctuation">,</span> Emitter<span class="token punctuation">,</span> TopLevelToken<span class="token punctuation">,</span> Liquid <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'liquidjs'</span>
|
||||
|
||||
engine<span class="token punctuation">.</span><span class="token function">registerTag</span><span class="token punctuation">(</span><span class="token string">'upper'</span><span class="token punctuation">,</span> <span class="token keyword">class</span> <span class="token class-name">UpperTag</span> <span class="token keyword">extends</span> <span class="token class-name">Tag</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">private</span> hash<span class="token operator">:</span> Hash
|
||||
<span class="token function">constructor</span><span class="token punctuation">(</span>tagToken<span class="token operator">:</span> TagToken<span class="token punctuation">,</span> remainTokens<span class="token operator">:</span> TopLevelToken<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> liquid<span class="token operator">:</span> Liquid<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">super</span><span class="token punctuation">(</span>tagToken<span class="token punctuation">,</span> remainTokens<span class="token punctuation">,</span> liquid<span class="token punctuation">)</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>hash <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Hash</span><span class="token punctuation">(</span>tagToken<span class="token punctuation">.</span>args<span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token operator">*</span> <span class="token function">render</span><span class="token punctuation">(</span>ctx<span class="token operator">:</span> Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">const</span> hash <span class="token operator">=</span> <span class="token keyword">yield</span> <span class="token keyword">this</span><span class="token punctuation">.</span>hash<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
<span class="token keyword">return</span> hash<span class="token punctuation">.</span>name<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// 'ALICE'</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>可以参考已有的标签实现:<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/tree/master/src/tags">https://github.com/harttle/liquidjs/tree/master/src/tags</a></p>
|
||||
<h2 id="注册过滤器" class="article-heading"><a href="#注册过滤器" class="headerlink" title="注册过滤器"></a>注册过滤器<a class="article-anchor" href="#注册过滤器" aria-hidden="true"></a></h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 使用方式: {{ name | upper }}</span></span><br><span class="line">engine.<span class="title function_">registerFilter</span>(<span class="string">'upper'</span>, <span class="function"><span class="params">v</span> =></span> v.<span class="title function_">toUpperCase</span>())</span><br></pre></td></tr></table></figure>
|
||||
<h2 id="注册过滤器" class="article-heading"><a href="#注册过滤器" class="headerlink" title="注册过滤器"></a>注册过滤器<a class="article-anchor" href="#注册过滤器" aria-hidden="true"></a></h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 使用方式: {{ name | upper }}</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">registerFilter</span><span class="token punctuation">(</span><span class="token string">'upper'</span><span class="token punctuation">,</span> <span class="token parameter">v</span> <span class="token operator">=></span> v<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>过滤器的参数将会传递给上面注册的过滤器函数,从第二个参数开始(第一个参数是过滤器左侧的输入),例如:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Usage: {{ 1 | add: 2, 3 }}</span></span><br><span class="line">engine.<span class="title function_">registerFilter</span>(<span class="string">'add'</span>, <span class="function">(<span class="params">initial, arg1, arg2</span>) =></span> initial + arg1 + arg2)</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// Usage: {{ 1 | add: 2, 3 }}</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">registerFilter</span><span class="token punctuation">(</span><span class="token string">'add'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">initial<span class="token punctuation">,</span> arg1<span class="token punctuation">,</span> arg2</span><span class="token punctuation">)</span> <span class="token operator">=></span> initial <span class="token operator">+</span> arg1 <span class="token operator">+</span> arg2<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>查看已有的过滤器实现:<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/tree/master/src/filters">https://github.com/harttle/liquidjs/tree/master/src/filters</a>。对于复杂的标签,也可以用一个类来实现:</p>
|
||||
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Usage: {% upper name:"alice" %}</span></span><br><span class="line"><span class="keyword">import</span> { <span class="title class_">Hash</span>, <span class="title class_">Tag</span>, <span class="title class_">TagToken</span>, <span class="title class_">Context</span>, <span class="title class_">Emitter</span>, <span class="title class_">TopLevelToken</span>, <span class="title class_">Liquid</span> } <span class="keyword">from</span> <span class="string">'liquidjs'</span></span><br><span class="line"></span><br><span class="line">engine.<span class="title function_">registerTag</span>(<span class="string">'upper'</span>, <span class="keyword">class</span> <span class="title class_">UpperTag</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Tag</span> {</span><br><span class="line"> <span class="keyword">private</span> <span class="attr">hash</span>: <span class="title class_">Hash</span></span><br><span class="line"> <span class="title function_">constructor</span>(<span class="params"><span class="attr">tagToken</span>: <span class="title class_">TagToken</span>, <span class="attr">remainTokens</span>: <span class="title class_">TopLevelToken</span>[], <span class="attr">liquid</span>: <span class="title class_">Liquid</span></span>) {</span><br><span class="line"> <span class="variable language_">super</span>(tagToken, remainTokens, liquid)</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">hash</span> = <span class="keyword">new</span> <span class="title class_">Hash</span>(tagToken.<span class="property">args</span>)</span><br><span class="line"> }</span><br><span class="line"> * <span class="title function_">render</span>(<span class="params"><span class="attr">ctx</span>: <span class="title class_">Context</span></span>) {</span><br><span class="line"> <span class="keyword">const</span> hash = <span class="keyword">yield</span> <span class="variable language_">this</span>.<span class="property">hash</span>.<span class="title function_">render</span>();</span><br><span class="line"> <span class="keyword">return</span> hash.<span class="property">name</span>.<span class="title function_">toUpperCase</span>() <span class="comment">// 'ALICE'</span></span><br><span class="line"> }</span><br><span class="line">});</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token comment">// Usage: {% upper name:"alice" %}</span>
|
||||
<span class="token keyword">import</span> <span class="token punctuation">{</span> Hash<span class="token punctuation">,</span> Tag<span class="token punctuation">,</span> TagToken<span class="token punctuation">,</span> Context<span class="token punctuation">,</span> Emitter<span class="token punctuation">,</span> TopLevelToken<span class="token punctuation">,</span> Liquid <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'liquidjs'</span>
|
||||
|
||||
engine<span class="token punctuation">.</span><span class="token function">registerTag</span><span class="token punctuation">(</span><span class="token string">'upper'</span><span class="token punctuation">,</span> <span class="token keyword">class</span> <span class="token class-name">UpperTag</span> <span class="token keyword">extends</span> <span class="token class-name">Tag</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">private</span> hash<span class="token operator">:</span> Hash
|
||||
<span class="token function">constructor</span><span class="token punctuation">(</span>tagToken<span class="token operator">:</span> TagToken<span class="token punctuation">,</span> remainTokens<span class="token operator">:</span> TopLevelToken<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> liquid<span class="token operator">:</span> Liquid<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">super</span><span class="token punctuation">(</span>tagToken<span class="token punctuation">,</span> remainTokens<span class="token punctuation">,</span> liquid<span class="token punctuation">)</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>hash <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Hash</span><span class="token punctuation">(</span>tagToken<span class="token punctuation">.</span>args<span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token operator">*</span> <span class="token function">render</span><span class="token punctuation">(</span>ctx<span class="token operator">:</span> Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">const</span> hash <span class="token operator">=</span> <span class="token keyword">yield</span> <span class="token keyword">this</span><span class="token punctuation">.</span>hash<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
<span class="token keyword">return</span> hash<span class="token punctuation">.</span>name<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// 'ALICE'</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<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/harttle/liquidjs/issues/324">#324</a>),注册一个假的标签/过滤器并在里面抛出相应的错误即可。</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 禁用标签</span></span><br><span class="line"><span class="keyword">const</span> disabledTag = {</span><br><span class="line"> <span class="attr">parse</span>: <span class="keyword">function</span>(<span class="params">token</span>) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">Error</span>(<span class="string">`tag "<span class="subst">${token.name}</span>" disabled`</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line">engine.<span class="title function_">registerTag</span>(<span class="string">'include'</span>, disabledTag);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 禁用过滤器</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">disabledFilter</span>(<span class="params">name</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">Error</span>(<span class="string">`filter "<span class="subst">${name}</span>" disabled`</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line">engine.<span class="title function_">registerFilter</span>(<span class="string">'plus'</span>, <span class="title function_">disabledFilter</span>(<span class="string">'plus'</span>));</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 禁用标签</span>
|
||||
<span class="token keyword">const</span> disabledTag <span class="token operator">=</span> <span class="token punctuation">{</span>
|
||||
<span class="token function-variable function">parse</span><span class="token operator">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">token</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">tag "</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>token<span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">" disabled</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">registerTag</span><span class="token punctuation">(</span><span class="token string">'include'</span><span class="token punctuation">,</span> disabledTag<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
|
||||
<span class="token comment">// 禁用过滤器</span>
|
||||
<span class="token keyword">function</span> <span class="token function">disabledFilter</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">filter "</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">" disabled</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">registerFilter</span><span class="token punctuation">(</span><span class="token string">'plus'</span><span class="token punctuation">,</span> <span class="token function">disabledFilter</span><span class="token punctuation">(</span><span class="token string">'plus'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="escaping.html" class="article-footer-prev" title="转义"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="access-scope-in-filters.html" class="article-footer-next" title="过滤器里访问上下文"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -94,20 +94,32 @@
|
||||
<div class="article-content" itemprop="articleBody">
|
||||
<p>一个典型的项目会有一个目录下都是模板,最方便的方式就是设置 LiquidJS 的 <a href="/api/interfaces/LiquidOptions.html#root">root</a> 然后调用 <a href="/api/classes/Liquid.html#renderFile">.renderFile()</a> 或 <a href="/api/classes/Liquid.html#renderFileSync">.renderFileSync()</a> 来渲染其中的一个模板文件。</p>
|
||||
<h2 id="渲染一个文件" class="article-heading"><a href="#渲染一个文件" class="headerlink" title="渲染一个文件"></a>渲染一个文件<a class="article-anchor" href="#渲染一个文件" aria-hidden="true"></a></h2><p>例如你有如下的目录结构:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">.</span><br><span class="line">├── index.js</span><br><span class="line">└── views/</span><br><span class="line"> ├── hello.liquid</span><br><span class="line"> └── world.liquid</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-none"><code class="language-none">.
|
||||
├── index.js
|
||||
└── views/
|
||||
├── hello.liquid
|
||||
└── world.liquid<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>其中 <code>hello.liquid</code> 内容为:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">name: {{name}}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid">name: <span class="token liquid language-liquid"><span class="token delimiter punctuation">{{</span>name<span class="token delimiter punctuation">}}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
<p>在 <code>index.js</code> 中可以这样渲染 <code>hello.liquid</code>:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>({</span><br><span class="line"> <span class="attr">root</span>: path.<span class="title function_">resolve</span>(__dirname, <span class="string">'views/'</span>), <span class="comment">// 设置模板查找目录</span></span><br><span class="line"> <span class="attr">extname</span>: <span class="string">'.liquid'</span> <span class="comment">// 添加后缀,默认为 "" 表示不添加后缀</span></span><br><span class="line">});</span><br><span class="line"><span class="comment">// 将会读取并渲染 `views/hello.liquid`</span></span><br><span class="line">engine.<span class="title function_">renderFile</span>(<span class="string">"hello"</span>, {<span class="attr">name</span>: <span class="string">'alice'</span>}).<span class="title function_">then</span>(<span class="variable language_">console</span>.<span class="property">log</span>)</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> engine <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Liquid</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
|
||||
<span class="token literal-property property">root</span><span class="token operator">:</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>__dirname<span class="token punctuation">,</span> <span class="token string">'views/'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">// 设置模板查找目录</span>
|
||||
<span class="token literal-property property">extname</span><span class="token operator">:</span> <span class="token string">'.liquid'</span> <span class="token comment">// 添加后缀,默认为 "" 表示不添加后缀</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
<span class="token comment">// 将会读取并渲染 `views/hello.liquid`</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">renderFile</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'alice'</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>执行 <code>node index.js</code> 你将会得到类似这样的输出:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">name: alice</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-none"><code class="language-none">name: alice<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
<h2 id="模板查找" class="article-heading"><a href="#模板查找" class="headerlink" title="模板查找"></a>模板查找<a class="article-anchor" href="#模板查找" aria-hidden="true"></a></h2><p>传递给 <a href="/api/classes/Liquid.html#renderFile">.renderFile()</a>, <a href="/api/classes/Liquid.html#parseFile">.parseFile()</a> <a href="/api/classes/Liquid.html#renderFileSync">.renderFileSync()</a>, <a href="/api/classes/Liquid.html#parseFileSync">.parseFileSync()</a> 这些 API 的模板名,<br>以及传递给 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://help.shopify.com/themes/liquid/tags/theme-tags#include">include</a>, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://help.shopify.com/en/themes/liquid/tags/theme-tags#layout">layout</a> 这些标签的模板名,将会根据 <a href="/api/interfaces/LiquidOptions.html#root">root</a> 选项来查找。</p>
|
||||
<p><code>root</code> 可以设置为 <code>string</code> 类型的路径(见上面的例子), 也可以设置为一个字符串数组表示路径列表,这时 LiquidJS 将会按顺序去查找。例如:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>({</span><br><span class="line"> <span class="attr">root</span>: [<span class="string">'views/'</span>, <span class="string">'views/partials/'</span>],</span><br><span class="line"> <span class="attr">extname</span>: <span class="string">'.liquid'</span></span><br><span class="line">});</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> engine <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Liquid</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
|
||||
<span class="token literal-property property">root</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">'views/'</span><span class="token punctuation">,</span> <span class="token string">'views/partials/'</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
|
||||
<span class="token literal-property property">extname</span><span class="token operator">:</span> <span class="token string">'.liquid'</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<blockquote class="note tip"><strong class="note-title">相对路径</strong><p><code>root</code> 中使用相对路径将会被解释为相对于 <code>cwd()</code>(当前工作目录)。</p>
|
||||
</blockquote>
|
||||
@@ -130,12 +142,31 @@
|
||||
</blockquote>
|
||||
|
||||
<h2 id="文件系统接口" class="article-heading"><a href="#文件系统接口" class="headerlink" title="文件系统接口"></a>文件系统接口<a class="article-anchor" href="#文件系统接口" aria-hidden="true"></a></h2><p>LiquidJS 定义了一个<a href="/api/interfaces/FS.html">文件系统接口</a>,在 Node.js 下的默认实现是 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/blob/master/src/fs/fs-impl.ts">src/fs/node.ts</a>,在浏览器打包文件中的默认实现是 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/blob/master/src/fs/fs-impl-browser.ts">src/fs/browser.ts</a>。<br>你可以通过创建 <code>Liquid</code> 时的 <a href="/api/interfaces/LiquidOptions.html#fs">fs</a> 参数来指定一个自定义实现来指定如何读取模板文件。比如从数据库里读取:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>({</span><br><span class="line"> <span class="attr">fs</span>: {</span><br><span class="line"> <span class="title function_">readFileSync</span> (file) {</span><br><span class="line"> <span class="keyword">return</span> db.<span class="title function_">model</span>(<span class="string">'Template'</span>).<span class="title function_">findByIdSync</span>(file).<span class="property">text</span></span><br><span class="line"> },</span><br><span class="line"> <span class="keyword">await</span> <span class="title function_">readFile</span> (file) {</span><br><span class="line"> <span class="keyword">const</span> template = <span class="keyword">await</span> db.<span class="title function_">model</span>(<span class="string">'Template'</span>).<span class="title function_">findById</span>(file)</span><br><span class="line"> <span class="keyword">return</span> template.<span class="property">text</span></span><br><span class="line"> },</span><br><span class="line"> <span class="title function_">existsSync</span> () {</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line"> },</span><br><span class="line"> <span class="keyword">await</span> <span class="title function_">exists</span> () {</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line"> },</span><br><span class="line"> <span class="title function_">resolve</span>(<span class="params">root, file, ext</span>) {</span><br><span class="line"> <span class="keyword">return</span> file</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">});</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> engine <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Liquid</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
|
||||
<span class="token literal-property property">fs</span><span class="token operator">:</span> <span class="token punctuation">{</span>
|
||||
<span class="token function">readFileSync</span> <span class="token punctuation">(</span><span class="token parameter">file</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">return</span> db<span class="token punctuation">.</span><span class="token function">model</span><span class="token punctuation">(</span><span class="token string">'Template'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">findByIdSync</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span><span class="token punctuation">.</span>text
|
||||
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||||
<span class="token keyword">await</span> <span class="token function">readFile</span> <span class="token punctuation">(</span><span class="token parameter">file</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">const</span> template <span class="token operator">=</span> <span class="token keyword">await</span> db<span class="token punctuation">.</span><span class="token function">model</span><span class="token punctuation">(</span><span class="token string">'Template'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">findById</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span>
|
||||
<span class="token keyword">return</span> template<span class="token punctuation">.</span>text
|
||||
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||||
<span class="token function">existsSync</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">return</span> <span class="token boolean">true</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||||
<span class="token keyword">await</span> <span class="token function">exists</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">return</span> <span class="token boolean">true</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||||
<span class="token function">resolve</span><span class="token punctuation">(</span><span class="token parameter">root<span class="token punctuation">,</span> file<span class="token punctuation">,</span> ext</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">return</span> file
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="options.html" class="article-footer-prev" title="选项"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="partials-and-layouts.html" class="article-footer-next" title="引用/继承"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -94,10 +94,14 @@
|
||||
<div class="article-content" itemprop="articleBody">
|
||||
<p>自定义标签可以有内容,也可以嵌套使用。本文描述了如何实现一个由<em>开始标签</em>,<em>结束标签</em>和之间的<em>标签内容</em>的自定义标签。</p>
|
||||
<h2 id="渲染标签内容" class="article-heading"><a href="#渲染标签内容" class="headerlink" title="渲染标签内容"></a>渲染标签内容<a class="article-anchor" href="#渲染标签内容" aria-hidden="true"></a></h2><p>我们先实现一个简单的 <code>wrap</code> 标签,它会把内容包装在 <code><div class="wrapper"></div></code> 元素里:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">{% wrap %}</span><br><span class="line"> {{ "hello world!" | capitalize }}</span><br><span class="line">{% endwrap %}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> wrap <span class="token delimiter punctuation">%}</span></span>
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{{</span> <span class="token string">"hello world!"</span> <span class="token operator">|</span> <span class="token function filter">capitalize</span> <span class="token delimiter punctuation">}}</span></span>
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> endwrap <span class="token delimiter punctuation">%}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>期望输出:</p>
|
||||
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">'wrapper'</span>></span></span><br><span class="line"> Hello world!</span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-markup" data-language="markup"><code class="language-markup"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">'</span>wrapper<span class="token punctuation">'</span></span><span class="token punctuation">></span></span>
|
||||
Hello world!
|
||||
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>首先 <a href="./register-filters-tags.html">注册</a> 一个名为 <code>wrap</code> 的标签,把内容解析到 <code>this.tpls</code> 数组里。<code>parse(tagToken, remainTokens)</code> 中,</p>
|
||||
<ul>
|
||||
@@ -105,25 +109,77 @@
|
||||
<li><code>remainTokens</code> 是当前模板中后续所有 <em>Token</em> 的数组。</li>
|
||||
</ul>
|
||||
<p>我们要做的是从 <code>remainTokens</code> 里拿出来/<code>.shift()</code> 足够的标签直到遇到 <code>endwrap</code>(其实可以是任意名字,但按照惯例应该叫 <code>endwrap</code>)。如果到模板结尾都没遇到 <code>endwrap</code>,需要抛出一个标签未关闭的 <code>Error</code>。</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">engine.<span class="title function_">registerTag</span>(<span class="string">'wrap'</span>, {</span><br><span class="line"> <span class="title function_">parse</span>(<span class="params">tagToken, remainTokens</span>) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">tpls</span> = []</span><br><span class="line"> <span class="keyword">let</span> closed = <span class="literal">false</span></span><br><span class="line"> <span class="keyword">while</span>(remainTokens.<span class="property">length</span>) {</span><br><span class="line"> <span class="keyword">let</span> token = remainTokens.<span class="title function_">shift</span>()</span><br><span class="line"> <span class="comment">// 得到了结束标签,停止解析</span></span><br><span class="line"> <span class="keyword">if</span> (token.<span class="property">name</span> === <span class="string">'endwrap'</span>) {</span><br><span class="line"> closed = <span class="literal">true</span></span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 把 Token 解析成 Template</span></span><br><span class="line"> <span class="comment">// parseToken() 可能会消耗多个 Token</span></span><br><span class="line"> <span class="comment">// 例如 {% if %}...{% endif %}</span></span><br><span class="line"> <span class="keyword">let</span> tpl = <span class="variable language_">this</span>.<span class="property">liquid</span>.<span class="property">parser</span>.<span class="title function_">parseToken</span>(token, remainTokens)</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">tpls</span>.<span class="title function_">push</span>(tpl)</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (!closed) <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">Error</span>(<span class="string">`tag <span class="subst">${tagToken.getText()}</span> not closed`</span>)</span><br><span class="line"> },</span><br><span class="line"> * <span class="title function_">render</span>(<span class="params">context, emitter</span>) {</span><br><span class="line"> emitter.<span class="title function_">write</span>(<span class="string">"<div class='wrapper'>"</span>)</span><br><span class="line"> <span class="keyword">yield</span> <span class="variable language_">this</span>.<span class="property">liquid</span>.<span class="property">renderer</span>.<span class="title function_">renderTemplates</span>(<span class="variable language_">this</span>.<span class="property">tpls</span>, context, emitter)</span><br><span class="line"> emitter.<span class="title function_">write</span>(<span class="string">"</div>"</span>)</span><br><span class="line"> }</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">engine<span class="token punctuation">.</span><span class="token function">registerTag</span><span class="token punctuation">(</span><span class="token string">'wrap'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
|
||||
<span class="token function">parse</span><span class="token punctuation">(</span><span class="token parameter">tagToken<span class="token punctuation">,</span> remainTokens</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>tpls <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
|
||||
<span class="token keyword">let</span> closed <span class="token operator">=</span> <span class="token boolean">false</span>
|
||||
<span class="token keyword">while</span><span class="token punctuation">(</span>remainTokens<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">let</span> token <span class="token operator">=</span> remainTokens<span class="token punctuation">.</span><span class="token function">shift</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||||
<span class="token comment">// 得到了结束标签,停止解析</span>
|
||||
<span class="token keyword">if</span> <span class="token punctuation">(</span>token<span class="token punctuation">.</span>name <span class="token operator">===</span> <span class="token string">'endwrap'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
closed <span class="token operator">=</span> <span class="token boolean">true</span>
|
||||
<span class="token keyword">break</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token comment">// 把 Token 解析成 Template</span>
|
||||
<span class="token comment">// parseToken() 可能会消耗多个 Token</span>
|
||||
<span class="token comment">// 例如 {% if %}...{% endif %}</span>
|
||||
<span class="token keyword">let</span> tpl <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>liquid<span class="token punctuation">.</span>parser<span class="token punctuation">.</span><span class="token function">parseToken</span><span class="token punctuation">(</span>token<span class="token punctuation">,</span> remainTokens<span class="token punctuation">)</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>tpls<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>tpl<span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>closed<span class="token punctuation">)</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">tag </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>tagToken<span class="token punctuation">.</span><span class="token function">getText</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> not closed</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||||
<span class="token operator">*</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token parameter">context<span class="token punctuation">,</span> emitter</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
emitter<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token string">"<div class='wrapper'>"</span><span class="token punctuation">)</span>
|
||||
<span class="token keyword">yield</span> <span class="token keyword">this</span><span class="token punctuation">.</span>liquid<span class="token punctuation">.</span>renderer<span class="token punctuation">.</span><span class="token function">renderTemplates</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>tpls<span class="token punctuation">,</span> context<span class="token punctuation">,</span> emitter<span class="token punctuation">)</span>
|
||||
emitter<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token string">"</div>"</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p><code>.renderTemplates()</code> 可能是异步的,因此需要 <code>yield</code> 来等它完成。更多关于 LiquidJS 异步的信息可以参考 <a href="./sync-and-async.html">同步和异步</a>。<code>render()</code> 的其他部分比较直观,这是 JSFiddle 版本:<a target="_blank" rel="noopener external nofollow noreferrer" href="http://jsfiddle.net/por0zcn1/3/">http://jsfiddle.net/por0zcn1/3/</a>。</p>
|
||||
<h2 id="使用-ParseStream" class="article-heading"><a href="#使用-ParseStream" class="headerlink" title="使用 ParseStream"></a>使用 ParseStream<a class="article-anchor" href="#使用-ParseStream" aria-hidden="true"></a></h2><p>对于像 <a href="../tags/for.html">for</a> 和 <a href="../tags/if.html">if</a> 这样的复杂标签,<code>parse()</code> 会变得很复杂。使用 <a href="/api/classes/ParseStream.html">ParseStream</a> 工具可以按事件风格来组织 <code>parse()</code> 的逻辑。下面是用 <code>ParseStream</code> 重写过的 <code>parse()</code>,实现了和上面例子中完全一样的功能。</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">parse</span>(<span class="params">tagToken, remainTokens</span>) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">tpls</span> = []</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">liquid</span>.<span class="property">parser</span>.<span class="title function_">parseStream</span>(remainTokens)</span><br><span class="line"> .<span class="title function_">on</span>(<span class="string">'template'</span>, <span class="function"><span class="params">tpl</span> =></span> <span class="variable language_">this</span>.<span class="property">tpls</span>.<span class="title function_">push</span>(tpl))</span><br><span class="line"> <span class="comment">// 注意这里不能用箭头函数,因为我们需要 `this`</span></span><br><span class="line"> .<span class="title function_">on</span>(<span class="string">'tag:endwrap'</span>, <span class="keyword">function</span> (<span class="params"></span>) { <span class="variable language_">this</span>.<span class="title function_">stop</span>() })</span><br><span class="line"> .<span class="title function_">on</span>(<span class="string">'end'</span>, <span class="function">() =></span> { <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">Error</span>(<span class="string">`tag <span class="subst">${tagToken.getText()}</span> not closed`</span>) })</span><br><span class="line"> .<span class="title function_">start</span>()</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token function">parse</span><span class="token punctuation">(</span><span class="token parameter">tagToken<span class="token punctuation">,</span> remainTokens</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>tpls <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>liquid<span class="token punctuation">.</span>parser<span class="token punctuation">.</span><span class="token function">parseStream</span><span class="token punctuation">(</span>remainTokens<span class="token punctuation">)</span>
|
||||
<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'template'</span><span class="token punctuation">,</span> <span class="token parameter">tpl</span> <span class="token operator">=></span> <span class="token keyword">this</span><span class="token punctuation">.</span>tpls<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>tpl<span class="token punctuation">)</span><span class="token punctuation">)</span>
|
||||
<span class="token comment">// 注意这里不能用箭头函数,因为我们需要 `this`</span>
|
||||
<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'tag:endwrap'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'end'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">tag </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>tagToken<span class="token punctuation">.</span><span class="token function">getText</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> not closed</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">.</span><span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>这是 JSFiddle 链接:<a target="_blank" rel="noopener external nofollow noreferrer" href="http://jsfiddle.net/por0zcn1/4/">http://jsfiddle.net/por0zcn1/4/</a>。简单起见,下面的例子都借助 <code>ParseStream</code> 来实现。</p>
|
||||
<h2 id="操作上下文" class="article-heading"><a href="#操作上下文" class="headerlink" title="操作上下文"></a>操作上下文<a class="article-anchor" href="#操作上下文" aria-hidden="true"></a></h2><p>上面的 <code>wrap</code> 标签看起来没什么用,反正没它也可以很容易地渲染那部分内容。我们现在来实现一个 <code>repeat</code> 标签,把内容渲染两次(还可以<a href="./parse-parameters.html">加个参数</a>让它渲染任意次):</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">{% repeat %}</span><br><span class="line"> {{ repeat.i }}. {{ "hello world!" | capitalize }}</span><br><span class="line">{% endrepeat %}`</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> repeat <span class="token delimiter punctuation">%}</span></span>
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{{</span> repeat<span class="token punctuation">.</span>i <span class="token delimiter punctuation">}}</span></span>. <span class="token liquid language-liquid"><span class="token delimiter punctuation">{{</span> <span class="token string">"hello world!"</span> <span class="token operator">|</span> <span class="token function filter">capitalize</span> <span class="token delimiter punctuation">}}</span></span>
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> endrepeat <span class="token delimiter punctuation">%}</span></span>`<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>期望输出:</p>
|
||||
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">1. Hello world!</span><br><span class="line">2. Hello world!</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-markup" data-language="markup"><code class="language-markup">1. Hello world!
|
||||
2. Hello world!<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>你可能注意到了在 <code>repeat</code> 上下文里有个额外的变量 <code>repeat.i</code>,这就需要我们操作 <em>上下文</em>。</p>
|
||||
<blockquote class="note info"><strong class="note-title">上下文</strong><p><em>上下文</em> 定义了 Liquid 模板中每个变量的值。在 LiquidJS 中,<code>Context</code> 由一个 <code>Scope</code> 的栈组成。<em>Scope</em> 就是一个普通对象,就像传给 <code>engine.render(tpl, scope)</code> 的 <code>scope</code> 一样。</p>
|
||||
</blockquote>
|
||||
|
||||
<p>每次进入新的 <em>上下文</em> 时,我们需要 <code>push</code> 一个新的 <code>Scope</code>。当结束渲染并退出 <em>上下文</em> 时,再把 <code>Scope</code> 从 <em>上下文</em> <code>pop</code> 出来。见下面的实现:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">engine.<span class="title function_">registerTag</span>(<span class="string">'repeat'</span>, {</span><br><span class="line"> <span class="title function_">parse</span>(<span class="params">tagToken, remainTokens</span>) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">tpls</span> = []</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">liquid</span>.<span class="property">parser</span>.<span class="title function_">parseStream</span>(remainTokens)</span><br><span class="line"> .<span class="title function_">on</span>(<span class="string">'template'</span>, <span class="function"><span class="params">tpl</span> =></span> <span class="variable language_">this</span>.<span class="property">tpls</span>.<span class="title function_">push</span>(tpl))</span><br><span class="line"> .<span class="title function_">on</span>(<span class="string">'tag:endrepeat'</span>, <span class="keyword">function</span> (<span class="params"></span>) { <span class="variable language_">this</span>.<span class="title function_">stop</span>() })</span><br><span class="line"> .<span class="title function_">on</span>(<span class="string">'end'</span>, <span class="function">() =></span> { <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">Error</span>(<span class="string">`tag <span class="subst">${tagToken.getText()}</span> not closed`</span>) })</span><br><span class="line"> .<span class="title function_">start</span>()</span><br><span class="line"> },</span><br><span class="line"> * <span class="title function_">render</span>(<span class="params">context, emitter</span>) {</span><br><span class="line"> <span class="keyword">const</span> repeat = { <span class="attr">i</span>: <span class="number">1</span> }</span><br><span class="line"> context.<span class="title function_">push</span>({ repeat })</span><br><span class="line"> <span class="keyword">yield</span> <span class="variable language_">this</span>.<span class="property">liquid</span>.<span class="property">renderer</span>.<span class="title function_">renderTemplates</span>(<span class="variable language_">this</span>.<span class="property">tpls</span>, context, emitter)</span><br><span class="line"> repeat.<span class="property">i</span>++</span><br><span class="line"> <span class="keyword">yield</span> <span class="variable language_">this</span>.<span class="property">liquid</span>.<span class="property">renderer</span>.<span class="title function_">renderTemplates</span>(<span class="variable language_">this</span>.<span class="property">tpls</span>, context, emitter)</span><br><span class="line"> context.<span class="title function_">pop</span>()</span><br><span class="line"> }</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">engine<span class="token punctuation">.</span><span class="token function">registerTag</span><span class="token punctuation">(</span><span class="token string">'repeat'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
|
||||
<span class="token function">parse</span><span class="token punctuation">(</span><span class="token parameter">tagToken<span class="token punctuation">,</span> remainTokens</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>tpls <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>liquid<span class="token punctuation">.</span>parser<span class="token punctuation">.</span><span class="token function">parseStream</span><span class="token punctuation">(</span>remainTokens<span class="token punctuation">)</span>
|
||||
<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'template'</span><span class="token punctuation">,</span> <span class="token parameter">tpl</span> <span class="token operator">=></span> <span class="token keyword">this</span><span class="token punctuation">.</span>tpls<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>tpl<span class="token punctuation">)</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'tag:endrepeat'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'end'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">tag </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>tagToken<span class="token punctuation">.</span><span class="token function">getText</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> not closed</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">.</span><span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
||||
<span class="token operator">*</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token parameter">context<span class="token punctuation">,</span> emitter</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">const</span> repeat <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">i</span><span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">}</span>
|
||||
context<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">{</span> repeat <span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||||
<span class="token keyword">yield</span> <span class="token keyword">this</span><span class="token punctuation">.</span>liquid<span class="token punctuation">.</span>renderer<span class="token punctuation">.</span><span class="token function">renderTemplates</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>tpls<span class="token punctuation">,</span> context<span class="token punctuation">,</span> emitter<span class="token punctuation">)</span>
|
||||
repeat<span class="token punctuation">.</span>i<span class="token operator">++</span>
|
||||
<span class="token keyword">yield</span> <span class="token keyword">this</span><span class="token punctuation">.</span>liquid<span class="token punctuation">.</span>renderer<span class="token punctuation">.</span><span class="token function">renderTemplates</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>tpls<span class="token punctuation">,</span> context<span class="token punctuation">,</span> emitter<span class="token punctuation">)</span>
|
||||
context<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p><code>parse()</code> 部分和 <code>wrap</code> 标签完全相同,在 <code>render()</code> 部分我们通过调用两次 <code>.renderTemplates(this.tpls)</code> 来重复渲染内容。这是 JSFiddle 链接:<a target="_blank" rel="noopener external nofollow noreferrer" href="http://jsfiddle.net/por0zcn1/2/">http://jsfiddle.net/por0zcn1/2/</a>。</p>
|
||||
<blockquote class="note warn"><strong class="note-title">成对使用 Push 和 Pop</strong><p>必须成对地使用 <code>context.push()</code> 和 <code>context.pop()</code>。如果忘记 <code>pop()</code> 会导致 <code>Scope</code> 泄露给后面的模板内容,也可能损坏 <em>上下文</em> 栈。.</p>
|
||||
@@ -132,7 +188,7 @@
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="parse-parameters.html" class="article-footer-prev" title="参数解析"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="drops.html" class="article-footer-next" title="Liquid Drop"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -94,21 +94,32 @@
|
||||
<div class="article-content" itemprop="articleBody">
|
||||
<p>如果你还不了解 Liquid 模板语言,请参考 <a href="./intro-to-liquid.html">Liquid 模板语言简介</a>。</p>
|
||||
<h2 id="在-Node-js-里使用" class="article-heading"><a href="#在-Node-js-里使用" class="headerlink" title="在 Node.js 里使用"></a>在 Node.js 里使用<a class="article-anchor" href="#在-Node-js-里使用" aria-hidden="true"></a></h2><p>通过 NPM 安装:</p>
|
||||
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install --save liquidjs</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token function">npm</span> <span class="token function">install</span> <span class="token parameter variable">--save</span> liquidjs<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> { <span class="title class_">Liquid</span> } = <span class="built_in">require</span>(<span class="string">'liquidjs'</span>);</span><br><span class="line"><span class="keyword">var</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>();</span><br><span class="line"></span><br><span class="line">engine</span><br><span class="line"> .<span class="title function_">parseAndRender</span>(<span class="string">'{{name | capitalize}}'</span>, {<span class="attr">name</span>: <span class="string">'alice'</span>})</span><br><span class="line"> .<span class="title function_">then</span>(<span class="variable language_">console</span>.<span class="property">log</span>); <span class="comment">// 输出 'Alice'</span></span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> <span class="token punctuation">{</span> Liquid <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'liquidjs'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
<span class="token keyword">var</span> engine <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Liquid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
|
||||
engine
|
||||
<span class="token punctuation">.</span><span class="token function">parseAndRender</span><span class="token punctuation">(</span><span class="token string">'{{name | capitalize}}'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'alice'</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 输出 'Alice'</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<blockquote class="note info"><strong class="note-title">示例</strong><p>这里有一个 LiquidJS 在 Node.js 里使用的例子:<a href="https://github.com/harttle/liquidjs/blob/master/demo/nodejs/" rel="external nofollow noreferrer" target="_blank">liquidjs/demo/nodejs/</a>.</p>
|
||||
</blockquote>
|
||||
|
||||
<p>LiquidJS 的类型定义也导出并发布到了 NPM 包里,写 TypeScript 的项目可以直接这样使用:</p>
|
||||
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">Liquid</span> } <span class="keyword">from</span> <span class="string">'liquidjs'</span>;</span><br><span class="line"><span class="keyword">const</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>();</span><br><span class="line"></span><br><span class="line">engine</span><br><span class="line"> .<span class="title function_">parseAndRender</span>(<span class="string">'{{name | capitalize}}'</span>, {<span class="attr">name</span>: <span class="string">'alice'</span>})</span><br><span class="line"> .<span class="title function_">then</span>(<span class="variable language_">console</span>.<span class="property">log</span>); <span class="comment">// 输出 'Alice'</span></span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token keyword">import</span> <span class="token punctuation">{</span> Liquid <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'liquidjs'</span><span class="token punctuation">;</span>
|
||||
<span class="token keyword">const</span> engine <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Liquid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
|
||||
engine
|
||||
<span class="token punctuation">.</span><span class="token function">parseAndRender</span><span class="token punctuation">(</span><span class="token string">'{{name | capitalize}}'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>name<span class="token operator">:</span> <span class="token string">'alice'</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token builtin">console</span><span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 输出 'Alice'</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<blockquote class="note info"><strong class="note-title">示例</strong><p>这里有一个 LiquidJS 在 TypeScript 下的例子:<a href="https://github.com/harttle/liquidjs/blob/master/demo/typescript/" rel="external nofollow noreferrer" target="_blank">liquidjs/demo/typescript/</a>.</p>
|
||||
</blockquote>
|
||||
|
||||
<h2 id="在浏览器里使用" class="article-heading"><a href="#在浏览器里使用" class="headerlink" title="在浏览器里使用"></a>在浏览器里使用<a class="article-anchor" href="#在浏览器里使用" aria-hidden="true"></a></h2><p>LiquidJS 预先构建了 UMD Bundle,可以通过 jsDelivr CDN 来引用:</p>
|
||||
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://cdn.jsdelivr.net/npm/liquidjs/dist/liquid.browser.min.js"</span>></span><span class="tag"></<span class="name">script</span>></span> <span class="comment"><!--生产环境--></span></span><br><span class="line"><span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://cdn.jsdelivr.net/npm/liquidjs/dist/liquid.browser.umd.js"</span>></span><span class="tag"></<span class="name">script</span>></span> <span class="comment"><!--开发环境--></span></span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-markup" data-language="markup"><code class="language-markup"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://cdn.jsdelivr.net/npm/liquidjs/dist/liquid.browser.min.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>script</span><span class="token punctuation">></span></span> <span class="token comment"><!--生产环境--></span>
|
||||
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://cdn.jsdelivr.net/npm/liquidjs/dist/liquid.browser.umd.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>script</span><span class="token punctuation">></span></span> <span class="token comment"><!--开发环境--></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
|
||||
|
||||
<blockquote class="note info"><strong class="note-title">示例</strong><p>这里有一个 jsFiddle 上的在线例子:<a href="https://jsfiddle.net/x43eb0z6/" rel="external nofollow noreferrer" target="_blank">jsfiddle.net/x43eb0z6</a>,其源码也可以在 <a href="https://github.com/harttle/liquidjs/blob/master/demo/browser/" rel="external nofollow noreferrer" target="_blank">liquidjs/demo/browser/</a> 找到。</p>
|
||||
</blockquote>
|
||||
@@ -117,16 +128,16 @@
|
||||
</blockquote>
|
||||
|
||||
<h2 id="在命令行里使用" class="article-heading"><a href="#在命令行里使用" class="headerlink" title="在命令行里使用"></a>在命令行里使用<a class="article-anchor" href="#在命令行里使用" aria-hidden="true"></a></h2><p>你还可以在命令行里使用 LiquidJS:</p>
|
||||
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">echo</span> <span class="string">'{{"hello" | capitalize}}'</span> | npx liquidjs</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token builtin class-name">echo</span> <span class="token string">'{{"hello" | capitalize}}'</span> <span class="token operator">|</span> npx liquidjs<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
<p>模板来自标准输入,数据则来自参数,这个参数可以是一个 JSON 文件的路径,也可以是一个 JSON 字符串:</p>
|
||||
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">echo</span> <span class="string">'Hello, {{ name }}.'</span> | npx liquidjs <span class="string">'{"name": "Snake"}'</span></span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token builtin class-name">echo</span> <span class="token string">'Hello, {{ name }}.'</span> <span class="token operator">|</span> npx liquidjs <span class="token string">'{"name": "Snake"}'</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
<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/stevenanthonyrevo">@stevenanthonyrevo</a> 还提供了一个 ReactJS demo,请参考 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/blob/master/demo/reactjs/">liquidjs/demo/reactjs/</a>。</p>
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="intro-to-liquid.html" class="article-footer-prev" title="Liquid 简介"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="options.html" class="article-footer-next" title="选项"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -110,7 +110,21 @@
|
||||
<li><code>evalValueSync()</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>LiquidJS 使用基于生成器的异步实现,来让同一份代码支持同步和异步调用。例如下面的 <code>UpperTag</code> 既可以用于 <code>engine.renderSync()</code> 也可以用于 <code>engine.render()</code>:</p>
|
||||
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">TagToken</span>, <span class="title class_">Context</span>, <span class="title class_">Emitter</span>, <span class="title class_">TopLevelToken</span>, <span class="title class_">Value</span>, <span class="title class_">Tag</span>, <span class="title class_">Liquid</span> } <span class="keyword">from</span> <span class="string">'liquidjs'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Usage: {% upper "alice" %}</span></span><br><span class="line"><span class="comment">// Output: ALICE</span></span><br><span class="line">engine.<span class="title function_">registerTag</span>(<span class="string">'upper'</span>, <span class="keyword">class</span> <span class="title class_">UpperTag</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Tag</span> {</span><br><span class="line"> <span class="keyword">private</span> <span class="attr">value</span>: <span class="title class_">Value</span></span><br><span class="line"> <span class="title function_">constructor</span> (<span class="params"><span class="attr">token</span>: <span class="title class_">TagToken</span>, <span class="attr">remainTokens</span>: <span class="title class_">TopLevelToken</span>[], <span class="attr">liquid</span>: <span class="title class_">Liquid</span></span>) {</span><br><span class="line"> <span class="variable language_">super</span>(token, remainTokens, liquid)</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">value</span> = <span class="keyword">new</span> <span class="title class_">Value</span>(token.<span class="property">args</span>, liquid)</span><br><span class="line"> }</span><br><span class="line"> * <span class="title function_">render</span> (<span class="attr">ctx</span>: <span class="title class_">Context</span>, <span class="attr">emitter</span>: <span class="title class_">Emitter</span>) {</span><br><span class="line"> <span class="keyword">const</span> title = <span class="keyword">yield</span> <span class="variable language_">this</span>.<span class="property">value</span>.<span class="title function_">value</span>(ctx)</span><br><span class="line"> emitter.<span class="title function_">write</span>(title.<span class="title function_">toUpperCase</span>())</span><br><span class="line"> }</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token keyword">import</span> <span class="token punctuation">{</span> TagToken<span class="token punctuation">,</span> Context<span class="token punctuation">,</span> Emitter<span class="token punctuation">,</span> TopLevelToken<span class="token punctuation">,</span> Value<span class="token punctuation">,</span> Tag<span class="token punctuation">,</span> Liquid <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'liquidjs'</span>
|
||||
|
||||
<span class="token comment">// Usage: {% upper "alice" %}</span>
|
||||
<span class="token comment">// Output: ALICE</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">registerTag</span><span class="token punctuation">(</span><span class="token string">'upper'</span><span class="token punctuation">,</span> <span class="token keyword">class</span> <span class="token class-name">UpperTag</span> <span class="token keyword">extends</span> <span class="token class-name">Tag</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">private</span> value<span class="token operator">:</span> Value
|
||||
<span class="token function">constructor</span> <span class="token punctuation">(</span>token<span class="token operator">:</span> TagToken<span class="token punctuation">,</span> remainTokens<span class="token operator">:</span> TopLevelToken<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> liquid<span class="token operator">:</span> Liquid<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">super</span><span class="token punctuation">(</span>token<span class="token punctuation">,</span> remainTokens<span class="token punctuation">,</span> liquid<span class="token punctuation">)</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>value <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Value</span><span class="token punctuation">(</span>token<span class="token punctuation">.</span>args<span class="token punctuation">,</span> liquid<span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token operator">*</span> <span class="token function">render</span> <span class="token punctuation">(</span>ctx<span class="token operator">:</span> Context<span class="token punctuation">,</span> emitter<span class="token operator">:</span> Emitter<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">const</span> title <span class="token operator">=</span> <span class="token keyword">yield</span> <span class="token keyword">this</span><span class="token punctuation">.</span>value<span class="token punctuation">.</span><span class="token function">value</span><span class="token punctuation">(</span>ctx<span class="token punctuation">)</span>
|
||||
emitter<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>title<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>所有内置标签都兼容同步,可以安全地用于同步或异步 API。实现同时支持同异步的标签,需要:</p>
|
||||
<ul>
|
||||
@@ -119,19 +133,51 @@
|
||||
<li>不能调用会返回 Promise 的函数。</li>
|
||||
</ul>
|
||||
<h2 id="调用返回-Promise-的函数" class="article-heading"><a href="#调用返回-Promise-的函数" class="headerlink" title="调用返回 Promise 的函数"></a>调用返回 Promise 的函数<a class="article-anchor" href="#调用返回-Promise-的函数" aria-hidden="true"></a></h2><p>但 LiquidJS 是支持 <code>Promise</code> 的,你仍然可以调用返回 <code>Promise</code> 的方法并等它 resolve。只需要把 <code>await</code> 换成 <code>yield</code>。例如:</p>
|
||||
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">* <span class="title function_">render</span> (<span class="attr">ctx</span>: <span class="title class_">Context</span>, <span class="attr">emitter</span>: <span class="title class_">Emitter</span>) {</span><br><span class="line"> <span class="keyword">const</span> file = <span class="keyword">yield</span> <span class="variable language_">this</span>.<span class="property">value</span>.<span class="title function_">value</span>(ctx)</span><br><span class="line"> <span class="keyword">const</span> title = <span class="keyword">yield</span> fs.<span class="title function_">readFile</span>(file, <span class="string">'utf8'</span>)</span><br><span class="line"> emitter.<span class="title function_">write</span>(title.<span class="title function_">toUpperCase</span>())</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token operator">*</span> <span class="token function">render</span> <span class="token punctuation">(</span>ctx<span class="token operator">:</span> Context<span class="token punctuation">,</span> emitter<span class="token operator">:</span> Emitter<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">const</span> file <span class="token operator">=</span> <span class="token keyword">yield</span> <span class="token keyword">this</span><span class="token punctuation">.</span>value<span class="token punctuation">.</span><span class="token function">value</span><span class="token punctuation">(</span>ctx<span class="token punctuation">)</span>
|
||||
<span class="token keyword">const</span> title <span class="token operator">=</span> <span class="token keyword">yield</span> fs<span class="token punctuation">.</span><span class="token function">readFile</span><span class="token punctuation">(</span>file<span class="token punctuation">,</span> <span class="token string">'utf8'</span><span class="token punctuation">)</span>
|
||||
emitter<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>title<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>现在 <code>* render()</code> 调用了一个返回 Promise 的 API,它就不再兼容同步了。不兼容同步的标签也仍然是合法标签,在异步 API 下也会正常运行。被同步调用时,返回 <code>Promise</code> 的标签会被渲染成 <code>[object Promise]</code>。</p>
|
||||
<h2 id="把-LiquidJS-生成器转换成-Promise" class="article-heading"><a href="#把-LiquidJS-生成器转换成-Promise" class="headerlink" title="把 LiquidJS 生成器转换成 Promise"></a>把 LiquidJS 生成器转换成 Promise<a class="article-anchor" href="#把-LiquidJS-生成器转换成-Promise" aria-hidden="true"></a></h2><p>有些 LiquidJS API 会返回 <code>Promise</code>,有些会返回生成器。你可以用 <a href="/api/functions/toPromise.html">toPromise</a> 来把生成器转换为 <code>Promise</code>,比如:</p>
|
||||
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { <span class="title class_">TagToken</span>, <span class="title class_">Context</span>, <span class="title class_">Emitter</span>, <span class="title class_">TopLevelToken</span>, <span class="title class_">Value</span>, <span class="title class_">Tag</span>, <span class="title class_">Liquid</span>, toPromise } <span class="keyword">from</span> <span class="string">'liquidjs'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Usage: {% upper "alice" %}</span></span><br><span class="line"><span class="comment">// Output: ALICE</span></span><br><span class="line">engine.<span class="title function_">registerTag</span>(<span class="string">'upper'</span>, <span class="keyword">class</span> <span class="title class_">UpperTag</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Tag</span> {</span><br><span class="line"> <span class="keyword">private</span> <span class="attr">value</span>: <span class="title class_">Value</span></span><br><span class="line"> <span class="title function_">constructor</span> (<span class="params"><span class="attr">token</span>: <span class="title class_">TagToken</span>, <span class="attr">remainTokens</span>: <span class="title class_">TopLevelToken</span>[], <span class="attr">liquid</span>: <span class="title class_">Liquid</span></span>) {</span><br><span class="line"> <span class="variable language_">super</span>(token, remainTokens, liquid)</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">value</span> = <span class="keyword">new</span> <span class="title class_">Value</span>(token.<span class="property">args</span>, liquid)</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">async</span> <span class="title function_">render</span> (<span class="attr">ctx</span>: <span class="title class_">Context</span>, <span class="attr">emitter</span>: <span class="title class_">Emitter</span>) {</span><br><span class="line"> <span class="keyword">const</span> title = <span class="keyword">await</span> <span class="title function_">toPromise</span>(<span class="variable language_">this</span>.<span class="property">value</span>.<span class="title function_">value</span>(ctx))</span><br><span class="line"> emitter.<span class="title function_">write</span>(title.<span class="title function_">toUpperCase</span>())</span><br><span class="line"> }</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token keyword">import</span> <span class="token punctuation">{</span> TagToken<span class="token punctuation">,</span> Context<span class="token punctuation">,</span> Emitter<span class="token punctuation">,</span> TopLevelToken<span class="token punctuation">,</span> Value<span class="token punctuation">,</span> Tag<span class="token punctuation">,</span> Liquid<span class="token punctuation">,</span> toPromise <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'liquidjs'</span>
|
||||
|
||||
<span class="token comment">// Usage: {% upper "alice" %}</span>
|
||||
<span class="token comment">// Output: ALICE</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">registerTag</span><span class="token punctuation">(</span><span class="token string">'upper'</span><span class="token punctuation">,</span> <span class="token keyword">class</span> <span class="token class-name">UpperTag</span> <span class="token keyword">extends</span> <span class="token class-name">Tag</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">private</span> value<span class="token operator">:</span> Value
|
||||
<span class="token function">constructor</span> <span class="token punctuation">(</span>token<span class="token operator">:</span> TagToken<span class="token punctuation">,</span> remainTokens<span class="token operator">:</span> TopLevelToken<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> liquid<span class="token operator">:</span> Liquid<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">super</span><span class="token punctuation">(</span>token<span class="token punctuation">,</span> remainTokens<span class="token punctuation">,</span> liquid<span class="token punctuation">)</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>value <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Value</span><span class="token punctuation">(</span>token<span class="token punctuation">.</span>args<span class="token punctuation">,</span> liquid<span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token keyword">async</span> <span class="token function">render</span> <span class="token punctuation">(</span>ctx<span class="token operator">:</span> Context<span class="token punctuation">,</span> emitter<span class="token operator">:</span> Emitter<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">const</span> title <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">toPromise</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>value<span class="token punctuation">.</span><span class="token function">value</span><span class="token punctuation">(</span>ctx<span class="token punctuation">)</span><span class="token punctuation">)</span>
|
||||
emitter<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>title<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<h2 id="纯异步标签" class="article-heading"><a href="#纯异步标签" class="headerlink" title="纯异步标签"></a>纯异步标签<a class="article-anchor" href="#纯异步标签" aria-hidden="true"></a></h2><p>如果你的标签就不打算支持同步,可以干脆实现成 <code>async render()</code>,这样就可以使用更熟悉的 <code>await</code> 了:</p>
|
||||
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { toPromise, <span class="title class_">TagToken</span>, <span class="title class_">Context</span>, <span class="title class_">Emitter</span>, <span class="title class_">TopLevelToken</span>, <span class="title class_">Value</span>, <span class="title class_">Tag</span>, <span class="title class_">Liquid</span> } <span class="keyword">from</span> <span class="string">'liquidjs'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Usage: {% upper "alice" %}</span></span><br><span class="line"><span class="comment">// Output: ALICE</span></span><br><span class="line">engine.<span class="title function_">registerTag</span>(<span class="string">'upper'</span>, <span class="keyword">class</span> <span class="title class_">UpperTag</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Tag</span> {</span><br><span class="line"> <span class="keyword">private</span> <span class="attr">value</span>: <span class="title class_">Value</span></span><br><span class="line"> <span class="title function_">constructor</span> (<span class="params"><span class="attr">token</span>: <span class="title class_">TagToken</span>, <span class="attr">remainTokens</span>: <span class="title class_">TopLevelToken</span>[], <span class="attr">liquid</span>: <span class="title class_">Liquid</span></span>) {</span><br><span class="line"> <span class="variable language_">super</span>(token, remainTokens, liquid)</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">value</span> = <span class="keyword">new</span> <span class="title class_">Value</span>(token.<span class="property">args</span>, liquid)</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">async</span> <span class="title function_">render</span> (<span class="attr">ctx</span>: <span class="title class_">Context</span>, <span class="attr">emitter</span>: <span class="title class_">Emitter</span>) {</span><br><span class="line"> <span class="keyword">const</span> title = <span class="keyword">await</span> <span class="title function_">toPromise</span>(<span class="variable language_">this</span>.<span class="property">value</span>.<span class="title function_">value</span>(ctx))</span><br><span class="line"> emitter.<span class="title function_">write</span>(<span class="string">`<h1><span class="subst">${title}</span></h1>`</span>)</span><br><span class="line"> }</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token keyword">import</span> <span class="token punctuation">{</span> toPromise<span class="token punctuation">,</span> TagToken<span class="token punctuation">,</span> Context<span class="token punctuation">,</span> Emitter<span class="token punctuation">,</span> TopLevelToken<span class="token punctuation">,</span> Value<span class="token punctuation">,</span> Tag<span class="token punctuation">,</span> Liquid <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'liquidjs'</span>
|
||||
|
||||
<span class="token comment">// Usage: {% upper "alice" %}</span>
|
||||
<span class="token comment">// Output: ALICE</span>
|
||||
engine<span class="token punctuation">.</span><span class="token function">registerTag</span><span class="token punctuation">(</span><span class="token string">'upper'</span><span class="token punctuation">,</span> <span class="token keyword">class</span> <span class="token class-name">UpperTag</span> <span class="token keyword">extends</span> <span class="token class-name">Tag</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">private</span> value<span class="token operator">:</span> Value
|
||||
<span class="token function">constructor</span> <span class="token punctuation">(</span>token<span class="token operator">:</span> TagToken<span class="token punctuation">,</span> remainTokens<span class="token operator">:</span> TopLevelToken<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> liquid<span class="token operator">:</span> Liquid<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">super</span><span class="token punctuation">(</span>token<span class="token punctuation">,</span> remainTokens<span class="token punctuation">,</span> liquid<span class="token punctuation">)</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>value <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Value</span><span class="token punctuation">(</span>token<span class="token punctuation">.</span>args<span class="token punctuation">,</span> liquid<span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token keyword">async</span> <span class="token function">render</span> <span class="token punctuation">(</span>ctx<span class="token operator">:</span> Context<span class="token punctuation">,</span> emitter<span class="token operator">:</span> Emitter<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">const</span> title <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">toPromise</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>value<span class="token punctuation">.</span><span class="token function">value</span><span class="token punctuation">(</span>ctx<span class="token punctuation">)</span><span class="token punctuation">)</span>
|
||||
emitter<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"><h1></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>title<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"></h1></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="drops.html" class="article-footer-prev" title="Liquid Drop"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="whitespace-control.html" class="article-footer-next" title="换行和缩进"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -226,7 +226,7 @@
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="operators.html" class="article-footer-prev" title="运算符"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="dos.html" class="article-footer-next" title="DoS"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -93,28 +93,49 @@
|
||||
</header>
|
||||
<div class="article-content" itemprop="articleBody">
|
||||
<p>LiquidJS 可以用来作为 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://expressjs.com/en/resources/template-engines.html">Express 的模板引擎</a>。可以把 Liquid 设置到 <a target="_blank" rel="noopener external nofollow noreferrer" href="http://expressjs.com/en/guide/using-template-engines.html">view engine</a> 选项上即可:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> { <span class="title class_">Liquid</span> } = <span class="built_in">require</span>(<span class="string">'liquidjs'</span>);</span><br><span class="line"><span class="keyword">var</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 注册为 liquid 文件的模板引擎</span></span><br><span class="line">app.<span class="title function_">engine</span>(<span class="string">'liquid'</span>, engine.<span class="title function_">express</span>()); </span><br><span class="line">app.<span class="title function_">set</span>(<span class="string">'views'</span>, <span class="string">'./views'</span>); <span class="comment">// 指定模板目录</span></span><br><span class="line">app.<span class="title function_">set</span>(<span class="string">'view engine'</span>, <span class="string">'liquid'</span>); <span class="comment">// 把 liquid 文件设为默认模板</span></span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> <span class="token punctuation">{</span> Liquid <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'liquidjs'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
<span class="token keyword">var</span> engine <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Liquid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
|
||||
<span class="token comment">// 注册为 liquid 文件的模板引擎</span>
|
||||
app<span class="token punctuation">.</span><span class="token function">engine</span><span class="token punctuation">(</span><span class="token string">'liquid'</span><span class="token punctuation">,</span> engine<span class="token punctuation">.</span><span class="token function">express</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
app<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'views'</span><span class="token punctuation">,</span> <span class="token string">'./views'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 指定模板目录</span>
|
||||
app<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'view engine'</span><span class="token punctuation">,</span> <span class="token string">'liquid'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 把 liquid 文件设为默认模板</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<blockquote class="note info"><strong class="note-title">示例</strong><p>这是一个在 Express.js 中使用 LiquidJS 的例子:<a href="https://github.com/harttle/liquidjs/blob/master/demo/express/" rel="external nofollow noreferrer" target="_blank">liquidjs/demo/express/</a>.</p>
|
||||
</blockquote>
|
||||
|
||||
<h2 id="模板查找" class="article-heading"><a href="#模板查找" class="headerlink" title="模板查找"></a>模板查找<a class="article-anchor" href="#模板查找" aria-hidden="true"></a></h2><p>LiquidJS 仍然会去 <a href="/api/interfaces/LiquidOptions.html#root">root</a> 指定的目录查找(参考 <a href="./render-a-file.html">Render A Template File</a>),也会去 Express.js 的 <a target="_blank" rel="noopener external nofollow noreferrer" href="http://expressjs.com/en/guide/using-template-engines.html"><code>views</code></a> 选项指定的目录里(上述例子中是 <code>./views</code>)去查找。例如你有这样的目录结构:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">.</span><br><span class="line">├── views1/</span><br><span class="line">│ └── hello.liquid</span><br><span class="line">└── views2/</span><br><span class="line"> └── world.liquid</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-none"><code class="language-none">.
|
||||
├── views1/
|
||||
│ └── hello.liquid
|
||||
└── views2/
|
||||
└── world.liquid<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>LiquidJS 的模板 root 设置到了 <code>views1</code>,Express.js 的 views 设置到了 <code>views2</code>:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> { <span class="title class_">Liquid</span> } = <span class="built_in">require</span>(<span class="string">'liquidjs'</span>);</span><br><span class="line"><span class="keyword">var</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>({</span><br><span class="line"> <span class="attr">root</span>: <span class="string">'./views1/'</span></span><br><span class="line">});</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">engine</span>(<span class="string">'liquid'</span>, engine.<span class="title function_">express</span>()); </span><br><span class="line">app.<span class="title function_">set</span>(<span class="string">'views'</span>, <span class="string">'./views2'</span>);</span><br><span class="line">app.<span class="title function_">set</span>(<span class="string">'view engine'</span>, <span class="string">'liquid'</span>);</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> <span class="token punctuation">{</span> Liquid <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'liquidjs'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
<span class="token keyword">var</span> engine <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Liquid</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
|
||||
<span class="token literal-property property">root</span><span class="token operator">:</span> <span class="token string">'./views1/'</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
|
||||
app<span class="token punctuation">.</span><span class="token function">engine</span><span class="token punctuation">(</span><span class="token string">'liquid'</span><span class="token punctuation">,</span> engine<span class="token punctuation">.</span><span class="token function">express</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
app<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'views'</span><span class="token punctuation">,</span> <span class="token string">'./views2'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
app<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">'view engine'</span><span class="token punctuation">,</span> <span class="token string">'liquid'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p><code>hello.liquid</code> 和 <code>world.liquid</code> 两个文件都可以找到并且成功渲染:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">res.<span class="title function_">render</span>(<span class="string">'hello'</span>)</span><br><span class="line">res.<span class="title function_">render</span>(<span class="string">'world'</span>)</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">res<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span><span class="token string">'hello'</span><span class="token punctuation">)</span>
|
||||
res<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span><span class="token string">'world'</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
|
||||
|
||||
<h2 id="缓存" class="article-heading"><a href="#缓存" class="headerlink" title="缓存"></a>缓存<a class="article-anchor" href="#缓存" aria-hidden="true"></a></h2><p>直接把 <a href="/api/interfaces/LiquidOptions.html#cache">cache 选项</a> 设为 <code>true</code> 即可开启模板缓存,参考 <a href="./caching.html">缓存</a> 一文。推荐在生产环境中开启缓存,可以用如下代码:</p>
|
||||
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> { <span class="title class_">Liquid</span> } = <span class="built_in">require</span>(<span class="string">'liquidjs'</span>);</span><br><span class="line"><span class="keyword">var</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>({</span><br><span class="line"> <span class="attr">cache</span>: process.<span class="property">env</span>.<span class="property">NODE_ENV</span> === <span class="string">'production'</span></span><br><span class="line">});</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> <span class="token punctuation">{</span> Liquid <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'liquidjs'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
||||
<span class="token keyword">var</span> engine <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Liquid</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
|
||||
<span class="token literal-property property">cache</span><span class="token operator">:</span> process<span class="token punctuation">.</span>env<span class="token punctuation">.</span><span class="token constant">NODE_ENV</span> <span class="token operator">===</span> <span class="token string">'production'</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
|
||||
|
||||
<p><code>cache</code> 还可以是一个数字表示最大缓存的模板数量,也可以是一个自定义的缓存实现,详情请参考 <a href="/api/interfaces/LiquidOptions.html#cache">cache 选项</a>。</p>
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="partials-and-layouts.html" class="article-footer-prev" title="引用/继承"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="caching.html" class="article-footer-next" title="缓存"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -94,16 +94,19 @@
|
||||
<div class="article-content" itemprop="articleBody">
|
||||
<p>为了让源代码缩进好看,我们会加很多空白字符比如把不会产生输出的标签也单独一行。LiquidJS 提供了空白字符控制机制,可以避免这些多余的空白字符输出到 HTML 中。</p>
|
||||
<h2 id="通过标记的方式" class="article-heading"><a href="#通过标记的方式" class="headerlink" title="通过标记的方式"></a>通过标记的方式<a class="article-anchor" href="#通过标记的方式" aria-hidden="true"></a></h2><p>默认所有标签和输出的行,都会在行尾产生一个换行(<code>\n</code>),如果有缩进的话还会产生很多前导空格。例如:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">{% author = "harttle" %}</span><br><span class="line">{{ author }}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> author <span class="token operator">=</span> <span class="token string">"harttle"</span> <span class="token delimiter punctuation">%}</span></span>
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{{</span> author <span class="token delimiter punctuation">}}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>将会输出(注意前面的空行):</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">harttle</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-none"><code class="language-none">
|
||||
harttle<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>可以在标签和输出的标记里面加横线(<code>{{-</code>, <code>-}}</code>, <code>{%-</code>, <code>-%}</code>)来移除左侧/右侧的空白。例如:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">{% assign author = "harttle" -%}</span><br><span class="line">{{ author }}</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span> <span class="token keyword">assign</span> author <span class="token operator">=</span> <span class="token string">"harttle"</span> <span class="token delimiter punctuation">-%}</span></span>
|
||||
<span class="token liquid language-liquid"><span class="token delimiter punctuation">{{</span> author <span class="token delimiter punctuation">}}</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
|
||||
|
||||
<p>将会输出:</p>
|
||||
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">harttle</span><br></pre></td></tr></table></figure>
|
||||
<pre class="line-numbers language-none"><code class="language-none">harttle<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
|
||||
|
||||
<p>这个例子中 <code>-%}</code> 移除了 <code>assign</code> 标签右侧的空白。</p>
|
||||
<h2 id="通过选项" class="article-heading"><a href="#通过选项" class="headerlink" title="通过选项"></a>通过选项<a class="article-anchor" href="#通过选项" aria-hidden="true"></a></h2><p>此外 LiquidJS 还提供了一系列选项来帮助扫代码式地移除空白:</p>
|
||||
@@ -118,7 +121,7 @@
|
||||
|
||||
</div>
|
||||
<footer class="article-footer">
|
||||
<time class="article-footer-updated" datetime="2024-08-19T19:36:26.430Z" itemprop="dateModified">上次更新:2024-08-19</time>
|
||||
<time class="article-footer-updated" datetime="2024-08-20T01:26:05.768Z" itemprop="dateModified">上次更新:2024-08-20</time>
|
||||
<a href="sync-and-async.html" class="article-footer-prev" title="同步和异步"><i class="icon-chevron-left"></i><span>上一页</span></a><a href="plugins.html" class="article-footer-next" title="插件"><span>下一页</span><i class="icon-chevron-right"></i></a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user