Deploying to gh-pages from @ harttle/liquidjs@e941378535 🚀

This commit is contained in:
harttle
2024-08-16 16:56:29 +00:00
parent 6c9d227f92
commit fbd1c14cb8
422 changed files with 6202 additions and 17559 deletions
+4 -13
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -93,19 +93,10 @@
</header>
<div class="article-content" itemprop="articleBody">
<p>As covered in <a href="/tutorials/register-filters-tags.html">Register Filters/Tags</a>, we can access filter arguments directly in filter function like:</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// Usage: &#123;&#123; 1 | add: 2, 3 &#125;&#125;</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>
<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: &#123;&#123; 1 | add: 2, 3 &#125;&#125;</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">&#x27;add&#x27;</span>, <span class="function">(<span class="params">initial, arg1, arg2</span>) =&gt;</span> initial + arg1 + arg2)</span><br></pre></td></tr></table></figure>
<p>When it comes to stateful filters, for example transform a URL path to full URL, well need to access a <code>origin</code> in current scope:</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// Usage: &#123;&#123; '/index.html' | fullURL &#125;&#125;</span>
<span class="token comment">// Scope: &#123; origin: "https://liquidjs.com" &#125;</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">&#123;</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">&#125;</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>
<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: &#123;&#123; &#x27;/index.html&#x27; | fullURL &#125;&#125;</span></span><br><span class="line"><span class="comment">// Scope: &#123; origin: &quot;https://liquidjs.com&quot; &#125;</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">&#x27;fullURL&#x27;</span>, <span class="keyword">function</span> (<span class="params">path</span>) &#123;</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">&#x27;origin&#x27;</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">&#125;)</span><br></pre></td></tr></table></figure>
<p>See this JSFiddle: <a target="_blank" rel="noopener external nofollow noreferrer" href="https://jsfiddle.net/ctj364up/1/">https://jsfiddle.net/ctj364up/1/</a></p>
<blockquote class="note warn"><strong class="note-title">Arrow Functions</strong><p><code>this</code> in arrow functions is bound to current JavaScript context, youll need to use <code>function()&#123;&#125;</code> instead of <code>()=>&#123;&#125;</code> syntax to access <code>this.context</code> correctly.</p>
@@ -114,7 +105,7 @@ engine<span class="token punctuation">.</span><span class="token function">regis
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.834Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="register-filters-tags.html" class="article-footer-prev" title="Register Filters/Tags"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="parse-parameters.html" class="article-footer-next" title="Parse Parameters"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+5 -20
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -96,34 +96,19 @@
<p>LiquidJS provides multiple ways to cache the parsed templates to improve performance.</p>
<h2 id="Programmatically" class="article-heading"><a href="#Programmatically" class="headerlink" title="Programmatically"></a>Programmatically<a class="article-anchor" href="#Programmatically" aria-hidden="true"></a></h2><p>The <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> APIs are used to parse templates from string or files. The result template can be then rendered multiple times with different context.</p>
<p>Parse from string:</p>
<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">'&#123;&#123;name | capitalize&#125;&#125;'</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">&#123;</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'alice'</span><span class="token punctuation">&#125;</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">&#123;</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'bob'</span><span class="token punctuation">&#125;</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>
<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">&#x27;&#123;&#123;name | capitalize&#125;&#125;&#x27;</span>);</span><br><span class="line"></span><br><span class="line">engine.<span class="title function_">renderSync</span>(tpl, &#123;<span class="attr">name</span>: <span class="string">&#x27;alice&#x27;</span>&#125;) <span class="comment">// &#x27;Alice&#x27;</span></span><br><span class="line">engine.<span class="title function_">renderSync</span>(tpl, &#123;<span class="attr">name</span>: <span class="string">&#x27;bob&#x27;</span>&#125;) <span class="comment">// &#x27;Bob&#x27;</span></span><br></pre></td></tr></table></figure>
<p>Parse from file:</p>
<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`: &#123;&#123;name&#125;&#125;</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">&#123;</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'alice'</span><span class="token punctuation">&#125;</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">&#123;</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'bob'</span><span class="token punctuation">&#125;</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>
<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">&#x27;hello&#x27;</span>); <span class="comment">// contents of `hello.liquid`: &#123;&#123;name&#125;&#125;</span></span><br><span class="line"></span><br><span class="line">engine.<span class="title function_">renderSync</span>(tpl, &#123;<span class="attr">name</span>: <span class="string">&#x27;alice&#x27;</span>&#125;) <span class="comment">// &#x27;Alice&#x27;</span></span><br><span class="line">engine.<span class="title function_">renderSync</span>(tpl, &#123;<span class="attr">name</span>: <span class="string">&#x27;bob&#x27;</span>&#125;) <span class="comment">// &#x27;Bob&#x27;</span></span><br></pre></td></tr></table></figure>
<p>The template string/file is parsed only once and rendered multiple times using different context. Templates for different files can be stored into a <code>Map</code> and can be retrieved directly for subsequent renders.</p>
<h2 id="The-cache-Option" class="article-heading"><a href="#The-cache-Option" class="headerlink" title="The cache Option"></a>The <code>cache</code> Option<a class="article-anchor" href="#The-cache-Option" aria-hidden="true"></a></h2><p>The <a href="/api/interfaces/LiquidOptions.html#cache">cache option</a> can be set to instruct liquidjs to use cached parsed templates each time you call <a href="/api/classes/Liquid.html#renderFile">renderFile</a> or <a href="/api/classes/Liquid.html#renderFileSync">renderFileSync</a>.</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> <span class="token punctuation">&#123;</span> Liquid <span class="token punctuation">&#125;</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">&#123;</span>
<span class="token literal-property property">cache</span><span class="token operator">:</span> <span class="token boolean">true</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// liquidjs parses the hello.liquid, then renders it with &#123;name: 'alice'&#125;</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">&#123;</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'alice'</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token comment">// liquidjs finds the cached template, then renders it with &#123;name: 'bob'&#125;</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">&#123;</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'bob'</span><span class="token punctuation">&#125;</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>
<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> &#123; <span class="title class_">Liquid</span> &#125; = <span class="built_in">require</span>(<span class="string">&#x27;liquidjs&#x27;</span>);</span><br><span class="line"><span class="keyword">var</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>(&#123;</span><br><span class="line"> <span class="attr">cache</span>: <span class="literal">true</span></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// liquidjs parses the hello.liquid, then renders it with &#123;name: &#x27;alice&#x27;&#125;</span></span><br><span class="line">engine.<span class="title function_">renderFileSync</span>(<span class="string">&#x27;hello&#x27;</span>, &#123;<span class="attr">name</span>: <span class="string">&#x27;alice&#x27;</span>&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// liquidjs finds the cached template, then renders it with &#123;name: &#x27;bob&#x27;&#125;</span></span><br><span class="line">engine.<span class="title function_">renderFileSync</span>(<span class="string">&#x27;hello&#x27;</span>, &#123;<span class="attr">name</span>: <span class="string">&#x27;bob&#x27;</span>&#125;)</span><br></pre></td></tr></table></figure>
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.834Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="use-in-expressjs.html" class="article-footer-prev" title="Use in Express.js"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="escaping.html" class="article-footer-next" title="Escaping"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+89 -105
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -468,93 +468,77 @@
<li>allow string literals contain delimiters, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/288">#288</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/9c40da7">9c40da7</a>)</li>
</ul>
<h1 id="9-20-0-2021-01-23"><a href="#9-20-0-2021-01-23" class="headerlink" title="9.20.0 (2021-01-23)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.19.0...v9.20.0">9.20.0</a> (2021-01-23)</h1><h3 id="Features-39"><a href="#Features-39" class="headerlink" title="Features"></a>Features</h3><ul>
<li>support `{{block.super}}`, see [#38](https://github.com/harttle/liquidjs/issues/38) ([a3af44d](https://github.com/harttle/liquidjs/commit/a3af44d))
# [9.19.0](https://github.com/harttle/liquidjs/compare/v9.18.0...v9.19.0) (2020-12-18)
### Bug Fixes
* lint ([de32259](https://github.com/harttle/liquidjs/commit/de32259))
* move offset adding complexity inside TimezoneDate ([26b2175](https://github.com/harttle/liquidjs/commit/26b2175))
* simpler timezone regex and non-null offset ([e3ecfe3](https://github.com/harttle/liquidjs/commit/e3ecfe3))
### Features
* add preserveTimezones option ([d70cd2a](https://github.com/harttle/liquidjs/commit/d70cd2a))
* parse and handle date timezone offsets ([c16c787](https://github.com/harttle/liquidjs/commit/c16c787))
# [9.18.0](https://github.com/harttle/liquidjs/compare/v9.17.0...v9.18.0) (2020-12-17)
### Bug Fixes
* address refactor comments ([6a0ad10](https://github.com/harttle/liquidjs/commit/6a0ad10))
### Features
* add option for keeping variable type in output ([cd92e77](https://github.com/harttle/liquidjs/commit/cd92e77))
# [9.17.0](https://github.com/harttle/liquidjs/compare/v9.16.1...v9.17.0) (2020-12-07)
### Bug Fixes
* elsif is not supported for unless, fixes [#268](https://github.com/harttle/liquidjs/issues/268) ([2bbf501](https://github.com/harttle/liquidjs/commit/2bbf501))
* enforce string-type pattern in `replace`, fixes [#243](https://github.com/harttle/liquidjs/issues/243) ([c8afa39](https://github.com/harttle/liquidjs/commit/c8afa39))
* raw block not ignoring {% characters, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/263">#263</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/a492d8e">a492d8e</a>)</li>
<li>support <code>{{block.super}}</code>, see <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/38">#38</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/a3af44d">a3af44d</a>)</li>
</ul>
<h1 id="9-19-0-2020-12-18"><a href="#9-19-0-2020-12-18" class="headerlink" title="9.19.0 (2020-12-18)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.18.0...v9.19.0">9.19.0</a> (2020-12-18)</h1><h3 id="Bug-Fixes-62"><a href="#Bug-Fixes-62" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>lint (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/de32259">de32259</a>)</li>
<li>move offset adding complexity inside TimezoneDate (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/26b2175">26b2175</a>)</li>
<li>simpler timezone regex and non-null offset (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/e3ecfe3">e3ecfe3</a>)</li>
</ul>
<h3 id="Features-40"><a href="#Features-40" class="headerlink" title="Features"></a>Features</h3><ul>
<li>add preserveTimezones option (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/d70cd2a">d70cd2a</a>)</li>
<li>parse and handle date timezone offsets (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/c16c787">c16c787</a>)</li>
</ul>
<h1 id="9-18-0-2020-12-17"><a href="#9-18-0-2020-12-17" class="headerlink" title="9.18.0 (2020-12-17)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.17.0...v9.18.0">9.18.0</a> (2020-12-17)</h1><h3 id="Bug-Fixes-63"><a href="#Bug-Fixes-63" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>address refactor comments (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/6a0ad10">6a0ad10</a>)</li>
</ul>
<h3 id="Features-41"><a href="#Features-41" class="headerlink" title="Features"></a>Features</h3><ul>
<li>add option for keeping variable type in output (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/cd92e77">cd92e77</a>)</li>
</ul>
<h1 id="9-17-0-2020-12-07"><a href="#9-17-0-2020-12-07" class="headerlink" title="9.17.0 (2020-12-07)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.16.1...v9.17.0">9.17.0</a> (2020-12-07)</h1><h3 id="Bug-Fixes-64"><a href="#Bug-Fixes-64" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>elsif is not supported for unless, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/268">#268</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/2bbf501">2bbf501</a>)</li>
<li>enforce string-type pattern in <code>replace</code>, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/243">#243</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/c8afa39">c8afa39</a>)</li>
<li>raw block not ignoring {% characters, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/263">#263</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/a492d8e">a492d8e</a>)</li>
</ul>
<h3 id="Features-42"><a href="#Features-42" class="headerlink" title="Features"></a>Features</h3><ul>
<li>passing liquid to FilterImpl, closes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/277">#277</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/f9f595f">f9f595f</a>)</li>
</ul>
<h2 id="9-16-1-2020-10-09"><a href="#9-16-1-2020-10-09" class="headerlink" title="9.16.1 (2020-10-09)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.16.0...v9.16.1">9.16.1</a> (2020-10-09)</h2><h3 id="Bug-Fixes-62"><a href="#Bug-Fixes-62" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-16-1-2020-10-09"><a href="#9-16-1-2020-10-09" class="headerlink" title="9.16.1 (2020-10-09)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.16.0...v9.16.1">9.16.1</a> (2020-10-09)</h2><h3 id="Bug-Fixes-65"><a href="#Bug-Fixes-65" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>braced property access (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/18a807e">18a807e</a>)</li>
</ul>
<h1 id="9-16-0-2020-10-08"><a href="#9-16-0-2020-10-08" class="headerlink" title="9.16.0 (2020-10-08)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.15.1...v9.16.0">9.16.0</a> (2020-10-08)</h1><h3 id="Features-41"><a href="#Features-41" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="9-16-0-2020-10-08"><a href="#9-16-0-2020-10-08" class="headerlink" title="9.16.0 (2020-10-08)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.15.1...v9.16.0">9.16.0</a> (2020-10-08)</h1><h3 id="Features-43"><a href="#Features-43" class="headerlink" title="Features"></a>Features</h3><ul>
<li>support jsTruthy, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/255">#255</a> <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/257">#257</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/72ee7b4">72ee7b4</a>)</li>
</ul>
<h2 id="9-15-1-2020-10-03"><a href="#9-15-1-2020-10-03" class="headerlink" title="9.15.1 (2020-10-03)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.15.0...v9.15.1">9.15.1</a> (2020-10-03)</h2><h3 id="Bug-Fixes-63"><a href="#Bug-Fixes-63" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-15-1-2020-10-03"><a href="#9-15-1-2020-10-03" class="headerlink" title="9.15.1 (2020-10-03)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.15.0...v9.15.1">9.15.1</a> (2020-10-03)</h2><h3 id="Bug-Fixes-66"><a href="#Bug-Fixes-66" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>allow quoted variable name in capture, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/252">#252</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/5b3f419">5b3f419</a>)</li>
</ul>
<h1 id="9-15-0-2020-08-04"><a href="#9-15-0-2020-08-04" class="headerlink" title="9.15.0 (2020-08-04)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.14.1...v9.15.0">9.15.0</a> (2020-08-04)</h1><h3 id="Features-42"><a href="#Features-42" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="9-15-0-2020-08-04"><a href="#9-15-0-2020-08-04" class="headerlink" title="9.15.0 (2020-08-04)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.14.1...v9.15.0">9.15.0</a> (2020-08-04)</h1><h3 id="Features-44"><a href="#Features-44" class="headerlink" title="Features"></a>Features</h3><ul>
<li>export toPromise and toValue, see <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/158">#158</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/2e5ab98">2e5ab98</a>)</li>
</ul>
<h2 id="9-14-1-2020-07-08"><a href="#9-14-1-2020-07-08" class="headerlink" title="9.14.1 (2020-07-08)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.14.0...v9.14.1">9.14.1</a> (2020-07-08)</h2><h3 id="Bug-Fixes-64"><a href="#Bug-Fixes-64" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-14-1-2020-07-08"><a href="#9-14-1-2020-07-08" class="headerlink" title="9.14.1 (2020-07-08)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.14.0...v9.14.1">9.14.1</a> (2020-07-08)</h2><h3 id="Bug-Fixes-67"><a href="#Bug-Fixes-67" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>enumerate Promises (e.g. in for & tablerow) (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/237">#237</a>) (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/941dd66">941dd66</a>)</li>
</ul>
<h1 id="9-14-0-2020-06-25"><a href="#9-14-0-2020-06-25" class="headerlink" title="9.14.0 (2020-06-25)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.13.0...v9.14.0">9.14.0</a> (2020-06-25)</h1><h3 id="Features-43"><a href="#Features-43" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="9-14-0-2020-06-25"><a href="#9-14-0-2020-06-25" class="headerlink" title="9.14.0 (2020-06-25)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.13.0...v9.14.0">9.14.0</a> (2020-06-25)</h1><h3 id="Features-45"><a href="#Features-45" class="headerlink" title="Features"></a>Features</h3><ul>
<li>setup universal browser and node builds (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/6cf6ffa">6cf6ffa</a>)</li>
</ul>
<h1 id="9-13-0-2020-06-25"><a href="#9-13-0-2020-06-25" class="headerlink" title="9.13.0 (2020-06-25)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.12.0...v9.13.0">9.13.0</a> (2020-06-25)</h1><h3 id="Features-44"><a href="#Features-44" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="9-13-0-2020-06-25"><a href="#9-13-0-2020-06-25" class="headerlink" title="9.13.0 (2020-06-25)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.12.0...v9.13.0">9.13.0</a> (2020-06-25)</h1><h3 id="Features-46"><a href="#Features-46" class="headerlink" title="Features"></a>Features</h3><ul>
<li>async filters, closes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/232">#232</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/e36f3ff">e36f3ff</a>)</li>
</ul>
<h1 id="9-12-0-2020-05-15"><a href="#9-12-0-2020-05-15" class="headerlink" title="9.12.0 (2020-05-15)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.11...v9.12.0">9.12.0</a> (2020-05-15)</h1><h3 id="Features-45"><a href="#Features-45" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="9-12-0-2020-05-15"><a href="#9-12-0-2020-05-15" class="headerlink" title="9.12.0 (2020-05-15)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.11...v9.12.0">9.12.0</a> (2020-05-15)</h1><h3 id="Features-47"><a href="#Features-47" class="headerlink" title="Features"></a>Features</h3><ul>
<li>sort by key, see <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/227">#227</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/4f17c94">4f17c94</a>)</li>
</ul>
<h2 id="9-11-11-2020-05-01"><a href="#9-11-11-2020-05-01" class="headerlink" title="9.11.11 (2020-05-01)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.10...v9.11.11">9.11.11</a> (2020-05-01)</h2><h3 id="Bug-Fixes-65"><a href="#Bug-Fixes-65" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-11-11-2020-05-01"><a href="#9-11-11-2020-05-01" class="headerlink" title="9.11.11 (2020-05-01)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.10...v9.11.11">9.11.11</a> (2020-05-01)</h2><h3 id="Bug-Fixes-68"><a href="#Bug-Fixes-68" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>properly treat unicode blanks, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/221">#221</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/673b015">673b015</a>)</li>
</ul>
<h2 id="9-11-10-2020-04-03"><a href="#9-11-10-2020-04-03" class="headerlink" title="9.11.10 (2020-04-03)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.9...v9.11.10">9.11.10</a> (2020-04-03)</h2><h3 id="Bug-Fixes-66"><a href="#Bug-Fixes-66" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-11-10-2020-04-03"><a href="#9-11-10-2020-04-03" class="headerlink" title="9.11.10 (2020-04-03)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.9...v9.11.10">9.11.10</a> (2020-04-03)</h2><h3 id="Bug-Fixes-69"><a href="#Bug-Fixes-69" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>respect cache render options (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/a93f11d">a93f11d</a>)</li>
</ul>
<h2 id="9-11-9-2020-03-31"><a href="#9-11-9-2020-03-31" class="headerlink" title="9.11.9 (2020-03-31)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.8...v9.11.9">9.11.9</a> (2020-03-31)</h2><h3 id="Bug-Fixes-67"><a href="#Bug-Fixes-67" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-11-9-2020-03-31"><a href="#9-11-9-2020-03-31" class="headerlink" title="9.11.9 (2020-03-31)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.8...v9.11.9">9.11.9</a> (2020-03-31)</h2><h3 id="Bug-Fixes-70"><a href="#Bug-Fixes-70" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>coerce to Array in <code>map</code> and <code>where</code> filter (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/c923598">c923598</a>)</li>
</ul>
<h2 id="9-11-8-2020-03-31"><a href="#9-11-8-2020-03-31" class="headerlink" title="9.11.8 (2020-03-31)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.7...v9.11.8">9.11.8</a> (2020-03-31)</h2><h3 id="Bug-Fixes-68"><a href="#Bug-Fixes-68" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-11-8-2020-03-31"><a href="#9-11-8-2020-03-31" class="headerlink" title="9.11.8 (2020-03-31)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.7...v9.11.8">9.11.8</a> (2020-03-31)</h2><h3 id="Bug-Fixes-71"><a href="#Bug-Fixes-71" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>throw an error if : omitted unintentionally, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/212">#212</a>, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/208">#208</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/8daf281">8daf281</a>)</li>
</ul>
<h2 id="9-11-7-2020-03-28"><a href="#9-11-7-2020-03-28" class="headerlink" title="9.11.7 (2020-03-28)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.6...v9.11.7">9.11.7</a> (2020-03-28)</h2><h3 id="Bug-Fixes-69"><a href="#Bug-Fixes-69" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-11-7-2020-03-28"><a href="#9-11-7-2020-03-28" class="headerlink" title="9.11.7 (2020-03-28)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.6...v9.11.7">9.11.7</a> (2020-03-28)</h2><h3 id="Bug-Fixes-72"><a href="#Bug-Fixes-72" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>try fix travis (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/b3db412">b3db412</a>)</li>
</ul>
<h2 id="9-11-6-2020-03-25"><a href="#9-11-6-2020-03-25" class="headerlink" title="9.11.6 (2020-03-25)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.5...v9.11.6">9.11.6</a> (2020-03-25)</h2><h3 id="Bug-Fixes-70"><a href="#Bug-Fixes-70" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-11-6-2020-03-25"><a href="#9-11-6-2020-03-25" class="headerlink" title="9.11.6 (2020-03-25)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.5...v9.11.6">9.11.6</a> (2020-03-25)</h2><h3 id="Bug-Fixes-73"><a href="#Bug-Fixes-73" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>default filter not applied for empty array (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/c371762">c371762</a>)</li>
</ul>
<h2 id="9-11-5-2020-03-24"><a href="#9-11-5-2020-03-24" class="headerlink" title="9.11.5 (2020-03-24)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.4...v9.11.5">9.11.5</a> (2020-03-24)</h2><h3 id="Bug-Fixes-71"><a href="#Bug-Fixes-71" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-11-5-2020-03-24"><a href="#9-11-5-2020-03-24" class="headerlink" title="9.11.5 (2020-03-24)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.4...v9.11.5">9.11.5</a> (2020-03-24)</h2><h3 id="Bug-Fixes-74"><a href="#Bug-Fixes-74" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>throws on invalid arguments for prepend/append, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/208">#208</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/479c633">479c633</a>)</li>
</ul>
<h2 id="9-11-4-2020-03-23"><a href="#9-11-4-2020-03-23" class="headerlink" title="9.11.4 (2020-03-23)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.3...v9.11.4">9.11.4</a> (2020-03-23)</h2><h3 id="Bug-Fixes-72"><a href="#Bug-Fixes-72" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-11-4-2020-03-23"><a href="#9-11-4-2020-03-23" class="headerlink" title="9.11.4 (2020-03-23)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.3...v9.11.4">9.11.4</a> (2020-03-23)</h2><h3 id="Bug-Fixes-75"><a href="#Bug-Fixes-75" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>return variable name in include error (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/93433a8">93433a8</a>)</li>
</ul>
<h2 id="9-11-3-2020-03-14"><a href="#9-11-3-2020-03-14" class="headerlink" title="9.11.3 (2020-03-14)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.2...v9.11.3">9.11.3</a> (2020-03-14)</h2><h3 id="Performance-Improvements-4"><a href="#Performance-Improvements-4" class="headerlink" title="Performance Improvements"></a>Performance Improvements</h3><ul>
@@ -564,82 +548,82 @@
<h2 id="9-11-2-2020-03-14"><a href="#9-11-2-2020-03-14" class="headerlink" title="9.11.2 (2020-03-14)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.1...v9.11.2">9.11.2</a> (2020-03-14)</h2><h3 id="Performance-Improvements-5"><a href="#Performance-Improvements-5" class="headerlink" title="Performance Improvements"></a>Performance Improvements</h3><ul>
<li>remove transient strings to reduce memory (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/3dfdf98">3dfdf98</a>)</li>
</ul>
<h2 id="9-11-1-2020-03-09"><a href="#9-11-1-2020-03-09" class="headerlink" title="9.11.1 (2020-03-09)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.0...v9.11.1">9.11.1</a> (2020-03-09)</h2><h3 id="Bug-Fixes-73"><a href="#Bug-Fixes-73" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-11-1-2020-03-09"><a href="#9-11-1-2020-03-09" class="headerlink" title="9.11.1 (2020-03-09)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.11.0...v9.11.1">9.11.1</a> (2020-03-09)</h2><h3 id="Bug-Fixes-76"><a href="#Bug-Fixes-76" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>concurrent write on LRU cache (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/200">#200</a>) (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/6de9338">6de9338</a>)</li>
</ul>
<h1 id="9-11-0-2020-03-04"><a href="#9-11-0-2020-03-04" class="headerlink" title="9.11.0 (2020-03-04)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.10.0...v9.11.0">9.11.0</a> (2020-03-04)</h1><h3 id="Bug-Fixes-74"><a href="#Bug-Fixes-74" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h1 id="9-11-0-2020-03-04"><a href="#9-11-0-2020-03-04" class="headerlink" title="9.11.0 (2020-03-04)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.10.0...v9.11.0">9.11.0</a> (2020-03-04)</h1><h3 id="Bug-Fixes-77"><a href="#Bug-Fixes-77" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li><code>Buffer not defined</code> for browser bundles, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/197">#197</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/65b849c">65b849c</a>)</li>
<li>stable sort for undefined keys, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/191">#191</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/f57156b">f57156b</a>)</li>
</ul>
<h3 id="Features-46"><a href="#Features-46" class="headerlink" title="Features"></a>Features</h3><ul>
<h3 id="Features-48"><a href="#Features-48" class="headerlink" title="Features"></a>Features</h3><ul>
<li>async cache.read()/write(), remove .has() (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/61dac49">61dac49</a>)</li>
</ul>
<h1 id="9-10-0-2020-03-03"><a href="#9-10-0-2020-03-03" class="headerlink" title="9.10.0 (2020-03-03)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.9.0...v9.10.0">9.10.0</a> (2020-03-03)</h1><h3 id="Features-47"><a href="#Features-47" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="9-10-0-2020-03-03"><a href="#9-10-0-2020-03-03" class="headerlink" title="9.10.0 (2020-03-03)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.9.0...v9.10.0">9.10.0</a> (2020-03-03)</h1><h3 id="Features-49"><a href="#Features-49" class="headerlink" title="Features"></a>Features</h3><ul>
<li>support json filter, closes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/192">#192</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/aa27a6c">aa27a6c</a>)</li>
<li>with & for in <code>render</code> tag, closes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/195">#195</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/6ea6881">6ea6881</a>)</li>
</ul>
<h1 id="9-9-0-2020-03-02"><a href="#9-9-0-2020-03-02" class="headerlink" title="9.9.0 (2020-03-02)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.8.0...v9.9.0">9.9.0</a> (2020-03-02)</h1><h3 id="Features-48"><a href="#Features-48" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="9-9-0-2020-03-02"><a href="#9-9-0-2020-03-02" class="headerlink" title="9.9.0 (2020-03-02)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.8.0...v9.9.0">9.9.0</a> (2020-03-02)</h1><h3 id="Features-50"><a href="#Features-50" class="headerlink" title="Features"></a>Features</h3><ul>
<li>move filters/tags to instances, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/188">#188</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/df8a919">df8a919</a>)</li>
</ul>
<h1 id="9-8-0-2020-02-20"><a href="#9-8-0-2020-02-20" class="headerlink" title="9.8.0 (2020-02-20)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.7.2...v9.8.0">9.8.0</a> (2020-02-20)</h1><h3 id="Features-49"><a href="#Features-49" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="9-8-0-2020-02-20"><a href="#9-8-0-2020-02-20" class="headerlink" title="9.8.0 (2020-02-20)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.7.2...v9.8.0">9.8.0</a> (2020-02-20)</h1><h3 id="Features-51"><a href="#Features-51" class="headerlink" title="Features"></a>Features</h3><ul>
<li>"today" when using date filter, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/193">#193</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/185312d">185312d</a>)</li>
</ul>
<h2 id="9-7-2-2020-02-20"><a href="#9-7-2-2020-02-20" class="headerlink" title="9.7.2 (2020-02-20)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.7.1...v9.7.2">9.7.2</a> (2020-02-20)</h2><h3 id="Bug-Fixes-75"><a href="#Bug-Fixes-75" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-7-2-2020-02-20"><a href="#9-7-2-2020-02-20" class="headerlink" title="9.7.2 (2020-02-20)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.7.1...v9.7.2">9.7.2</a> (2020-02-20)</h2><h3 id="Bug-Fixes-78"><a href="#Bug-Fixes-78" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>add funding entry to show up in npm fund command (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/40095a8">40095a8</a>)</li>
</ul>
<h2 id="9-7-1-2020-02-19"><a href="#9-7-1-2020-02-19" class="headerlink" title="9.7.1 (2020-02-19)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.7.0...v9.7.1">9.7.1</a> (2020-02-19)</h2><h3 id="Bug-Fixes-76"><a href="#Bug-Fixes-76" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-7-1-2020-02-19"><a href="#9-7-1-2020-02-19" class="headerlink" title="9.7.1 (2020-02-19)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.7.0...v9.7.1">9.7.1</a> (2020-02-19)</h2><h3 id="Bug-Fixes-79"><a href="#Bug-Fixes-79" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>update index.html (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/22386b0">22386b0</a>)</li>
</ul>
<h1 id="9-7-0-2020-02-07"><a href="#9-7-0-2020-02-07" class="headerlink" title="9.7.0 (2020-02-07)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.6.2...v9.7.0">9.7.0</a> (2020-02-07)</h1><h3 id="Bug-Fixes-77"><a href="#Bug-Fixes-77" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h1 id="9-7-0-2020-02-07"><a href="#9-7-0-2020-02-07" class="headerlink" title="9.7.0 (2020-02-07)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.6.2...v9.7.0">9.7.0</a> (2020-02-07)</h1><h3 id="Bug-Fixes-80"><a href="#Bug-Fixes-80" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>expression and string literal parser, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/186">#186</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/fc0cf6f">fc0cf6f</a>)</li>
</ul>
<h3 id="Features-50"><a href="#Features-50" class="headerlink" title="Features"></a>Features</h3><ul>
<h3 id="Features-52"><a href="#Features-52" class="headerlink" title="Features"></a>Features</h3><ul>
<li>globals shared between tags, see <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/185">#185</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/870e7ec">870e7ec</a>)</li>
</ul>
<h2 id="9-6-2-2020-01-10"><a href="#9-6-2-2020-01-10" class="headerlink" title="9.6.2 (2020-01-10)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.6.1...v9.6.2">9.6.2</a> (2020-01-10)</h2><h3 id="Performance-Improvements-6"><a href="#Performance-Improvements-6" class="headerlink" title="Performance Improvements"></a>Performance Improvements</h3><ul>
<li>prevent multiple case evaluations (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/807e840">807e840</a>)</li>
</ul>
<h2 id="9-6-1-2020-01-04"><a href="#9-6-1-2020-01-04" class="headerlink" title="9.6.1 (2020-01-04)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.6.0...v9.6.1">9.6.1</a> (2020-01-04)</h2><h3 id="Bug-Fixes-78"><a href="#Bug-Fixes-78" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-6-1-2020-01-04"><a href="#9-6-1-2020-01-04" class="headerlink" title="9.6.1 (2020-01-04)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.6.0...v9.6.1">9.6.1</a> (2020-01-04)</h2><h3 id="Bug-Fixes-81"><a href="#Bug-Fixes-81" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>add <code>this</code> to fs references in parseFile (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/4b079c5">4b079c5</a>)</li>
</ul>
<h1 id="9-6-0-2019-12-15"><a href="#9-6-0-2019-12-15" class="headerlink" title="9.6.0 (2019-12-15)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.5.0...v9.6.0">9.6.0</a> (2019-12-15)</h1><h3 id="Features-51"><a href="#Features-51" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="9-6-0-2019-12-15"><a href="#9-6-0-2019-12-15" class="headerlink" title="9.6.0 (2019-12-15)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.5.0...v9.6.0">9.6.0</a> (2019-12-15)</h1><h3 id="Features-53"><a href="#Features-53" class="headerlink" title="Features"></a>Features</h3><ul>
<li>full syntax for strftime, close <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/177">#177</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/ba5ff3f">ba5ff3f</a>)</li>
</ul>
<h1 id="9-5-0-2019-12-12"><a href="#9-5-0-2019-12-12" class="headerlink" title="9.5.0 (2019-12-12)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.4.2...v9.5.0">9.5.0</a> (2019-12-12)</h1><h3 id="Features-52"><a href="#Features-52" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="9-5-0-2019-12-12"><a href="#9-5-0-2019-12-12" class="headerlink" title="9.5.0 (2019-12-12)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.4.2...v9.5.0">9.5.0</a> (2019-12-12)</h1><h3 id="Features-54"><a href="#Features-54" class="headerlink" title="Features"></a>Features</h3><ul>
<li>nested property for the <code>where</code> filter, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/178">#178</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/60ec74f">60ec74f</a>)</li>
</ul>
<h2 id="9-4-2-2019-11-15"><a href="#9-4-2-2019-11-15" class="headerlink" title="9.4.2 (2019-11-15)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.4.1...v9.4.2">9.4.2</a> (2019-11-15)</h2><h3 id="Bug-Fixes-79"><a href="#Bug-Fixes-79" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-4-2-2019-11-15"><a href="#9-4-2-2019-11-15" class="headerlink" title="9.4.2 (2019-11-15)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.4.1...v9.4.2">9.4.2</a> (2019-11-15)</h2><h3 id="Bug-Fixes-82"><a href="#Bug-Fixes-82" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>reading .first, .last of Array, closes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/175">#175</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/f82da11">f82da11</a>)</li>
</ul>
<h2 id="9-4-1-2019-11-15"><a href="#9-4-1-2019-11-15" class="headerlink" title="9.4.1 (2019-11-15)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.4.0...v9.4.1">9.4.1</a> (2019-11-15)</h2><h3 id="Bug-Fixes-80"><a href="#Bug-Fixes-80" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-4-1-2019-11-15"><a href="#9-4-1-2019-11-15" class="headerlink" title="9.4.1 (2019-11-15)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.4.0...v9.4.1">9.4.1</a> (2019-11-15)</h2><h3 id="Bug-Fixes-83"><a href="#Bug-Fixes-83" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>remove node dependencies for esm bundle, see <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/173">#173</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/04df929">04df929</a>)</li>
</ul>
<h1 id="9-4-0-2019-11-14"><a href="#9-4-0-2019-11-14" class="headerlink" title="9.4.0 (2019-11-14)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.3.1...v9.4.0">9.4.0</a> (2019-11-14)</h1><h3 id="Features-53"><a href="#Features-53" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="9-4-0-2019-11-14"><a href="#9-4-0-2019-11-14" class="headerlink" title="9.4.0 (2019-11-14)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.3.1...v9.4.0">9.4.0</a> (2019-11-14)</h1><h3 id="Features-55"><a href="#Features-55" class="headerlink" title="Features"></a>Features</h3><ul>
<li>add ability to pass JSON context to CLI (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/9504e4e">9504e4e</a>)</li>
</ul>
<h2 id="9-3-1-2019-11-09"><a href="#9-3-1-2019-11-09" class="headerlink" title="9.3.1 (2019-11-09)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.3.0...v9.3.1">9.3.1</a> (2019-11-09)</h2><h3 id="Bug-Fixes-81"><a href="#Bug-Fixes-81" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-3-1-2019-11-09"><a href="#9-3-1-2019-11-09" class="headerlink" title="9.3.1 (2019-11-09)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.3.0...v9.3.1">9.3.1</a> (2019-11-09)</h2><h3 id="Bug-Fixes-84"><a href="#Bug-Fixes-84" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>liquidjs command in /bin/liquid.js, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/169">#169</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/0073b90">0073b90</a>)</li>
</ul>
<h1 id="9-3-0-2019-11-07"><a href="#9-3-0-2019-11-07" class="headerlink" title="9.3.0 (2019-11-07)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.2.0...v9.3.0">9.3.0</a> (2019-11-07)</h1><h3 id="Features-54"><a href="#Features-54" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="9-3-0-2019-11-07"><a href="#9-3-0-2019-11-07" class="headerlink" title="9.3.0 (2019-11-07)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.2.0...v9.3.0">9.3.0</a> (2019-11-07)</h1><h3 id="Features-56"><a href="#Features-56" class="headerlink" title="Features"></a>Features</h3><ul>
<li>support require.resolve for lookup, see <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/168">#168</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/2dd4355">2dd4355</a>)</li>
</ul>
<h2 id="9-1-1-2019-10-10"><a href="#9-1-1-2019-10-10" class="headerlink" title="9.1.1 (2019-10-10)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.1.0...v9.1.1">9.1.1</a> (2019-10-10)</h2><h3 id="Performance-Improvements-7"><a href="#Performance-Improvements-7" class="headerlink" title="Performance Improvements"></a>Performance Improvements</h3><ul>
<li>add string flattening to reduce retained memory (node only) (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/3ad512c">3ad512c</a>)</li>
</ul>
<h1 id="9-1-0-2019-10-07"><a href="#9-1-0-2019-10-07" class="headerlink" title="9.1.0 (2019-10-07)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.0.1...v9.1.0">9.1.0</a> (2019-10-07)</h1><h3 id="Features-55"><a href="#Features-55" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="9-1-0-2019-10-07"><a href="#9-1-0-2019-10-07" class="headerlink" title="9.1.0 (2019-10-07)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.0.1...v9.1.0">9.1.0</a> (2019-10-07)</h1><h3 id="Features-57"><a href="#Features-57" class="headerlink" title="Features"></a>Features</h3><ul>
<li>alias getTemplate() to parseFile() (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/6b83788">6b83788</a>)</li>
</ul>
<h2 id="9-0-1-2019-10-02"><a href="#9-0-1-2019-10-02" class="headerlink" title="9.0.1 (2019-10-02)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.0.0...v9.0.1">9.0.1</a> (2019-10-02)</h2><h3 id="Bug-Fixes-82"><a href="#Bug-Fixes-82" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="9-0-1-2019-10-02"><a href="#9-0-1-2019-10-02" class="headerlink" title="9.0.1 (2019-10-02)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v9.0.0...v9.0.1">9.0.1</a> (2019-10-02)</h2><h3 id="Bug-Fixes-85"><a href="#Bug-Fixes-85" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li><code>unless</code> content is not waited, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/160">#160</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/d2c8d13">d2c8d13</a>)</li>
</ul>
<h1 id="9-0-0-2019-08-26"><a href="#9-0-0-2019-08-26" class="headerlink" title="9.0.0 (2019-08-26)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.5.3...v9.0.0">9.0.0</a> (2019-08-26)</h1><h3 id="Bug-Fixes-83"><a href="#Bug-Fixes-83" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h1 id="9-0-0-2019-08-26"><a href="#9-0-0-2019-08-26" class="headerlink" title="9.0.0 (2019-08-26)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.5.3...v9.0.0">9.0.0</a> (2019-08-26)</h1><h3 id="Bug-Fixes-86"><a href="#Bug-Fixes-86" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>break/continue omitting output before them, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/123">#123</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/ae45c46">ae45c46</a>)</li>
<li>reactjs demo during yarn install, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/145">#145</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/b65df44">b65df44</a>)</li>
</ul>
<h3 id="Code-Refactoring-1"><a href="#Code-Refactoring-1" class="headerlink" title="Code Refactoring"></a>Code Refactoring</h3><ul>
<li>return value of Tag#render is no longer used (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/8028f82">8028f82</a>)</li>
</ul>
<h3 id="Features-56"><a href="#Features-56" class="headerlink" title="Features"></a>Features</h3><ul>
<h3 id="Features-58"><a href="#Features-58" class="headerlink" title="Features"></a>Features</h3><ul>
<li>renderSync, parseAndRenderSync and renderFileSync, see <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/48">#48</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/7fb01ad">7fb01ad</a>)</li>
</ul>
<h3 id="Performance-Improvements-8"><a href="#Performance-Improvements-8" class="headerlink" title="Performance Improvements"></a>Performance Improvements</h3><ul>
@@ -650,95 +634,95 @@
<li>ship to Node.js 8, the dist/liquid.cjs.js (main) no longer<br>supports Node.js 6, other bundles are also provided via dist/liquid.esm.js, dist/liquid.js (ES5 umd) and liquid.min.js (minified ES5 umd)</li>
<li>remove default export, now should be used like import<br>{Liquid} from 'liquidjs'</li>
</ul>
<h2 id="8-5-3-2019-08-25"><a href="#8-5-3-2019-08-25" class="headerlink" title="8.5.3 (2019-08-25)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.5.2...v8.5.3">8.5.3</a> (2019-08-25)</h2><h3 id="Bug-Fixes-84"><a href="#Bug-Fixes-84" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="8-5-3-2019-08-25"><a href="#8-5-3-2019-08-25" class="headerlink" title="8.5.3 (2019-08-25)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.5.2...v8.5.3">8.5.3</a> (2019-08-25)</h2><h3 id="Bug-Fixes-87"><a href="#Bug-Fixes-87" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>escape filter when input is undefined (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/a00945c">a00945c</a>)</li>
</ul>
<h2 id="8-5-2-2019-08-09"><a href="#8-5-2-2019-08-09" class="headerlink" title="8.5.2 (2019-08-09)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.5.1...v8.5.2">8.5.2</a> (2019-08-09)</h2><h3 id="Bug-Fixes-85"><a href="#Bug-Fixes-85" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="8-5-2-2019-08-09"><a href="#8-5-2-2019-08-09" class="headerlink" title="8.5.2 (2019-08-09)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.5.1...v8.5.2">8.5.2</a> (2019-08-09)</h2><h3 id="Bug-Fixes-88"><a href="#Bug-Fixes-88" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>quotation tokenizing, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/151">#151</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/1e4f237">1e4f237</a>)</li>
</ul>
<h2 id="8-5-1-2019-08-05"><a href="#8-5-1-2019-08-05" class="headerlink" title="8.5.1 (2019-08-05)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.5.0...v8.5.1">8.5.1</a> (2019-08-05)</h2><h3 id="Bug-Fixes-86"><a href="#Bug-Fixes-86" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="8-5-1-2019-08-05"><a href="#8-5-1-2019-08-05" class="headerlink" title="8.5.1 (2019-08-05)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.5.0...v8.5.1">8.5.1</a> (2019-08-05)</h2><h3 id="Bug-Fixes-89"><a href="#Bug-Fixes-89" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>publish bin directory to npm, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/146">#146</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/a85b650">a85b650</a>)</li>
</ul>
<h1 id="8-5-0-2019-08-01"><a href="#8-5-0-2019-08-01" class="headerlink" title="8.5.0 (2019-08-01)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.4.1...v8.5.0">8.5.0</a> (2019-08-01)</h1><h3 id="Features-57"><a href="#Features-57" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="8-5-0-2019-08-01"><a href="#8-5-0-2019-08-01" class="headerlink" title="8.5.0 (2019-08-01)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.4.1...v8.5.0">8.5.0</a> (2019-08-01)</h1><h3 id="Features-59"><a href="#Features-59" class="headerlink" title="Features"></a>Features</h3><ul>
<li>CLI support (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/fc045b5">fc045b5</a>)</li>
</ul>
<h2 id="8-4-1-2019-07-22"><a href="#8-4-1-2019-07-22" class="headerlink" title="8.4.1 (2019-07-22)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.4.0...v8.4.1">8.4.1</a> (2019-07-22)</h2><h3 id="Bug-Fixes-87"><a href="#Bug-Fixes-87" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="8-4-1-2019-07-22"><a href="#8-4-1-2019-07-22" class="headerlink" title="8.4.1 (2019-07-22)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.4.0...v8.4.1">8.4.1</a> (2019-07-22)</h2><h3 id="Bug-Fixes-90"><a href="#Bug-Fixes-90" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>some filters on undefined variable throws, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/140">#140</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/6e6ea0a">6e6ea0a</a>)</li>
</ul>
<h1 id="8-4-0-2019-07-06"><a href="#8-4-0-2019-07-06" class="headerlink" title="8.4.0 (2019-07-06)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.3.0...v8.4.0">8.4.0</a> (2019-07-06)</h1><h3 id="Features-58"><a href="#Features-58" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="8-4-0-2019-07-06"><a href="#8-4-0-2019-07-06" class="headerlink" title="8.4.0 (2019-07-06)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.3.0...v8.4.0">8.4.0</a> (2019-07-06)</h1><h3 id="Features-60"><a href="#Features-60" class="headerlink" title="Features"></a>Features</h3><ul>
<li>at_least, at_most, sort_natural for <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/132">#132</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/e6f5f1c">e6f5f1c</a>)</li>
</ul>
<h1 id="8-3-0-2019-06-27"><a href="#8-3-0-2019-06-27" class="headerlink" title="8.3.0 (2019-06-27)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.2.4...v8.3.0">8.3.0</a> (2019-06-27)</h1><h3 id="Features-59"><a href="#Features-59" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="8-3-0-2019-06-27"><a href="#8-3-0-2019-06-27" class="headerlink" title="8.3.0 (2019-06-27)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.2.4...v8.3.0">8.3.0</a> (2019-06-27)</h1><h3 id="Features-61"><a href="#Features-61" class="headerlink" title="Features"></a>Features</h3><ul>
<li>fs option implemented by <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/138">#138</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/3f5e23c">3f5e23c</a>)</li>
</ul>
<h2 id="8-2-4-2019-06-17"><a href="#8-2-4-2019-06-17" class="headerlink" title="8.2.4 (2019-06-17)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.2.3...v8.2.4">8.2.4</a> (2019-06-17)</h2><h3 id="Performance-Improvements-9"><a href="#Performance-Improvements-9" class="headerlink" title="Performance Improvements"></a>Performance Improvements</h3><ul>
<li>improve getTemplate() when cache is enabled (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/1ffba2b">1ffba2b</a>)</li>
</ul>
<h2 id="8-2-3-2019-05-19"><a href="#8-2-3-2019-05-19" class="headerlink" title="8.2.3 (2019-05-19)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.2.2...v8.2.3">8.2.3</a> (2019-05-19)</h2><h3 id="Bug-Fixes-88"><a href="#Bug-Fixes-88" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="8-2-3-2019-05-19"><a href="#8-2-3-2019-05-19" class="headerlink" title="8.2.3 (2019-05-19)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.2.2...v8.2.3">8.2.3</a> (2019-05-19)</h2><h3 id="Bug-Fixes-91"><a href="#Bug-Fixes-91" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>reverse filter not pure, see <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/126">#126</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/505c408">505c408</a>)</li>
</ul>
<h2 id="8-2-2-2019-05-12"><a href="#8-2-2-2019-05-12" class="headerlink" title="8.2.2 (2019-05-12)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.2.1...v8.2.2">8.2.2</a> (2019-05-12)</h2><h3 id="Bug-Fixes-89"><a href="#Bug-Fixes-89" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="8-2-2-2019-05-12"><a href="#8-2-2-2019-05-12" class="headerlink" title="8.2.2 (2019-05-12)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.2.1...v8.2.2">8.2.2</a> (2019-05-12)</h2><h3 id="Bug-Fixes-92"><a href="#Bug-Fixes-92" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>date from integer, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/125">#125</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/fdf0043">fdf0043</a>)</li>
<li>pass drops directly to filters/tags (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/bef2909">bef2909</a>)</li>
</ul>
<h2 id="8-2-1-2019-04-26"><a href="#8-2-1-2019-04-26" class="headerlink" title="8.2.1 (2019-04-26)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.2.0...v8.2.1">8.2.1</a> (2019-04-26)</h2><h3 id="Bug-Fixes-90"><a href="#Bug-Fixes-90" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="8-2-1-2019-04-26"><a href="#8-2-1-2019-04-26" class="headerlink" title="8.2.1 (2019-04-26)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.2.0...v8.2.1">8.2.1</a> (2019-04-26)</h2><h3 id="Bug-Fixes-93"><a href="#Bug-Fixes-93" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li><code>default</code> filter is not working with an empty string, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/122">#122</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/6075c0a">6075c0a</a>)</li>
</ul>
<h1 id="8-2-0-2019-04-17"><a href="#8-2-0-2019-04-17" class="headerlink" title="8.2.0 (2019-04-17)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.1.0...v8.2.0">8.2.0</a> (2019-04-17)</h1><h3 id="Features-60"><a href="#Features-60" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="8-2-0-2019-04-17"><a href="#8-2-0-2019-04-17" class="headerlink" title="8.2.0 (2019-04-17)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.1.0...v8.2.0">8.2.0</a> (2019-04-17)</h1><h3 id="Features-62"><a href="#Features-62" class="headerlink" title="Features"></a>Features</h3><ul>
<li>pass context to filters (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/00bc1ef">00bc1ef</a>)</li>
</ul>
<h1 id="8-1-0-2019-04-02"><a href="#8-1-0-2019-04-02" class="headerlink" title="8.1.0 (2019-04-02)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.0.3...v8.1.0">8.1.0</a> (2019-04-02)</h1><h3 id="Features-61"><a href="#Features-61" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="8-1-0-2019-04-02"><a href="#8-1-0-2019-04-02" class="headerlink" title="8.1.0 (2019-04-02)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.0.3...v8.1.0">8.1.0</a> (2019-04-02)</h1><h3 id="Features-63"><a href="#Features-63" class="headerlink" title="Features"></a>Features</h3><ul>
<li>where filter, working on <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/118">#118</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/daa0b57">daa0b57</a>)</li>
</ul>
<h2 id="8-0-3-2019-04-01"><a href="#8-0-3-2019-04-01" class="headerlink" title="8.0.3 (2019-04-01)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.0.2...v8.0.3">8.0.3</a> (2019-04-01)</h2><h3 id="Bug-Fixes-91"><a href="#Bug-Fixes-91" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="8-0-3-2019-04-01"><a href="#8-0-3-2019-04-01" class="headerlink" title="8.0.3 (2019-04-01)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.0.2...v8.0.3">8.0.3</a> (2019-04-01)</h2><h3 id="Bug-Fixes-94"><a href="#Bug-Fixes-94" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>slice filter on negative <code>begin</code>, <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/117">#117</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/eadb6f3">eadb6f3</a>)</li>
</ul>
<h2 id="8-0-2-2019-03-25"><a href="#8-0-2-2019-03-25" class="headerlink" title="8.0.2 (2019-03-25)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.0.1...v8.0.2">8.0.2</a> (2019-03-25)</h2><h3 id="Performance-Improvements-10"><a href="#Performance-Improvements-10" class="headerlink" title="Performance Improvements"></a>Performance Improvements</h3><ul>
<li>use polymorphism instead duck test (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/82d7673">82d7673</a>)</li>
</ul>
<h2 id="8-0-1-2019-03-22"><a href="#8-0-1-2019-03-22" class="headerlink" title="8.0.1 (2019-03-22)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.0.0...v8.0.1">8.0.1</a> (2019-03-22)</h2><h3 id="Bug-Fixes-92"><a href="#Bug-Fixes-92" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="8-0-1-2019-03-22"><a href="#8-0-1-2019-03-22" class="headerlink" title="8.0.1 (2019-03-22)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v8.0.0...v8.0.1">8.0.1</a> (2019-03-22)</h2><h3 id="Bug-Fixes-95"><a href="#Bug-Fixes-95" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>incorrect scope when using assign with for, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/115">#115</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/defbb58">defbb58</a>)</li>
</ul>
<h1 id="8-0-0-2019-03-10"><a href="#8-0-0-2019-03-10" class="headerlink" title="8.0.0 (2019-03-10)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.5.1...v8.0.0">8.0.0</a> (2019-03-10)</h1><h3 id="Code-Refactoring-2"><a href="#Code-Refactoring-2" class="headerlink" title="Code Refactoring"></a>Code Refactoring</h3><ul>
<li>use camelCase for JavaScript APIs (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/64e0c87">64e0c87</a>)</li>
</ul>
<h3 id="Features-62"><a href="#Features-62" class="headerlink" title="Features"></a>Features</h3><ul>
<h3 id="Features-64"><a href="#Features-64" class="headerlink" title="Features"></a>Features</h3><ul>
<li>promise support for drops, working on <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/65">#65</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/4a8088d">4a8088d</a>)</li>
</ul>
<h3 id="BREAKING-CHANGES-2"><a href="#BREAKING-CHANGES-2" class="headerlink" title="BREAKING CHANGES"></a>BREAKING CHANGES</h3><ul>
<li>Options and method names in JavaScript API are now renamed to camelCase, for a complete list see #109</li>
</ul>
<h2 id="7-5-1-2019-03-05"><a href="#7-5-1-2019-03-05" class="headerlink" title="7.5.1 (2019-03-05)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.5.0...v7.5.1">7.5.1</a> (2019-03-05)</h2><h3 id="Bug-Fixes-93"><a href="#Bug-Fixes-93" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="7-5-1-2019-03-05"><a href="#7-5-1-2019-03-05" class="headerlink" title="7.5.1 (2019-03-05)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.5.0...v7.5.1">7.5.1</a> (2019-03-05)</h2><h3 id="Bug-Fixes-96"><a href="#Bug-Fixes-96" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>named params for filters, working on <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/113">#113</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/5ffc904">5ffc904</a>)</li>
</ul>
<h1 id="7-5-0-2019-03-01"><a href="#7-5-0-2019-03-01" class="headerlink" title="7.5.0 (2019-03-01)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.4.0...v7.5.0">7.5.0</a> (2019-03-01)</h1><h3 id="Features-63"><a href="#Features-63" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="7-5-0-2019-03-01"><a href="#7-5-0-2019-03-01" class="headerlink" title="7.5.0 (2019-03-01)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.4.0...v7.5.0">7.5.0</a> (2019-03-01)</h1><h3 id="Features-65"><a href="#Features-65" class="headerlink" title="Features"></a>Features</h3><ul>
<li>tablerowloop object (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/3647305">3647305</a>)</li>
</ul>
<h1 id="7-4-0-2019-02-28"><a href="#7-4-0-2019-02-28" class="headerlink" title="7.4.0 (2019-02-28)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.3.1...v7.4.0">7.4.0</a> (2019-02-28)</h1><h3 id="Bug-Fixes-94"><a href="#Bug-Fixes-94" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h1 id="7-4-0-2019-02-28"><a href="#7-4-0-2019-02-28" class="headerlink" title="7.4.0 (2019-02-28)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.3.1...v7.4.0">7.4.0</a> (2019-02-28)</h1><h3 id="Bug-Fixes-97"><a href="#Bug-Fixes-97" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>math filters now return number, resolves <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/110">#110</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/b4acdb4">b4acdb4</a>)</li>
</ul>
<h3 id="Features-64"><a href="#Features-64" class="headerlink" title="Features"></a>Features</h3><ul>
<h3 id="Features-66"><a href="#Features-66" class="headerlink" title="Features"></a>Features</h3><ul>
<li>exported Drop interface for <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/107">#107</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/7bee9fc">7bee9fc</a>), closes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/109">#109</a></li>
</ul>
<h2 id="7-3-1-2019-02-25"><a href="#7-3-1-2019-02-25" class="headerlink" title="7.3.1 (2019-02-25)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.3.0...v7.3.1">7.3.1</a> (2019-02-25)</h2><h3 id="Bug-Fixes-95"><a href="#Bug-Fixes-95" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="7-3-1-2019-02-25"><a href="#7-3-1-2019-02-25" class="headerlink" title="7.3.1 (2019-02-25)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.3.0...v7.3.1">7.3.1</a> (2019-02-25)</h2><h3 id="Bug-Fixes-98"><a href="#Bug-Fixes-98" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li><strong>#108:</strong> remove absolute path in emitted d.ts (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/53a835a">53a835a</a>), closes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/108">#108</a></li>
</ul>
<h1 id="7-3-0-2019-02-24"><a href="#7-3-0-2019-02-24" class="headerlink" title="7.3.0 (2019-02-24)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.2.2...v7.3.0">7.3.0</a> (2019-02-24)</h1><h3 id="Features-65"><a href="#Features-65" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="7-3-0-2019-02-24"><a href="#7-3-0-2019-02-24" class="headerlink" title="7.3.0 (2019-02-24)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.2.2...v7.3.0">7.3.0</a> (2019-02-24)</h1><h3 id="Features-67"><a href="#Features-67" class="headerlink" title="Features"></a>Features</h3><ul>
<li>nil/null/empty/blank literals, resolves <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/102">#102</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/88c9e96">88c9e96</a>)</li>
</ul>
<h2 id="7-2-2-2019-02-23"><a href="#7-2-2-2019-02-23" class="headerlink" title="7.2.2 (2019-02-23)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.2.1...v7.2.2">7.2.2</a> (2019-02-23)</h2><h3 id="Bug-Fixes-96"><a href="#Bug-Fixes-96" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="7-2-2-2019-02-23"><a href="#7-2-2-2019-02-23" class="headerlink" title="7.2.2 (2019-02-23)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.2.1...v7.2.2">7.2.2</a> (2019-02-23)</h2><h3 id="Bug-Fixes-99"><a href="#Bug-Fixes-99" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>filters break when argument contains [()|, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/89">#89</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/e977669">e977669</a>)</li>
</ul>
<h2 id="7-2-1-2019-02-22"><a href="#7-2-1-2019-02-22" class="headerlink" title="7.2.1 (2019-02-22)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.2.0...v7.2.1">7.2.1</a> (2019-02-22)</h2><h3 id="Bug-Fixes-97"><a href="#Bug-Fixes-97" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="7-2-1-2019-02-22"><a href="#7-2-1-2019-02-22" class="headerlink" title="7.2.1 (2019-02-22)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.2.0...v7.2.1">7.2.1</a> (2019-02-22)</h2><h3 id="Bug-Fixes-100"><a href="#Bug-Fixes-100" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>default length for truncate and truncatewords (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/56c7992">56c7992</a>)</li>
</ul>
<h1 id="7-2-0-2019-02-20"><a href="#7-2-0-2019-02-20" class="headerlink" title="7.2.0 (2019-02-20)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.1.0...v7.2.0">7.2.0</a> (2019-02-20)</h1><h3 id="Features-66"><a href="#Features-66" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="7-2-0-2019-02-20"><a href="#7-2-0-2019-02-20" class="headerlink" title="7.2.0 (2019-02-20)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.1.0...v7.2.0">7.2.0</a> (2019-02-20)</h1><h3 id="Features-68"><a href="#Features-68" class="headerlink" title="Features"></a>Features</h3><ul>
<li>override output/tag delimiter, fixes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/54">#54</a> (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/d20a043">d20a043</a>)</li>
</ul>
<h3 id="BREAKING-CHANGES-3"><a href="#BREAKING-CHANGES-3" class="headerlink" title="BREAKING CHANGES"></a>BREAKING CHANGES</h3><ul>
<li><code>trim_value_left</code> option renamed to <code>trim_output_left</code>, <code>trim_value_right</code> option renamed to <code>trim_output_right</code></li>
</ul>
<h1 id="7-1-0-2019-02-20"><a href="#7-1-0-2019-02-20" class="headerlink" title="7.1.0 (2019-02-20)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.0.2...v7.1.0">7.1.0</a> (2019-02-20)</h1><h3 id="Features-67"><a href="#Features-67" class="headerlink" title="Features"></a>Features</h3><ul>
<h1 id="7-1-0-2019-02-20"><a href="#7-1-0-2019-02-20" class="headerlink" title="7.1.0 (2019-02-20)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v7.0.2...v7.1.0">7.1.0</a> (2019-02-20)</h1><h3 id="Features-69"><a href="#Features-69" class="headerlink" title="Features"></a>Features</h3><ul>
<li>throw an Error if delimiter not matched (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/c33d8f6">c33d8f6</a>)</li>
</ul>
<h1 id="7-0-0-2019-02-14"><a href="#7-0-0-2019-02-14" class="headerlink" title="7.0.0 (2019-02-14)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v6.4.3...v7.0.0">7.0.0</a> (2019-02-14)</h1><h3 id="chore"><a href="#chore" class="headerlink" title="chore"></a>chore</h3><ul>
@@ -747,19 +731,19 @@
<h3 id="BREAKING-CHANGES-4"><a href="#BREAKING-CHANGES-4" class="headerlink" title="BREAKING CHANGES"></a>BREAKING CHANGES</h3><ul>
<li><strong>TypeScript:</strong> calling <code>Liquid()</code> without <code>new</code> now becomes invalid</li>
</ul>
<h2 id="6-4-3-2019-02-13"><a href="#6-4-3-2019-02-13" class="headerlink" title="6.4.3 (2019-02-13)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v6.4.2...v6.4.3">6.4.3</a> (2019-02-13)</h2><h3 id="Bug-Fixes-98"><a href="#Bug-Fixes-98" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="6-4-3-2019-02-13"><a href="#6-4-3-2019-02-13" class="headerlink" title="6.4.3 (2019-02-13)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v6.4.2...v6.4.3">6.4.3</a> (2019-02-13)</h2><h3 id="Bug-Fixes-101"><a href="#Bug-Fixes-101" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>better index.d.ts and a demo (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/2015f68">2015f68</a>), closes <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/98">#98</a></li>
</ul>
<h2 id="6-4-2-2019-01-28"><a href="#6-4-2-2019-01-28" class="headerlink" title="6.4.2 (2019-01-28)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v6.4.1...v6.4.2">6.4.2</a> (2019-01-28)</h2><h3 id="Bug-Fixes-99"><a href="#Bug-Fixes-99" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="6-4-2-2019-01-28"><a href="#6-4-2-2019-01-28" class="headerlink" title="6.4.2 (2019-01-28)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v6.4.1...v6.4.2">6.4.2</a> (2019-01-28)</h2><h3 id="Bug-Fixes-102"><a href="#Bug-Fixes-102" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li><strong>CI:</strong> e2e not building cjs (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/dde7b3b">dde7b3b</a>)</li>
</ul>
<h2 id="6-4-1-2019-01-28"><a href="#6-4-1-2019-01-28" class="headerlink" title="6.4.1 (2019-01-28)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v6.4.0...v6.4.1">6.4.1</a> (2019-01-28)</h2><h3 id="Bug-Fixes-100"><a href="#Bug-Fixes-100" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<h2 id="6-4-1-2019-01-28"><a href="#6-4-1-2019-01-28" class="headerlink" title="6.4.1 (2019-01-28)"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/compare/v6.4.0...v6.4.1">6.4.1</a> (2019-01-28)</h2><h3 id="Bug-Fixes-103"><a href="#Bug-Fixes-103" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>regenerator undefined (<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/commit/a2caeb5">a2caeb5</a>)</li>
</ul>
</script></li></ul>
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:45.302Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:56:19.234Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="migrate-to-9.html" class="article-footer-prev" title="Migrate to LiquidJS 9"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="differences.html" class="article-footer-next" title="Differences with Shopify/liquid"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+2 -2
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -102,7 +102,7 @@
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.834Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="differences.html" class="article-footer-prev" title="Differences with Shopify/liquid"><i class="icon-chevron-left"></i><span>Prev</span></a>
</footer>
</div>
+2 -2
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -126,7 +126,7 @@
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.834Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="changelog.html" class="article-footer-prev" title="Changelog"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="contribution-guidelines.html" class="article-footer-next" title="Contribution Guidelines"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+5 -14
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -94,33 +94,24 @@
<div class="article-content" itemprop="articleBody">
<p>When the template or data context cannot be trusted, enabling DoS prevention options is crucial. LiquidJS provides 3 options for this purpose: <code>parseLimit</code>, <code>renderLimit</code>, and <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>Setting these options can largely ensure that your LiquidJS instance wont hang for extended periods or consume excessive memory. These limits are based on the available JavaScript APIs, so they are not precise hard limits but thresholds to help prevent your process from failing or hanging.</p>
<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">&#123;</span>
parseLimit<span class="token operator">:</span> <span class="token number">1e8</span><span class="token punctuation">,</span> <span class="token comment">// typical size of your templates in each render</span>
renderLimit<span class="token operator">:</span> <span class="token number">1000</span><span class="token punctuation">,</span> <span class="token comment">// limit each render to be completed in 1s</span>
memoryLimit<span class="token operator">:</span> <span class="token number">1e9</span><span class="token punctuation">,</span> <span class="token comment">// memory available for LiquidJS (1e9 for 1GB)</span>
<span class="token punctuation">&#125;</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>
<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>(&#123;</span><br><span class="line"> <span class="attr">parseLimit</span>: <span class="number">1e8</span>, <span class="comment">// typical size of your templates in each render</span></span><br><span class="line"> <span class="attr">renderLimit</span>: <span class="number">1000</span>, <span class="comment">// limit each render to be completed in 1s</span></span><br><span class="line"> <span class="attr">memoryLimit</span>: <span class="number">1e9</span>, <span class="comment">// memory available for LiquidJS (1e9 for 1GB)</span></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>When a <code>parse()</code> or <code>render()</code> cannot be completed within given resource, it throws.</p>
<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> restricts the size (character length) of templates parsed in each <code>.parse()</code> call, including referenced partials and layouts. Since LiquidJS parses template strings in near O(n) time, limiting total template length is usually sufficient.</p>
<p>A typical PC handles <code>1e8</code> (100M) characters without issues.</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>Restricting template size alone is insufficient because dynamic loops with large counts can occur in render time. <a href="/api/interfaces/LiquidOptions.html#renderLimit">renderLimit</a> mitigates this by limiting the time consumed by each <code>render()</code> call.</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%-</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">-%&#125;</span></span>
order: <span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;&#123;</span>i<span class="token delimiter punctuation">&#125;&#125;</span></span>
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%-</span> <span class="token keyword">endfor</span> <span class="token delimiter punctuation">-%&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<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">&#123;%- for i in (1..10000000) -%&#125;</span><br><span class="line"> order: &#123;&#123;i&#125;&#125;</span><br><span class="line">&#123;%- endfor -%&#125;</span><br></pre></td></tr></table></figure>
<p>Render time is checked on a per-template basis (before rendering each template). In the above example, there are 2 templates in the loop: <code>order:</code> and <code>&#123;&#123;i&#125;&#125;</code>, render time will be checked 10000000x2 times.</p>
<p>For time-consuming tags and filters within a single template, the process can still hang. For fully controlled rendering, consider using a process manager like <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>Even with small number of templates and iterations, memory usage can grow exponentially. In the following example, memory doubles with each iteration:</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</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">%&#125;</span></span>
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</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">%&#125;</span></span>
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</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">%&#125;</span></span>
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> <span class="token keyword">endfor</span> <span class="token delimiter punctuation">%&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<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">&#123;% assign array = &quot;1,2,3&quot; | split: &quot;,&quot; %&#125;</span><br><span class="line">&#123;% for i in (1..32) %&#125;</span><br><span class="line"> &#123;% assign array = array | concat: array %&#125;</span><br><span class="line">&#123;% endfor %&#125;</span><br></pre></td></tr></table></figure>
<p><a href="/api/interfaces/LiquidOptions.html#memoryLimit">memoryLimit</a> restricts memory-sensitive filters to prevent excessive memory allocation. As <a target="_blank" rel="noopener external nofollow noreferrer" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_management">JavaScript uses GC to manage memory</a>, <code>memoryLimit</code> limits only the total number of objects allocated by memory sensitive filters in LiquidJS thus may not reflect the actual memory footprint.</p>
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.834Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="truthy-and-falsy.html" class="article-footer-prev" title="Truthy and Falsy"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="migrate-to-9.html" class="article-footer-next" title="Migrate to LiquidJS 9"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+11 -107
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -96,23 +96,7 @@
<blockquote class="note info"><strong class="note-title">Drop for JavaScript</strong><p><em>Drop</em> interface is implemented differently in LiquidJS compared to built-in filters and other template functionalities. Since LiquidJS runs in JavaScript, custom Drops need to be reimplemented in JavaScript anyway. Theres no compatibility between JavaScript classes and Ruby classes.</p>
</blockquote>
<h2 id="Basic-Usage" class="article-heading"><a href="#Basic-Usage" class="headerlink" title="Basic Usage"></a>Basic Usage<a class="article-anchor" href="#Basic-Usage" 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">&#123;</span> Liquid<span class="token punctuation">,</span> Drop <span class="token punctuation">&#125;</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">&#123;</span>
<span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</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">&#125;</span>
<span class="token function">bar</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token string">'BAR'</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</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: &#123;&#123;settings.foo&#125;&#125;, bar: &#123;&#123;settings.bar&#125;&#125;</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">&#123;</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">&#125;</span>
<span class="token comment">// Outputs: "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>
<h2 id="Basic-Usage" class="article-heading"><a href="#Basic-Usage" class="headerlink" title="Basic Usage"></a>Basic Usage<a class="article-anchor" href="#Basic-Usage" 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> &#123; <span class="title class_">Liquid</span>, <span class="title class_">Drop</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;liquidjs&#x27;</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> &#123;</span><br><span class="line"> <span class="title function_">constructor</span>(<span class="params"></span>) &#123;</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">&#x27;FOO&#x27;</span></span><br><span class="line"> &#125;</span><br><span class="line"> <span class="title function_">bar</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="string">&#x27;BAR&#x27;</span></span><br><span class="line"> &#125;</span><br><span class="line">&#125;</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: &#123;&#123;settings.foo&#125;&#125;, bar: &#123;&#123;settings.bar&#125;&#125;`</span></span><br><span class="line"><span class="keyword">const</span> context = &#123; <span class="attr">settings</span>: <span class="keyword">new</span> <span class="title class_">SettingsDrop</span>() &#125;</span><br><span class="line"><span class="comment">// Outputs: &quot;foo: FOO, bar: BAR&quot;</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> =&gt;</span> <span class="variable language_">console</span>.<span class="title function_">log</span>(html))</span><br></pre></td></tr></table></figure>
<p><a target="_blank" rel="noopener external nofollow noreferrer" href="https://runkit.com/embed/2is7di4mc7kk">Runkit link</a></p>
<p>As shown above, besides reading properties from context scopes, you can also call methods. You only need to create a custom class inherited from <code>Drop</code>.</p>
@@ -120,93 +104,19 @@ engine<span class="token punctuation">.</span><span class="token function">parse
</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>For cases when there isnt a fixed set of properties, you can leverage <code>liquidMethodMissing</code> to dynamically resolve the value of a variable name.</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">import</span> <span class="token punctuation">&#123;</span> Liquid<span class="token punctuation">,</span> Drop <span class="token punctuation">&#125;</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">&#123;</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">&#123;</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">&#125;</span>
<span class="token punctuation">&#125;</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">// Outputs: "COO"</span>
engine<span class="token punctuation">.</span><span class="token function">parseAndRender</span><span class="token punctuation">(</span><span class="token string">"&#123;&#123;settings.coo&#125;&#125;"</span><span class="token punctuation">,</span> <span class="token punctuation">&#123;</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">&#125;</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>
<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> &#123; <span class="title class_">Liquid</span>, <span class="title class_">Drop</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;liquidjs&#x27;</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> &#123;</span><br><span class="line"> <span class="title function_">liquidMethodMissing</span>(<span class="params">key</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> key.<span class="title function_">toUpperCase</span>()</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</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">// Outputs: &quot;COO&quot;</span></span><br><span class="line">engine.<span class="title function_">parseAndRender</span>(<span class="string">&quot;&#123;&#123;settings.coo&#125;&#125;&quot;</span>, &#123; <span class="attr">settings</span>: <span class="keyword">new</span> <span class="title class_">SettingsDrop</span>() &#125;)</span><br><span class="line"> .<span class="title function_">then</span>(<span class="function"><span class="params">html</span> =&gt;</span> <span class="variable language_">console</span>.<span class="title function_">log</span>(html))</span><br></pre></td></tr></table></figure>
<p><code>liquidMethodMissing</code> supports Promise, meaning you can make async calls within it. A more useful case can be fetching the value dynamically from the database. By using Drops, you can avoid hardcoding each property into the context. For example:</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">import</span> <span class="token punctuation">&#123;</span> Liquid<span class="token punctuation">,</span> Drop <span class="token punctuation">&#125;</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">&#123;</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">&#123;</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">&#125;</span>
<span class="token punctuation">&#125;</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">&#123;</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">&#125;</span>
engine<span class="token punctuation">.</span><span class="token function">parseAndRender</span><span class="token punctuation">(</span><span class="token string">"&#123;&#123;db.coo&#125;&#125;"</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>
<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> &#123; <span class="title class_">Liquid</span>, <span class="title class_">Drop</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;liquidjs&#x27;</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> &#123;</span><br><span class="line"> <span class="keyword">async</span> <span class="title function_">liquidMethodMissing</span>(<span class="params">key</span>) &#123;</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"> &#125;</span><br><span class="line">&#125;</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 = &#123; <span class="attr">db</span>: <span class="keyword">new</span> <span class="title class_">DBDrop</span>() &#125;</span><br><span class="line">engine.<span class="title function_">parseAndRender</span>(<span class="string">&quot;&#123;&#123;db.coo&#125;&#125;&quot;</span>, context).<span class="title function_">then</span>(<span class="function"><span class="params">html</span> =&gt;</span> <span class="variable language_">console</span>.<span class="title function_">log</span>(html))</span><br></pre></td></tr></table></figure>
<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>Drops can implement a <code>valueOf()</code> method, the return value of which can be used to replace itself in the output. For example:</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">import</span> <span class="token punctuation">&#123;</span> Liquid<span class="token punctuation">,</span> Drop <span class="token punctuation">&#125;</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">&#123;</span>
<span class="token function">valueOf</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token string">'red'</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</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">&#123;</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">&#125;</span>
<span class="token comment">// Outputs: "red"</span>
engine<span class="token punctuation">.</span><span class="token function">parseAndRender</span><span class="token punctuation">(</span><span class="token string">"&#123;&#123;color&#125;&#125;"</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>
<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> &#123; <span class="title class_">Liquid</span>, <span class="title class_">Drop</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;liquidjs&#x27;</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> &#123;</span><br><span class="line"> <span class="title function_">valueOf</span>(<span class="params"></span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="string">&#x27;red&#x27;</span></span><br><span class="line"> &#125;</span><br><span class="line">&#125;</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 = &#123; <span class="attr">color</span>: <span class="keyword">new</span> <span class="title class_">ColorDrop</span>() &#125;</span><br><span class="line"><span class="comment">// Outputs: &quot;red&quot;</span></span><br><span class="line">engine.<span class="title function_">parseAndRender</span>(<span class="string">&quot;&#123;&#123;color&#125;&#125;&quot;</span>, context).<span class="title function_">then</span>(<span class="function"><span class="params">html</span> =&gt;</span> <span class="variable language_">console</span>.<span class="title function_">log</span>(html))</span><br></pre></td></tr></table></figure>
<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> is not a method of <code>Drop</code>, but it can be used to return a <code>Drop</code>. In cases where you have a fixed structure in the <code>context</code> that cannot change its values, you can implement <code>toLiquid()</code> to let LiquidJS use the returned value instead of itself to render the templates.</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">import</span> <span class="token punctuation">&#123;</span> Liquid<span class="token punctuation">,</span> Drop <span class="token punctuation">&#125;</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">&#123;</span>
<span class="token literal-property property">person</span><span class="token operator">:</span> <span class="token punctuation">&#123;</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">&#123;</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">// use a different `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">&#125;</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</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">// Outputs: "Yang, Jun"</span>
engine<span class="token punctuation">.</span><span class="token function">parseAndRender</span><span class="token punctuation">(</span><span class="token string">"&#123;&#123;person.name&#125;&#125;"</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>
<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> &#123; <span class="title class_">Liquid</span>, <span class="title class_">Drop</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;liquidjs&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> context = &#123;</span><br><span class="line"> <span class="attr">person</span>: &#123;</span><br><span class="line"> <span class="attr">firstName</span>: <span class="string">&quot;Jun&quot;</span>,</span><br><span class="line"> <span class="attr">lastName</span>: <span class="string">&quot;Yang&quot;</span>,</span><br><span class="line"> <span class="attr">name</span>: <span class="string">&quot;Jun Yang&quot;</span>,</span><br><span class="line"> <span class="attr">toLiquid</span>: <span class="function">() =&gt;</span> (&#123;</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">// use a different `name`</span></span><br><span class="line"> <span class="attr">name</span>: <span class="string">&quot;Yang, Jun&quot;</span></span><br><span class="line"> &#125;)</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</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">// Outputs: &quot;Yang, Jun&quot;</span></span><br><span class="line">engine.<span class="title function_">parseAndRender</span>(<span class="string">&quot;&#123;&#123;person.name&#125;&#125;&quot;</span>, context).<span class="title function_">then</span>(<span class="function"><span class="params">html</span> =&gt;</span> <span class="variable language_">console</span>.<span class="title function_">log</span>(html))</span><br></pre></td></tr></table></figure>
<p>Of course, you can also return a <code>PersonDrop</code> instance in the <code>toLiquid()</code> method and implement this functionality within <code>PersonDrop</code>:</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">import</span> <span class="token punctuation">&#123;</span> Liquid<span class="token punctuation">,</span> Drop <span class="token punctuation">&#125;</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">&#123;</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">&#123;</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">&#125;</span>
<span class="token function">name</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</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">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">const</span> context <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
<span class="token literal-property property">person</span><span class="token operator">:</span> <span class="token punctuation">&#123;</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">&#123;</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">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</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">// Outputs: "Yang, Jun"</span>
engine<span class="token punctuation">.</span><span class="token function">parseAndRender</span><span class="token punctuation">(</span><span class="token string">"&#123;&#123;person.name&#125;&#125;"</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>
<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> &#123; <span class="title class_">Liquid</span>, <span class="title class_">Drop</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;liquidjs&#x27;</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> &#123;</span><br><span class="line"> <span class="title function_">constructor</span>(<span class="params">person</span>) &#123;</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"> &#125;</span><br><span class="line"> <span class="title function_">name</span>(<span class="params"></span>) &#123;</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">&quot;, &quot;</span> + <span class="variable language_">this</span>.<span class="property">person</span>.<span class="property">firstName</span></span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> context = &#123;</span><br><span class="line"> <span class="attr">person</span>: &#123;</span><br><span class="line"> <span class="attr">firstName</span>: <span class="string">&quot;Jun&quot;</span>,</span><br><span class="line"> <span class="attr">lastName</span>: <span class="string">&quot;Yang&quot;</span>,</span><br><span class="line"> <span class="attr">name</span>: <span class="string">&quot;Jun Yang&quot;</span>,</span><br><span class="line"> <span class="attr">toLiquid</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123; <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">PersonDrop</span>(<span class="variable language_">this</span>) &#125;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</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">// Outputs: &quot;Yang, Jun&quot;</span></span><br><span class="line">engine.<span class="title function_">parseAndRender</span>(<span class="string">&quot;&#123;&#123;person.name&#125;&#125;&quot;</span>, context).<span class="title function_">then</span>(<span class="function"><span class="params">html</span> =&gt;</span> <span class="variable language_">console</span>.<span class="title function_">log</span>(html))</span><br></pre></td></tr></table></figure>
<blockquote class="note info"><strong class="note-title"><code>toLiquid()</code> vs. <code>valueOf()</code> Difference</strong><ul>
<li><code>valueOf()</code> is typically used to define how the current variable should be rendered, while <code>toLiquid()</code> is often used to convert an object into a Drop or another scope provided to the template.</li>
@@ -216,28 +126,22 @@ engine<span class="token punctuation">.</span><span class="token function">parse
<h2 id="Special-Drops" class="article-heading"><a href="#Special-Drops" class="headerlink" title="Special Drops"></a>Special Drops<a class="article-anchor" href="#Special-Drops" aria-hidden="true"></a></h2><p>LiquidJS itself implements several built-in drops to facilitate template writing. This part is compatible with Shopify Liquid, as we need templates to be portable.</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>Useful to check whether a string variable is <code>false</code>, <code>null</code>, <code>undefined</code>, an empty string, or a string containing only blank characters.</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> <span class="token keyword">unless</span> author <span class="token operator">==</span> blank <span class="token delimiter punctuation">%&#125;</span></span>
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;&#123;</span>author<span class="token delimiter punctuation">&#125;&#125;</span></span>
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> <span class="token keyword">endif</span> <span class="token delimiter punctuation">%&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<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">&#123;% unless author == blank %&#125;</span><br><span class="line"> &#123;&#123;author&#125;&#125;</span><br><span class="line">&#123;% endif %&#125;</span><br></pre></td></tr></table></figure>
<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>Useful to check if an array, string, or object is empty.</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</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">%&#125;</span></span>
Author list is empty
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> <span class="token keyword">endif</span> <span class="token delimiter punctuation">%&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<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">&#123;% if authors == empty %&#125;</span><br><span class="line"> Author list is empty</span><br><span class="line">&#123;% endif %&#125;</span><br></pre></td></tr></table></figure>
<blockquote class="note info"><strong class="note-title"><code>empty</code> implementation</strong><p>For arrays and strings, LiquidJS checks their <code>.length</code> property. For objects, LiquidJS calls <code>Object.keys()</code> to check whether they have keys.</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 is used to check whether a variable is not defined or defined as <code>null</code> or <code>undefined</code>, essentially equivalent to JavaScript <code>== null</code> check.</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> <span class="token keyword">if</span> nonexistent <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token delimiter punctuation">%&#125;</span></span>
null variable
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> <span class="token keyword">endif</span> <span class="token delimiter punctuation">%&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<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">&#123;% if nonexistent == nil %&#125;</span><br><span class="line"> null variable</span><br><span class="line">&#123;% endif %&#125;</span><br></pre></td></tr></table></figure>
<h3 id="Other-Drops" class="article-heading"><a href="#Other-Drops" class="headerlink" title="Other Drops"></a>Other Drops<a class="article-anchor" href="#Other-Drops" aria-hidden="true"></a></h3><p>There are still several Drops for specific tags, like <code>forloop</code>, <code>tablerowloop</code>, <code>block</code>, which are covered by respective tag documents.</p>
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.834Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="render-tag-content.html" class="article-footer-prev" title="Render Tag Content"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="sync-and-async.html" class="article-footer-next" title="Sync and Async"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+10 -16
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -99,43 +99,37 @@
</ol>
<h2 id="HTML-Escape" class="article-heading"><a href="#HTML-Escape" class="headerlink" title="HTML Escape"></a>HTML Escape<a class="article-anchor" href="#HTML-Escape" aria-hidden="true"></a></h2><p>By default output is not escaped. While you can use <a href="../filters/escape.html">escape</a> filter for this:</p>
<p>Input</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;&#123;</span> <span class="token string">"1 &lt; 2"</span> <span class="token operator">|</span> <span class="token function filter">escape</span> <span class="token delimiter punctuation">&#125;&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<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">&#123;&#123; &quot;1 &lt; 2&quot; | escape &#125;&#125;</span><br></pre></td></tr></table></figure>
<p>Output</p>
<pre class="line-numbers language-text" data-language="text"><code class="language-text">1 &amp;lt; 2<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<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 &amp;lt; 2</span><br></pre></td></tr></table></figure>
<p>Theres also <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> filters for you to fine tune your output.</p>
<p>In cases where variables are mostly not trusted, <a href="./options.html#outputEscape">outputEscape</a> can be set to <code>&quot;escape&quot;</code> to apply escape by default. In this case, when you need some output not to be escaped, <a href="../filters/raw.html">raw</a> filter can be used:</p>
<p>Input</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;&#123;</span> <span class="token string">"1 &lt; 2"</span> <span class="token delimiter punctuation">&#125;&#125;</span></span>
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;&#123;</span> <span class="token string">"&lt;button>OK&lt;/button>"</span> <span class="token operator">|</span> <span class="token keyword">raw</span> <span class="token delimiter punctuation">&#125;&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<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">&#123;&#123; &quot;1 &lt; 2&quot; &#125;&#125;</span><br><span class="line">&#123;&#123; &quot;&lt;button&gt;OK&lt;/button&gt;&quot; | raw &#125;&#125;</span><br></pre></td></tr></table></figure>
<p>Output</p>
<pre class="line-numbers language-text" data-language="text"><code class="language-text">1 &amp;lt; 2
&lt;button>OK&lt;/button><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<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 &amp;lt; 2</span><br><span class="line">&lt;button&gt;OK&lt;/button&gt;</span><br></pre></td></tr></table></figure>
<h2 id="Liquid-Escape" class="article-heading"><a href="#Liquid-Escape" class="headerlink" title="Liquid Escape"></a>Liquid Escape<a class="article-anchor" href="#Liquid-Escape" aria-hidden="true"></a></h2><p>To disable Liquid language and output strings like <code>&#123;&#123;</code> and <code>&#123;%</code>, the <a href="../filters/raw.html">raw</a> tag can be used.</p>
<p>Input</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> <span class="token keyword">raw</span> <span class="token delimiter punctuation">%&#125;</span></span>
In LiquidJS, &#123;&#123; this | escape &#125;&#125; will be HTML-escaped, but
&#123;&#123;&#123; that &#125;&#125;&#125; will not.
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> <span class="token keyword">endraw</span> <span class="token delimiter punctuation">%&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<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">&#123;% raw %&#125;</span><br><span class="line"> In LiquidJS, &#123;&#123; this | escape &#125;&#125; will be HTML-escaped, but</span><br><span class="line"> &#123;&#123;&#123; that &#125;&#125;&#125; will not.</span><br><span class="line">&#123;% endraw %&#125;</span><br></pre></td></tr></table></figure>
<p>Output</p>
<pre class="line-numbers language-text" data-language="text"><code class="language-text">In LiquidJS, &#123;&#123; this | escape &#125;&#125; will be HTML-escaped, but
&#123;&#123;&#123; that &#125;&#125;&#125; will not.<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<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, &#123;&#123; this | escape &#125;&#125; will be HTML-escaped, but</span><br><span class="line">&#123;&#123;&#123; that &#125;&#125;&#125; will not.</span><br></pre></td></tr></table></figure>
<p>Within strings literals in LiquidJS template, <code>\</code> can be used to escape special characters in string syntax. For example:</p>
<p>Input</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;&#123;</span> <span class="token string">"\"</span>" <span class="token delimiter punctuation">&#125;&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<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">&#123;&#123; &quot;\&quot;&quot; &#125;&#125;</span><br></pre></td></tr></table></figure>
<p>Output</p>
<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>
<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">&quot;</span><br></pre></td></tr></table></figure>
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.834Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="caching.html" class="article-footer-prev" title="Caching"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="register-filters-tags.html" class="article-footer-next" title="Register Filters/Tags"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+8 -12
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -96,36 +96,32 @@
<p>LiquidJS syntax is relatively simple. Therere 2 types of markups in LiquidJS:</p>
<ul>
<li><strong>Tags</strong>. A tag consists of a tag name and optional arguments wrapped between <code>{%</code> and <code>%&#125;</code>.</li>
<li><strong>Outputs</strong>. An output consists of a value and a list of filters, which is optional, wrapped between <code>{{` and `}}</code>.</li>
<li><strong>Outputs</strong>. An output consists of a value and a list of filters, which is optional, wrapped between <code>{{</code> and <code>&#125;&#125;</code>.</li>
</ul>
<blockquote class="note info"><strong class="note-title">Live Demo</strong><p>Before going into the details, heres a live demo to play around: <a href="https://liquidjs.com/playground.html">https://liquidjs.com/playground.html</a>.</p>
</blockquote>
<h2 id="Outputs" class="article-heading"><a href="#Outputs" class="headerlink" title="Outputs"></a>Outputs<a class="article-anchor" href="#Outputs" aria-hidden="true"></a></h2><p><strong>Outputs</strong> are used to output variables, which can be transformed by filters, into HTML. The following template will insert the value of <code>username</code> into the inputs value:</p>
<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">&lt;</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">&#123;&#123;</span>username<span class="token delimiter punctuation">&#125;&#125;</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>
<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">&lt;input type=&quot;text&quot; name=&quot;user&quot; value=&quot;&#123;&#123;username&#125;&#125;&quot;&gt;</span><br></pre></td></tr></table></figure>
<p>Values in output can be transformed by <strong>filter</strong>s before output. To append a string after the variable:</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;&#123;</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">&#125;&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<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">&#123;&#123; username | append: &quot;, welcome to LiquidJS!&quot; &#125;&#125;</span><br></pre></td></tr></table></figure>
<p>Filters can be chained:</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;&#123;</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">&#125;&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<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">&#123;&#123; username | append: &quot;, welcome to LiquidJS!&quot; | capitalize &#125;&#125;</span><br></pre></td></tr></table></figure>
<p>A complete list of filters supported by LiquidJS can be found <a href="../filters/overview.html">here</a>.</p>
<h2 id="Tags" class="article-heading"><a href="#Tags" class="headerlink" title="Tags"></a>Tags<a class="article-anchor" href="#Tags" aria-hidden="true"></a></h2><p><strong>Tags</strong> are used to control the template rendering process, manipulating template variables, inter-op with other templates, etc. For example <code>assign</code> can be used to define a variable which can be later used in the template:</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> <span class="token keyword">assign</span> foo <span class="token operator">=</span> <span class="token string">"FOO"</span> <span class="token delimiter punctuation">%&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<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">&#123;% assign foo = &quot;FOO&quot; %&#125;</span><br></pre></td></tr></table></figure>
<p>Typically tags appear in pairs with a start tag and a corresponding end tag. For example:</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> <span class="token keyword">if</span> foo <span class="token operator">==</span> <span class="token string">"FOO"</span> <span class="token delimiter punctuation">%&#125;</span></span>
Variable `foo` equals "FOO"
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> <span class="token keyword">else</span> <span class="token delimiter punctuation">%&#125;</span></span>
Variable `foo` not equals "FOO"
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> <span class="token keyword">endif</span> <span class="token delimiter punctuation">%&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<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">&#123;% if foo == &quot;FOO&quot; %&#125;</span><br><span class="line"> Variable `foo` equals &quot;FOO&quot;</span><br><span class="line">&#123;% else %&#125;</span><br><span class="line"> Variable `foo` not equals &quot;FOO&quot;</span><br><span class="line">&#123;% endif %&#125;</span><br></pre></td></tr></table></figure>
<p>A complete list of tags supported by LiquidJS can be found <a href="../tags/overview.html">here</a>.</p>
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.838Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="setup.html" class="article-footer-next" title="Setup"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+2 -2
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -116,7 +116,7 @@
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.838Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="dos.html" class="article-footer-prev" title="DoS"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="changelog.html" class="article-footer-next" title="Changelog"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+2 -2
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -106,7 +106,7 @@
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.838Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="plugins.html" class="article-footer-prev" title="Plugins"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="truthy-and-falsy.html" class="article-footer-next" title="Truthy and Falsy"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+8 -19
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -93,10 +93,7 @@
</header>
<div class="article-content" itemprop="articleBody">
<p>The <a href="/api/classes/Liquid.html">Liquid</a> constructor accepts a plain object as options to define the behavior of LiquidJS. All of these options are optional thus we can specify any of them, for example the <code>cache</code> option:</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token punctuation">&#123;</span> Liquid <span class="token punctuation">&#125;</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">&#123;</span>
<span class="token literal-property property">cache</span><span class="token operator">:</span> <span class="token boolean">true</span>
<span class="token punctuation">&#125;</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>
<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> &#123; <span class="title class_">Liquid</span> &#125; = <span class="built_in">require</span>(<span class="string">&#x27;liquidjs&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>(&#123;</span><br><span class="line"> <span class="attr">cache</span>: <span class="literal">true</span></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<blockquote class="note info"><strong class="note-title">API Document</strong><p>Following is an overview for all the options, for exact types and signatures please refer to <a href="https://liquidjs.com/api/interfaces/LiquidOptions.html" target="_self">LiquidOptions | API</a>.</p>
</blockquote>
@@ -112,10 +109,10 @@
<p>Note: for historical reasons, its named dynamicPartials but it also works for layouts.</p>
</blockquote>
<p><strong>dynamicPartials</strong> indicates whether or not to treat filename arguments in <a href="../tags/include.html">include</a>, <a href="../tags/render.html">render</a>, <a href="../tags/layout.html">layout</a> tags as a variable. Defaults to <code>true</code>. For example, render the following snippet with scope <code>&#123; file: &#39;foo.html&#39; &#125;</code> will include the <code>foo.html</code>:</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> <span class="token keyword">include</span> file <span class="token delimiter punctuation">%&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<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">&#123;% include file %&#125;</span><br></pre></td></tr></table></figure>
<p>Setting <code>dynamicPartials: false</code>, LiquidJS will try to include the file named <code>file</code>, which is weird but allows simpler syntax if your template relations are static:</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> <span class="token keyword">liquid</span> foo<span class="token punctuation">.</span>html <span class="token delimiter punctuation">%&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<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">&#123;% liquid foo.html %&#125;</span><br></pre></td></tr></table></figure>
<blockquote class="note warn"><strong class="note-title">Common Pitfall</strong><p>LiquidJS defaults this option to <code>true</code> to be compatible with shopify/liquid, but if youre from <a href="https://github.com/11ty/eleventy" rel="external nofollow noreferrer" target="_blank">eleventy</a> its set to <code>false</code> by default (see <a href="https://www.11ty.dev/docs/languages/liquid/#quoted-include-paths" rel="external nofollow noreferrer" target="_blank">Quoted Include Paths</a>) which I believe is trying to be compatible with Jekyll.</p>
</blockquote>
@@ -129,18 +126,10 @@
<li>Parameters are under <code>include</code> variable instead of current scope.</li>
</ul>
<p>For example in the following template, <code>name.html</code> is not quoted, <code>header</code> and <code>&quot;HEADER&quot;</code> are separated by <code>=</code>, and the <code>header</code> parameter is referenced by <code>include.header</code>. More details please check out <a href="../tags/include.html">include</a>.</p>
<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">&#123;%</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">%&#125;</span></span>
// article.html
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>article</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>header</span><span class="token punctuation">></span></span><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;&#123;</span><span class="token keyword">include</span><span class="token punctuation">.</span>header<span class="token delimiter punctuation">&#125;&#125;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>header</span><span class="token punctuation">></span></span>
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;&#123;</span><span class="token keyword">include</span><span class="token punctuation">.</span>content<span class="token delimiter punctuation">&#125;&#125;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</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>
<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">&#123;% include article.html header=&quot;HEADER&quot; content=&quot;CONTENT&quot; %&#125;</span><br><span class="line"></span><br><span class="line">// article.html</span><br><span class="line">&lt;article&gt;</span><br><span class="line"> &lt;header&gt;&#123;&#123;include.header&#125;&#125;&lt;/header&gt;</span><br><span class="line"> &#123;&#123;include.content&#125;&#125;</span><br><span class="line">&lt;/article&gt;</span><br></pre></td></tr></table></figure>
<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> defines the default extension name to be appended into filenames if the filename has no extension name. Defaults to <code>&#39;&#39;</code> which means its disabled by default. By setting it to <code>.liquid</code>:</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> <span class="token keyword">render</span> <span class="token string">"foo"</span> <span class="token delimiter punctuation">%&#125;</span></span> there's no extname, adds `.liquid` and loads foo.liquid
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> <span class="token keyword">render</span> <span class="token string">"foo.html"</span> <span class="token delimiter punctuation">%&#125;</span></span> there is an extname already, loads foo.html directly<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<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">&#123;% render &quot;foo&quot; %&#125; there&#x27;s no extname, adds `.liquid` and loads foo.liquid</span><br><span class="line">&#123;% render &quot;foo.html&quot; %&#125; there is an extname already, loads foo.html directly</span><br></pre></td></tr></table></figure>
<blockquote class="note info"><strong class="note-title">Legacy Versions</strong><p>Before 2.0.1, <code>extname</code> is set to <code>.liquid</code> by default. To change that you need to set <code>extname: ''</code> explicitly. See <a href="https://github.com/harttle/liquidjs/issues/41" rel="external nofollow noreferrer" target="_blank">#41</a> for details.</p>
</blockquote>
@@ -160,7 +149,7 @@
<p><strong>dateFormat</strong> is used to specify a default format to output dates. <code>%A, %B %-e, %Y at %-l:%M %P %z</code> will be used if not specified. For example, set <code>dateFormat: %Y-%m-%dT%H:%M:%S:%LZ</code> to output all dates in [JavaScript Date.toJson()][<a target="_blank" rel="noopener external nofollow noreferrer" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON]">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON]</a> format.</p>
<h2 id="Trimming" class="article-heading"><a href="#Trimming" class="headerlink" title="Trimming"></a>Trimming<a class="article-anchor" href="#Trimming" aria-hidden="true"></a></h2><p><strong>greedy</strong>, <strong>trimOutputLeft</strong>, <strong>trimOutputRight</strong>, <strong>trimTagLeft</strong>, <strong>trimTagRight</strong> options are used to eliminate extra newlines and indents in templates around Liquid Constructs. See <a href="./whitespace-control.html">Whitespace Control</a> for details.</p>
<h2 id="Delimiter" class="article-heading"><a href="#Delimiter" class="headerlink" title="Delimiter"></a>Delimiter<a class="article-anchor" href="#Delimiter" aria-hidden="true"></a></h2><p><strong>outputDelimiterLeft</strong>, <strong>outputDelimiterRight</strong>, <strong>tagDelimiterLeft</strong>, <strong>tagDelimiterRight</strong> are used to customize the delimiters for LiquidJS <a href="./intro-to-liquid.html">Tags and Filters</a>. For example with <code>outputDelimiterLeft: &lt;%=, outputDelimiterRight: %&gt;</code> we are able to avoid conflicts with other languages:</p>
<pre class="line-numbers language-ejs" data-language="ejs"><code class="language-ejs"><span class="token ejs language-ejs"><span class="token delimiter punctuation">&lt;%=</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>
<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">&lt;%= username | append: &quot;, welcome to LiquidJS!&quot; %&gt;</span><br></pre></td></tr></table></figure>
<h2 id="Strict" class="article-heading"><a href="#Strict" class="headerlink" title="Strict"></a>Strict<a class="article-anchor" href="#Strict" aria-hidden="true"></a></h2><p><strong>strictFilters</strong> is used to assert filter existence. If set to <code>false</code>, undefined filters will be skipped. Otherwise, undefined filters will cause a parse exception. Defaults to <code>false</code>.</p>
<p><strong>strictVariables</strong> is used to assert variable existence. If set to <code>false</code>, undefined variables will be rendered as empty string. Otherwise, undefined variables will cause a render exception. Defaults to <code>false</code>.</p>
@@ -173,7 +162,7 @@
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.838Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="setup.html" class="article-footer-prev" title="Setup"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="render-file.html" class="article-footer-next" title="Render Files"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+7 -51
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -93,75 +93,31 @@
</header>
<div class="article-content" itemprop="articleBody">
<h2 id="Access-Raw-Parameters" class="article-heading"><a href="#Access-Raw-Parameters" class="headerlink" title="Access Raw Parameters"></a>Access Raw Parameters<a class="article-anchor" href="#Access-Raw-Parameters" aria-hidden="true"></a></h2><p>As covered in <a href="/tutorials/register-filters-tags.html">Register Filters/Tags</a>, tag parameters is available on <code>tagToken.args</code> as a raw string. For example:</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// Usage: &#123;% random foo bar coo %&#125;</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">&#123;</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">&#123;</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">&#125;</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">&#123;</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">&#125;</span>
<span class="token punctuation">&#125;</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>
<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: &#123;% random foo bar coo %&#125;</span></span><br><span class="line"><span class="comment">// Output: &quot;foo&quot;, &quot;bar&quot; or &quot;coo&quot;</span></span><br><span class="line">engine.<span class="title function_">registerTag</span>(<span class="string">&#x27;random&#x27;</span>, &#123;</span><br><span class="line"> <span class="title function_">parse</span>(<span class="params">tagToken</span>) &#123;</span><br><span class="line"> <span class="comment">// tagToken.args === &quot;foo bar coo&quot;</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">&#x27; &#x27;</span>)</span><br><span class="line"> &#125;,</span><br><span class="line"> <span class="title function_">render</span>(<span class="params">context, emitter</span>) &#123;</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"> &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>Heres a JSFiddle version: <a target="_blank" rel="noopener external nofollow noreferrer" href="https://jsfiddle.net/ctj364up/2/">https://jsfiddle.net/ctj364up/2/</a></p>
<h2 id="Parse-Parameters-as-Values" class="article-heading"><a href="#Parse-Parameters-as-Values" class="headerlink" title="Parse Parameters as Values"></a>Parse Parameters as Values<a class="article-anchor" href="#Parse-Parameters-as-Values" aria-hidden="true"></a></h2><p>Sometimes we need more dynamic tags and want to pass values to the custom tag instead of static strings. Variables in LiquidJS can be literal (string, number, etc.) or a variable from current context scope.</p>
<p>The following modified template also contains 3 values to random from, but theyre values instead of static strings. The first one is string literal, second one is an identifier, third one is a property access sequence containing two identifiers.</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> random <span class="token string">"foo"</span> bar obj<span class="token punctuation">.</span>coo <span class="token delimiter punctuation">%&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<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">&#123;% random &quot;foo&quot; bar obj.coo %&#125;</span><br></pre></td></tr></table></figure>
<p>It can be tricky to parse all these cases manually, but theres a <a href="/api/classes/Tokenizer.html">Tokenizer</a> class in LiquidJS you can make use of.</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token punctuation">&#123;</span> Liquid<span class="token punctuation">,</span> Tokenizer<span class="token punctuation">,</span> evalToken <span class="token punctuation">&#125;</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">&#123;</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">&#123;</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">&#123;</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">&#125;</span>
<span class="token punctuation">&#125;</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">&#123;</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">&#125;</span>
<span class="token punctuation">&#125;</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>
<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"><span class="keyword">const</span> &#123; <span class="title class_">Liquid</span>, <span class="title class_">Tokenizer</span>, evalToken &#125; = <span class="built_in">require</span>(<span class="string">&#x27;liquidjs&#x27;</span>)</span><br><span class="line">engine.<span class="title function_">registerTag</span>(<span class="string">&#x27;random&#x27;</span>, &#123;</span><br><span class="line"> <span class="title function_">parse</span>(<span class="params">tagToken</span>) &#123;</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>()) &#123;</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"> &#125;</span><br><span class="line"> &#125;,</span><br><span class="line"> * <span class="title function_">render</span>(<span class="params">context, emitter</span>) &#123;</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"> &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>Calling this tag in scope <code>&#123; bar: &quot;bar&quot;, obj: &#123; coo: &quot;coo&quot; &#125; &#125;</code> yields exactly the same result as the first example. See this JSFiddle: <a target="_blank" rel="noopener external nofollow noreferrer" href="https://jsfiddle.net/ctj364up/3/">https://jsfiddle.net/ctj364up/3/</a></p>
<blockquote class="note info"><strong class="note-title">Async and Promises</strong><p>Async calls in LiquidJS are implemented by generators directly, for we can call generators in synchronous manner so this tag implementation is also valid for <code>renderSync()</code>, <code>parseAndRenderSync()</code>, <code>renderFileSync()</code>. If you need to await a promise in tag implementation, simply replace <code>await somePromise</code> with <code>yield somePromise</code> and keep <code>* render()</code> instead of <code>async render()</code> will do the trick. See <a href="/tutorials/sync-and-async.html">Sync and Async</a> for more details.</p>
</blockquote>
<h2 id="Parse-Key-Value-Pairs-as-Named-Parameters" class="article-heading"><a href="#Parse-Key-Value-Pairs-as-Named-Parameters" class="headerlink" title="Parse Key-Value Pairs as Named Parameters"></a>Parse Key-Value Pairs as Named Parameters<a class="article-anchor" href="#Parse-Key-Value-Pairs-as-Named-Parameters" aria-hidden="true"></a></h2><p>Named parameters become very handy when therere optional parameters or lots of parameters, in which case the order of parameters is not important. This is exactly what <a href="/api/classes/Hash.html">Hash</a> class is invented for.</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</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">%&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<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">&#123;% random from:2, to:max %&#125;</span><br></pre></td></tr></table></figure>
<p>In the above example, were trying to generate a random number in the range [2, max]. Well use <code>Hash</code> to parse <code>from</code> and <code>to</code> parameters.</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token punctuation">&#123;</span> Liquid<span class="token punctuation">,</span> Hash <span class="token punctuation">&#125;</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">&#123;</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">&#123;</span>
<span class="token comment">// parse the parameters structure into `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">&#125;</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">&#123;</span>
<span class="token comment">// evaluate the parameters in `context`</span>
<span class="token keyword">const</span> <span class="token punctuation">&#123;</span>from<span class="token punctuation">,</span> to<span class="token punctuation">&#125;</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">&#125;</span>
<span class="token punctuation">&#125;</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>
<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> &#123; <span class="title class_">Liquid</span>, <span class="title class_">Hash</span> &#125; = <span class="built_in">require</span>(<span class="string">&#x27;liquidjs&#x27;</span>)</span><br><span class="line"></span><br><span class="line">engine.<span class="title function_">registerTag</span>(<span class="string">&#x27;random&#x27;</span>, &#123;</span><br><span class="line"> <span class="title function_">parse</span>(<span class="params">tagToken</span>) &#123;</span><br><span class="line"> <span class="comment">// parse the parameters structure into `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"> &#125;,</span><br><span class="line"> * <span class="title function_">render</span>(<span class="params">context, emitter</span>) &#123;</span><br><span class="line"> <span class="comment">// evaluate the parameters in `context`</span></span><br><span class="line"> <span class="keyword">const</span> &#123;<span class="keyword">from</span>, to&#125; = <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"> &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>Rendering <code>&#123;% random from:2, to:max %&#125;</code> in scope <code>&#123; max: 10 &#125;</code> will generate a random number in the range [2, 10]. See this JSFiddle: <a target="_blank" rel="noopener external nofollow noreferrer" href="https://jsfiddle.net/ctj364up/4/">https://jsfiddle.net/ctj364up/4/</a></p>
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.838Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="access-scope-in-filters.html" class="article-footer-prev" title="Access Scope in Filters"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="render-tag-content.html" class="article-footer-next" title="Render Tag Content"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+6 -24
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -93,44 +93,26 @@
</header>
<div class="article-content" itemprop="articleBody">
<h2 id="Render-Partials" class="article-heading"><a href="#Render-Partials" class="headerlink" title="Render Partials"></a>Render Partials<a class="article-anchor" href="#Render-Partials" aria-hidden="true"></a></h2><p>For the following template files:</p>
<pre class="line-numbers language-none"><code class="language-none">&#x2F;&#x2F; file: color.liquid
color: &#39;&#123;&#123; color &#125;&#125;&#39; shape: &#39;&#123;&#123; shape &#125;&#125;&#39;
&#x2F;&#x2F; file: theme.liquid
&#123;% assign shape &#x3D; &#39;circle&#39; %&#125;
&#123;% render &#39;color.liquid&#39; %&#125;
&#123;% render &#39;color.liquid&#39; with &#39;red&#39; %&#125;
&#123;% render &#39;color.liquid&#39;, color: &#39;yellow&#39;, shape: &#39;square&#39; %&#125;<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>
<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">// file: color.liquid</span><br><span class="line">color: &#x27;&#123;&#123; color &#125;&#125;&#x27; shape: &#x27;&#123;&#123; shape &#125;&#125;&#x27;</span><br><span class="line"></span><br><span class="line">// file: theme.liquid</span><br><span class="line">&#123;% assign shape = &#x27;circle&#x27; %&#125;</span><br><span class="line">&#123;% render &#x27;color.liquid&#x27; %&#125;</span><br><span class="line">&#123;% render &#x27;color.liquid&#x27; with &#x27;red&#x27; %&#125;</span><br><span class="line">&#123;% render &#x27;color.liquid&#x27;, color: &#x27;yellow&#x27;, shape: &#x27;square&#x27; %&#125;</span><br></pre></td></tr></table></figure>
<p>The output will be:</p>
<pre class="line-numbers language-none"><code class="language-none">color: &#39;&#39; shape: &#39;circle&#39;
color: &#39;red&#39; shape: &#39;circle&#39;
color: &#39;yellow&#39; shape: &#39;square&#39;<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<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: &#x27;&#x27; shape: &#x27;circle&#x27;</span><br><span class="line">color: &#x27;red&#x27; shape: &#x27;circle&#x27;</span><br><span class="line">color: &#x27;yellow&#x27; shape: &#x27;square&#x27;</span><br></pre></td></tr></table></figure>
<p>More details please refer to the <a href="../tags/render.html">render</a> tag.</p>
<blockquote class="note tip"><strong class="note-title">The &quot;.liquid&quot; Extension</strong><p>The “.liquid” extension in <code>layout</code>, <code>render</code> and <code>include</code> can be omitted if Liquid instance is created using <code>extname: &quot;.liquid&quot;</code> option. See <a href="./options.html#extname">the extname option</a> for details.</p>
</blockquote>
<h2 id="Layout-Templates-Extends" class="article-heading"><a href="#Layout-Templates-Extends" class="headerlink" title="Layout Templates (Extends)"></a>Layout Templates (Extends)<a class="article-anchor" href="#Layout-Templates-Extends" aria-hidden="true"></a></h2><p>For the following template files:</p>
<pre class="line-numbers language-none"><code class="language-none">&#x2F;&#x2F; file: default-layout.liquid
Header
&#123;% block content %&#125;My default content&#123;% endblock %&#125;
Footer
&#x2F;&#x2F; file: page.liquid
&#123;% layout &quot;default-layout.liquid&quot; %&#125;
&#123;% block content %&#125;My page content&#123;% endblock %&#125;<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>
<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">// file: default-layout.liquid</span><br><span class="line">Header</span><br><span class="line">&#123;% block content %&#125;My default content&#123;% endblock %&#125;</span><br><span class="line">Footer</span><br><span class="line"></span><br><span class="line">// file: page.liquid</span><br><span class="line">&#123;% layout &quot;default-layout.liquid&quot; %&#125;</span><br><span class="line">&#123;% block content %&#125;My page content&#123;% endblock %&#125;</span><br></pre></td></tr></table></figure>
<p>The output of <code>page.liquid</code>:</p>
<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>
<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>
<p>More details please refer to the <a href="../tags/layout.html">layout</a> tag.</p>
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.838Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="render-file.html" class="article-footer-prev" title="Render Files"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="use-in-expressjs.html" class="article-footer-next" title="Use in Express.js"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+4 -16
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -95,22 +95,10 @@
<p>A number of tags and filters can be encapsulated into a <strong>plugin</strong>, which will be typically installed via npm. This article provides information about how to create and use a plugin.</p>
<h2 id="Write-a-Plugin" class="article-heading"><a href="#Write-a-Plugin" class="headerlink" title="Write a Plugin"></a>Write a Plugin<a class="article-anchor" href="#Write-a-Plugin" aria-hidden="true"></a></h2><p>A liquidjs plugin is simple function which takes the <a href="/api/classes/Liquid.html">Liquid class</a> as the first parameter and the Liquid instance for <code>this</code>. We can call liquidjs APIs on <code>this</code> to make certain changes, especially <a href="/harttle/liquidjs/wiki/Register-Filters-Tags">register filters and tags</a>.</p>
<p>Now well make a plugin to upper case every letter of the input, save the following snippet to <code>upup.js</code>:</p>
<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">&#123;</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">&#125;</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>
<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>) &#123;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="title function_">registerFilter</span>(<span class="string">&#x27;upup&#x27;</span>, <span class="function"><span class="params">x</span> =&gt;</span> x.<span class="title function_">toUpperCase</span>());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="Use-a-Plugin" class="article-heading"><a href="#Use-a-Plugin" class="headerlink" title="Use a Plugin"></a>Use a Plugin<a class="article-anchor" href="#Use-a-Plugin" aria-hidden="true"></a></h2><p>Simply pass the plugin function into the <code>.plugin()</code> method:</p>
<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">'&#123;&#123; "foo" | upup &#125;&#125;'</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 comment">// outputs "FOO"</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><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">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">&#x27;./upup.js&#x27;</span>));</span><br><span class="line">engine</span><br><span class="line"> .<span class="title function_">parseAndRender</span>(<span class="string">&#x27;&#123;&#123; &quot;foo&quot; | upup &#125;&#125;&#x27;</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">// outputs &quot;FOO&quot;</span></span><br></pre></td></tr></table></figure>
<h2 id="Plugin-List" class="article-heading"><a href="#Plugin-List" class="headerlink" title="Plugin List"></a>Plugin List<a class="article-anchor" href="#Plugin-List" aria-hidden="true"></a></h2><p>Since this library excludes certain features that are available on the Shopify platform but not on the <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/Shopify/liquid/">Shopify/liquid</a> repo, see <a href="/tutorials/differences.html">Differences with Shopify/liquid</a>.</p>
<p>Heres a list of plugins that backfill those features. Feel free to add yours, this file is publicly editable.</p>
@@ -121,7 +109,7 @@ engine
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.838Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="whitespace-control.html" class="article-footer-prev" title="Whitespace Control"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="operators.html" class="article-footer-next" title="Operators"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+7 -47
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -92,67 +92,27 @@
</header>
<div class="article-content" itemprop="articleBody">
<h2 id="Register-Tags" class="article-heading"><a href="#Register-Tags" class="headerlink" title="Register Tags"></a>Register Tags<a class="article-anchor" href="#Register-Tags" aria-hidden="true"></a></h2><pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token comment">// Usage: &#123;% upper name %&#125;</span>
<span class="token keyword">import</span> <span class="token punctuation">&#123;</span> Value<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">&#125;</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 punctuation">&#123;</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>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> <span class="token punctuation">&#123;</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">&#125;</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>ctx<span class="token operator">:</span> Context<span class="token punctuation">)</span> <span class="token punctuation">&#123;</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">&#125;</span>
<span class="token punctuation">&#125;</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></code></pre>
<h2 id="Register-Tags" class="article-heading"><a href="#Register-Tags" class="headerlink" title="Register Tags"></a>Register Tags<a class="article-anchor" href="#Register-Tags" aria-hidden="true"></a></h2><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// Usage: &#123;% upper name %&#125;</span></span><br><span class="line"><span class="keyword">import</span> &#123; <span class="title class_">Value</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> &#125; <span class="keyword">from</span> <span class="string">&#x27;liquidjs&#x27;</span></span><br><span class="line"></span><br><span class="line">engine.<span class="title function_">registerTag</span>(<span class="string">&#x27;upper&#x27;</span>, &#123;</span><br><span class="line"> <span class="attr">parse</span>: <span class="keyword">function</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>) &#123;</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"> &#125;,</span><br><span class="line"> <span class="attr">render</span>: <span class="keyword">function</span>*(<span class="attr">ctx</span>: <span class="title class_">Context</span>) &#123;</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">// &#x27;alice&#x27;</span></span><br><span class="line"> <span class="keyword">return</span> str.<span class="title function_">toUpperCase</span>() <span class="comment">// &#x27;ALICE&#x27;</span></span><br><span class="line"> &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<ul>
<li><code>parse</code>: Read tokens from <code>remainTokens</code> until your end token.</li>
<li><code>render</code>: Combine scope data with your parsed tokens into HTML string.</li>
</ul>
<p>For complex tag implementation, you can also provide a tag class:</p>
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token comment">// Usage: &#123;% upper name:"alice" %&#125;</span>
<span class="token keyword">import</span> <span class="token punctuation">&#123;</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">&#125;</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">&#123;</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">&#123;</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">&#125;</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">&#123;</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">&#125;</span>
<span class="token punctuation">&#125;</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>
<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: &#123;% upper name:&quot;alice&quot; %&#125;</span></span><br><span class="line"><span class="keyword">import</span> &#123; <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> &#125; <span class="keyword">from</span> <span class="string">&#x27;liquidjs&#x27;</span></span><br><span class="line"></span><br><span class="line">engine.<span class="title function_">registerTag</span>(<span class="string">&#x27;upper&#x27;</span>, <span class="keyword">class</span> <span class="title class_">UpperTag</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Tag</span> &#123;</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>) &#123;</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"> &#125;</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>) &#123;</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">// &#x27;ALICE&#x27;</span></span><br><span class="line"> &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<p>See existing tag implementations here: <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><br>See demo example here: <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/blob/master/demo/typescript/index.ts">https://github.com/harttle/liquidjs/blob/master/demo/typescript/index.ts</a></p>
<h2 id="Register-Filters" class="article-heading"><a href="#Register-Filters" class="headerlink" title="Register Filters"></a>Register Filters<a class="article-anchor" href="#Register-Filters" aria-hidden="true"></a></h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// Usage: &#123;&#123; name | upper &#125;&#125;</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>
<h2 id="Register-Filters" class="article-heading"><a href="#Register-Filters" class="headerlink" title="Register Filters"></a>Register Filters<a class="article-anchor" href="#Register-Filters" 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">// Usage: &#123;&#123; name | upper &#125;&#125;</span></span><br><span class="line">engine.<span class="title function_">registerFilter</span>(<span class="string">&#x27;upper&#x27;</span>, <span class="function"><span class="params">v</span> =&gt;</span> v.<span class="title function_">toUpperCase</span>())</span><br></pre></td></tr></table></figure>
<p>Filter arguments will be passed to the registered filter function, for example:</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// Usage: &#123;&#123; 1 | add: 2, 3 &#125;&#125;</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>
<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: &#123;&#123; 1 | add: 2, 3 &#125;&#125;</span></span><br><span class="line">engine.<span class="title function_">registerFilter</span>(<span class="string">&#x27;add&#x27;</span>, <span class="function">(<span class="params">initial, arg1, arg2</span>) =&gt;</span> initial + arg1 + arg2)</span><br></pre></td></tr></table></figure>
<p>See existing filter implementations here: <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>
<h2 id="Unregister-Tags-Filters" class="article-heading"><a href="#Unregister-Tags-Filters" class="headerlink" title="Unregister Tags/Filters"></a>Unregister Tags/Filters<a class="article-anchor" href="#Unregister-Tags-Filters" aria-hidden="true"></a></h2><p>In some cases its desirable to disable some tags/filters (see <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/issues/324">#324</a>), youll need to register a dummy tag/filter in which an corresponding Error throws.</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// disable a tag</span>
<span class="token keyword">const</span> disabledTag <span class="token operator">=</span> <span class="token punctuation">&#123;</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">&#123;</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">$&#123;</span>token<span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">&#125;</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">&#125;</span>
<span class="token punctuation">&#125;</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">// disable a filter</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">&#123;</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">&#123;</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">$&#123;</span>name<span class="token interpolation-punctuation punctuation">&#125;</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">&#125;</span>
<span class="token punctuation">&#125;</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>
<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">// disable a tag</span></span><br><span class="line"><span class="keyword">const</span> disabledTag = &#123;</span><br><span class="line"> <span class="attr">parse</span>: <span class="keyword">function</span>(<span class="params">token</span>) &#123;</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 &quot;<span class="subst">$&#123;token.name&#125;</span>&quot; disabled`</span>);</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line">engine.<span class="title function_">registerTag</span>(<span class="string">&#x27;include&#x27;</span>, disabledTag);</span><br><span class="line"></span><br><span class="line"><span class="comment">// disable a filter</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">disabledFilter</span>(<span class="params">name</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params"></span>) &#123;</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 &quot;<span class="subst">$&#123;name&#125;</span>&quot; disabled`</span>);</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line">engine.<span class="title function_">registerFilter</span>(<span class="string">&#x27;plus&#x27;</span>, <span class="title function_">disabledFilter</span>(<span class="string">&#x27;plus&#x27;</span>));</span><br></pre></td></tr></table></figure>
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.838Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="escaping.html" class="article-footer-prev" title="Escaping"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="access-scope-in-filters.html" class="article-footer-next" title="Access Scope in Filters"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+9 -52
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -94,31 +94,17 @@
<div class="article-content" itemprop="articleBody">
<p>For a typical project there could be a directory of template files, youll need to set the <a href="/api/interfaces/LiquidOptions.html#root">template root</a> and call <a href="/api/classes/Liquid.html#renderFile">renderFile</a> or <a href="/api/classes/Liquid.html#renderFileSync">renderFileSync</a> to render a specific file.</p>
<h2 id="Render-a-File" class="article-heading"><a href="#Render-a-File" class="headerlink" title="Render a File"></a>Render a File<a class="article-anchor" href="#Render-a-File" aria-hidden="true"></a></h2><p>For example you have a directory of templates like this:</p>
<pre class="line-numbers language-none"><code class="language-none">.
├── index.js
└── views&#x2F;
├── 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>
<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>
<p><code>hello.liquid</code> contains a single line `name: {{name}}`.<br>Now save the following contents into <code>index.js</code>:</p>
<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">&#123;</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">// root for layouts/includes lookup</span>
<span class="token literal-property property">extname</span><span class="token operator">:</span> <span class="token string">'.liquid'</span> <span class="token comment">// used for layouts/includes, defaults ""</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</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">&#123;</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'alice'</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span> <span class="token comment">// will read and render `views/hello.liquid`</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 comment">// outputs "Alice"</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>
<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> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>(&#123;</span><br><span class="line"> <span class="attr">root</span>: path.<span class="title function_">resolve</span>(__dirname, <span class="string">&#x27;views/&#x27;</span>), <span class="comment">// root for layouts/includes lookup</span></span><br><span class="line"> <span class="attr">extname</span>: <span class="string">&#x27;.liquid&#x27;</span> <span class="comment">// used for layouts/includes, defaults &quot;&quot;</span></span><br><span class="line">&#125;);</span><br><span class="line">engine</span><br><span class="line"> .<span class="title function_">renderFile</span>(<span class="string">&quot;hello&quot;</span>, &#123;<span class="attr">name</span>: <span class="string">&#x27;alice&#x27;</span>&#125;) <span class="comment">// will read and render `views/hello.liquid`</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">// outputs &quot;Alice&quot;</span></span><br></pre></td></tr></table></figure>
<p>Run <code>node index.js</code> and youll get output like this:</p>
<pre class="line-numbers language-none"><code class="language-none">&gt; node index.js
name: alice<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<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">&gt; node index.js</span><br><span class="line">name: alice</span><br></pre></td></tr></table></figure>
<h2 id="Template-Lookup" class="article-heading"><a href="#Template-Lookup" class="headerlink" title="Template Lookup"></a>Template Lookup<a class="article-anchor" href="#Template-Lookup" aria-hidden="true"></a></h2><p>Template files names passed to <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> APIs,<br>and <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> tags are resolved against <a href="/api/interfaces/LiquidOptions.html#root">the root option</a>.</p>
<p>It can be a string-typed path (see above example), or a list of root directories, in which case templates will be looked up in that order. e.g.</p>
<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">&#123;</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">&#125;</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>
<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>(&#123;</span><br><span class="line"> <span class="attr">root</span>: [<span class="string">&#x27;views/&#x27;</span>, <span class="string">&#x27;views/partials/&#x27;</span>],</span><br><span class="line"> <span class="attr">extname</span>: <span class="string">&#x27;.liquid&#x27;</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<blockquote class="note tip"><strong class="note-title">Relative Paths</strong><p>Relative paths in <code>root</code> will be resolved against <code>cwd()</code>.</p>
</blockquote>
@@ -134,50 +120,21 @@ name: alice<span aria-hidden="true" class="line-numbers-rows"><span></span><span
<li><a target="_blank" rel="noopener external nofollow noreferrer" href="https://example.com/bar/foo.liquid">https://example.com/bar/foo.liquid</a></li>
</ul>
<p>If fetch fails, a 404/500 error or network failures for example, an <code>ENOENT</code> error will be thrown.<br>Heres a demo for browsers: <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/tree/master/demo/browser">demo/browser</a>.</p>
<h2 id="Abstract-File-System" class="article-heading"><a href="#Abstract-File-System" class="headerlink" title="Abstract File System"></a>Abstract File System<a class="article-anchor" href="#Abstract-File-System" aria-hidden="true"></a></h2><p>LiquidJS defines an abstract file system interface in <a href="/api/interfaces/FS.html">src/fs/fs.ts</a> and the default implementation is <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/blob/master/src/fs/fs-impl.ts">src/fs/fs-impl.ts</a> for Node.js and <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/blob/master/src/fs/fs-impl-browser.ts">src/build/fs-impl-browser.ts</a> for the browser bundle.</p>
<h2 id="Abstract-File-System" class="article-heading"><a href="#Abstract-File-System" class="headerlink" title="Abstract File System"></a>Abstract File System<a class="article-anchor" href="#Abstract-File-System" aria-hidden="true"></a></h2><p>LiquidJS defines an <a href="/api/interfaces/FS.html">abstract file system interface</a> and the default implementation is <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/blob/master/src/fs/fs-impl.ts">src/fs/fs-impl.ts</a> for Node.js and <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/blob/master/src/fs/fs-impl-browser.ts">src/build/fs-impl-browser.ts</a> for the browser bundle.</p>
<p>The <code>Liquid</code> constructor provides a <a href="/api/interfaces/LiquidOptions.html#fs">fs</a> option to specify the file system implementation. Its supposed to be used to define customized template fetching logic, i.e. fetch template from a database table, like:</p>
<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">&#123;</span>
<span class="token literal-property property">fs</span><span class="token operator">:</span> <span class="token punctuation">&#123;</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">&#123;</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">&#125;</span><span class="token punctuation">,</span>
<span class="token keyword">async</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">&#123;</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">&#125;</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">&#123;</span>
<span class="token keyword">return</span> <span class="token boolean">true</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token keyword">async</span> <span class="token function">exists</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token boolean">true</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token function">contains</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token boolean">true</span>
<span class="token punctuation">&#125;</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">&#123;</span>
<span class="token keyword">return</span> file
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</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></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><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></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>(&#123;</span><br><span class="line"> <span class="attr">fs</span>: &#123;</span><br><span class="line"> <span class="title function_">readFileSync</span> (file) &#123;</span><br><span class="line"> <span class="keyword">return</span> db.<span class="title function_">model</span>(<span class="string">&#x27;Template&#x27;</span>).<span class="title function_">findByIdSync</span>(file).<span class="property">text</span></span><br><span class="line"> &#125;,</span><br><span class="line"> <span class="keyword">async</span> <span class="title function_">readFile</span> (file) &#123;</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">&#x27;Template&#x27;</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"> &#125;,</span><br><span class="line"> <span class="title function_">existsSync</span> () &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line"> &#125;,</span><br><span class="line"> <span class="keyword">async</span> <span class="title function_">exists</span> () &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line"> &#125;,</span><br><span class="line"> <span class="title function_">contains</span> () &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line"> &#125;,</span><br><span class="line"> <span class="title function_">resolve</span>(<span class="params">root, file, ext</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> file</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<blockquote class="note warn"><strong class="note-title">Path Traversal Vulnerability</strong><p>The default value of <code>contains()</code> always returns true. That means when specifying an abstract file system, youll need to provide a proper <code>contains()</code> to avoid expose such vulnerabilities.</p>
</blockquote>
<h2 id="In-memory-Template" class="article-heading"><a href="#In-memory-Template" class="headerlink" title="In-memory Template"></a>In-memory Template<a class="article-anchor" href="#In-memory-Template" aria-hidden="true"></a></h2><p>To facilitate rendering w/o files, theres a <code>templates</code> option to specify a mapping of filenames and their content. LiquidJS will read templates from the mapping.</p>
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><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">&#123;</span>
templates<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
<span class="token string-property property">'views/entry'</span><span class="token operator">:</span> <span class="token string">'header &#123;% include "../partials/footer" %&#125;'</span><span class="token punctuation">,</span>
<span class="token string-property property">'partials/footer'</span><span class="token operator">:</span> <span class="token string">'footer'</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
engine<span class="token punctuation">.</span><span class="token function">renderFileSync</span><span class="token punctuation">(</span><span class="token string">'views/entry'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token comment">// Result: 'header footer'</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>
<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></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>(&#123;</span><br><span class="line"> <span class="attr">templates</span>: &#123;</span><br><span class="line"> <span class="string">&#x27;views/entry&#x27;</span>: <span class="string">&#x27;header &#123;% include &quot;../partials/footer&quot; %&#125;&#x27;</span>,</span><br><span class="line"> <span class="string">&#x27;partials/footer&#x27;</span>: <span class="string">&#x27;footer&#x27;</span></span><br><span class="line"> &#125;</span><br><span class="line">&#125;)</span><br><span class="line">engine.<span class="title function_">renderFileSync</span>(<span class="string">&#x27;views/entry&#x27;</span>))</span><br><span class="line"><span class="comment">// Result: &#x27;header footer&#x27;</span></span><br></pre></td></tr></table></figure>
<p>Note that file system options like <code>root</code>, <code>layouts</code>, <code>partials</code>, <code>relativeReference</code> will be ignored when <code>templates</code> is specified.</p>
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.838Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="options.html" class="article-footer-prev" title="Options"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="partials-and-layouts.html" class="article-footer-next" title="Includes and Layouts"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+7 -89
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -94,101 +94,19 @@
<div class="article-content" itemprop="articleBody">
<p>Custom tags can have content template and can be nested. This article describes how to implement custom tags that consists of a <em>begin tag</em>, an <em>end tag</em>, and template content between them.</p>
<h2 id="Render-Tag-Content" class="article-heading"><a href="#Render-Tag-Content" class="headerlink" title="Render Tag Content"></a>Render Tag Content<a class="article-anchor" href="#Render-Tag-Content" aria-hidden="true"></a></h2><p>Well start with a simple tag <code>wrap</code> which wraps its content into a <code>&lt;div class=&quot;wrapper&quot;&gt;&lt;/div&gt;</code> element:</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> wrap <span class="token delimiter punctuation">%&#125;</span></span>
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;&#123;</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">&#125;&#125;</span></span>
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> endwrap <span class="token delimiter punctuation">%&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<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">&#123;% wrap %&#125;</span><br><span class="line"> &#123;&#123; &quot;hello world!&quot; | capitalize &#125;&#125;</span><br><span class="line">&#123;% endwrap %&#125;</span><br></pre></td></tr></table></figure>
<p>Expected output:</p>
<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">&lt;</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">&lt;/</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>
<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">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&#x27;wrapper&#x27;</span>&gt;</span></span><br><span class="line"> Hello world!</span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>Firstly, <a href="./register-filters-tags.html">register</a> a tag with name <code>wrap</code> and parse the content into <code>this.tpls</code>. Here in <code>parse(tagToken, remainTokens)</code>,</p>
<p>Firstly, [register][register-tags] a tag with name <code>wrap</code> and parse the content into <code>this.tpls</code>. Here in <code>parse(tagToken, remainTokens)</code>,</p>
<ul>
<li><code>tagToken</code> is current token <code>&#123;% wrap %&#125;</code>, and</li>
<li><code>remainTokens</code> is an array of all tokens following <code>&#123;% wrap %&#125;</code> until the end of this template file.</li>
<li><code>tagToken</code> is current token `</li>
</ul>
<p>Basically, what we need to do is take/<code>.shift()</code> enough tags from <code>remainTokens</code> until we got a <code>endwrap</code> token (the name can be arbitrary, but in convention, we need it to be <code>endwrap</code>). And if theres no <code>endwrap</code> until the end of template file, we need to throw an tag-not-closed <code>Error</code>.</p>
<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">&#123;</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">&#123;</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">&#123;</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">// we got the end tag! stop taking tokens</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">&#123;</span>
closed <span class="token operator">=</span> <span class="token boolean">true</span>
<span class="token keyword">break</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// parse token into template</span>
<span class="token comment">// parseToken() may consume more than 1 tokens</span>
<span class="token comment">// e.g. &#123;% if %&#125;...&#123;% endif %&#125;</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">&#125;</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">$&#123;</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">&#125;</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">&#125;</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">&#123;</span>
emitter<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token string">"&lt;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">"&lt;/div>"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</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> can be async, we need <code>yield</code> to wait it complete. More details on async in LiquidJS, please refer to <a href="./sync-and-async.html">Sync and Async</a>. Other parts of <code>render()</code> method is quite straightforward. Heres a JSFiddle version: <a target="_blank" rel="noopener external nofollow noreferrer" href="https://jsfiddle.net/por0zcn1/3/">https://jsfiddle.net/por0zcn1/3/</a></p>
<h2 id="Using-ParseStream" class="article-heading"><a href="#Using-ParseStream" class="headerlink" title="Using ParseStream"></a>Using ParseStream<a class="article-anchor" href="#Using-ParseStream" aria-hidden="true"></a></h2><p>When it comes to complex tags like <a href="../tags/for.html">for</a> and <a href="../tags/if.html">if</a>, the <code>parse()</code> can be very complicated. Theres a <a href="/api/classes/ParseStream.html">ParseStream</a> utility to organize the <code>parse()</code> in event-based style. Following is a re-written <code>parse()</code> using <code>ParseStream</code> and does exactly the same as above example.</p>
<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">&#123;</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">// note that we cannot use arrow function because we need `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">&#123;</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">&#125;</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">&#123;</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">$&#123;</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">&#125;</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">&#125;</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">&#125;</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>Heres a JSFiddle version: <a target="_blank" rel="noopener external nofollow noreferrer" href="https://jsfiddle.net/por0zcn1/4/">https://jsfiddle.net/por0zcn1/4/</a>. For simplicity, the following examples are implemented using <code>ParseStream</code>.</p>
<h2 id="Manipulate-the-Context" class="article-heading"><a href="#Manipulate-the-Context" class="headerlink" title="Manipulate the Context"></a>Manipulate the Context<a class="article-anchor" href="#Manipulate-the-Context" aria-hidden="true"></a></h2><p>The <code>wrap</code> tag above doesnt seem to be very useful, without using that tag we can render the content anyway. Now were going to implement a <code>repeat</code> tag to render the content 2 times (we can also add a <a href="./parse-parameters.html">parameter</a> to render arbitrary times).</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> repeat <span class="token delimiter punctuation">%&#125;</span></span>
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;&#123;</span> repeat<span class="token punctuation">.</span>i <span class="token delimiter punctuation">&#125;&#125;</span></span>. <span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;&#123;</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">&#125;&#125;</span></span>
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> endrepeat <span class="token delimiter punctuation">%&#125;</span></span>`<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<p>Expected outputs:</p>
<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>As youve noticed, theres an additional <code>repeat.i</code> in the context of <code>repeat</code>. That is implemented by manipulating the <em>Context</em>.</p>
<blockquote class="note info"><strong class="note-title">Context</strong><p><em>Context</em> defines the value of each variable in Liquid template. In LiquidJS, a <code>Context</code> consists of a stack of <code>Scope</code>s. A <em>Scope</em> is a plain object like the one specified in <code>engine.render(tpl, scope)</code>.</p>
</blockquote>
<p>Each time we enter a new <em>Context</em>, we need to push a new <em>Scope</em>. And when we finish rendering and exit the <em>Context</em>, we pop the <em>Scope</em> from the <em>Context</em>. As you can see in the following implementation:</p>
<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">&#123;</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">&#123;</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">&#123;</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">&#125;</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">&#123;</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">$&#123;</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">&#125;</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">&#125;</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">&#125;</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">&#123;</span>
<span class="token keyword">const</span> repeat <span class="token operator">=</span> <span class="token punctuation">&#123;</span> <span class="token literal-property property">i</span><span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">&#125;</span>
context<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span> repeat <span class="token punctuation">&#125;</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">&#125;</span>
<span class="token punctuation">&#125;</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>The <code>parse()</code> is exactly the same as <code>wrap</code> tag, we repeat the content simply by calling <code>.renderTemplates(this.tpls)</code> twice during <code>render()</code>. Heres the JSFiddle: <a target="_blank" rel="noopener external nofollow noreferrer" href="https://jsfiddle.net/por0zcn1/2/">https://jsfiddle.net/por0zcn1/2/</a></p>
<blockquote class="note warn"><strong class="note-title">Use Push & Pop in Pairs</strong><p><code>context.push()</code> and <code>context.pop()</code> have to be used in pairs. Failing to <code>pop()</code> the <em>Scope</em> you pushed will leak the <em>Scope</em> to latter templates and may corrupt the <em>Context</em> stack.</p>
</blockquote>
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.838Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="parse-parameters.html" class="article-footer-prev" title="Parse Parameters"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="drops.html" class="article-footer-next" title="Liquid Drops"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
@@ -197,7 +115,7 @@
<div id="article-toc-inner">
<div id="article-toc-inner-list">
<strong class="sidebar-title">Contents</strong>
<ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#Render-Tag-Content"><span class="toc-text">Render Tag Content</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Using-ParseStream"><span class="toc-text">Using ParseStream</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Manipulate-the-Context"><span class="toc-text">Manipulate the Context</span></a></li></ol>
<ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#Render-Tag-Content"><span class="toc-text">Render Tag Content</span></a></li></ol>
</div>
<a href="#" id="article-toc-top">Back to Top</a>
</div>
+12 -27
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -94,34 +94,21 @@
<div class="article-content" itemprop="articleBody">
<p>In case youre not familiar with Liquid Template Language, see <a href="./intro-to-liquid.html">Introduction to Liquid Template Language</a>.</p>
<h2 id="LiquidJS-in-Node-js" class="article-heading"><a href="#LiquidJS-in-Node-js" class="headerlink" title="LiquidJS in Node.js"></a>LiquidJS in Node.js<a class="article-anchor" href="#LiquidJS-in-Node-js" aria-hidden="true"></a></h2><p>Install via npm:</p>
<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 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-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> <span class="token punctuation">&#123;</span> Liquid <span class="token punctuation">&#125;</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">'&#123;&#123;name | capitalize&#125;&#125;'</span><span class="token punctuation">,</span> <span class="token punctuation">&#123;</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'alice'</span><span class="token punctuation">&#125;</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">// outputs '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>
<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> &#123; <span class="title class_">Liquid</span> &#125; = <span class="built_in">require</span>(<span class="string">&#x27;liquidjs&#x27;</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">&#x27;&#123;&#123;name | capitalize&#125;&#125;&#x27;</span>, &#123;<span class="attr">name</span>: <span class="string">&#x27;alice&#x27;</span>&#125;)</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">// outputs &#x27;Alice&#x27;</span></span><br></pre></td></tr></table></figure>
<blockquote class="note info"><strong class="note-title">Working Demo</strong><p>Heres a working demo for LiquidJS usage in 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>Type definitions for LiquidJS are also exported and published, which makes it more enjoyable for TypeScript projects:</p>
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token keyword">import</span> <span class="token punctuation">&#123;</span> Liquid <span class="token punctuation">&#125;</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">'&#123;&#123;name | capitalize&#125;&#125;'</span><span class="token punctuation">,</span> <span class="token punctuation">&#123;</span>name<span class="token operator">:</span> <span class="token string">'alice'</span><span class="token punctuation">&#125;</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">// outputs '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>
<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> &#123; <span class="title class_">Liquid</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;liquidjs&#x27;</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">&#x27;&#123;&#123;name | capitalize&#125;&#125;&#x27;</span>, &#123;<span class="attr">name</span>: <span class="string">&#x27;alice&#x27;</span>&#125;)</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">// outputs &#x27;Alice&#x27;</span></span><br></pre></td></tr></table></figure>
<blockquote class="note info"><strong class="note-title">Working Demo</strong><p>Heres a working demo for LiquidJS usage in 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="LiquidJS-in-Browsers" class="article-heading"><a href="#LiquidJS-in-Browsers" class="headerlink" title="LiquidJS in Browsers"></a>LiquidJS in Browsers<a class="article-anchor" href="#LiquidJS-in-Browsers" aria-hidden="true"></a></h2><p>Pre-built UMD bundles are also available:</p>
<pre class="line-numbers language-markup" data-language="markup"><code class="language-markup"><span class="token comment">&lt;!--for production--></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&lt;/</span>script</span><span class="token punctuation">></span></span>
<span class="token comment">&lt;!--for development--></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</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">&lt;/</span>script</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<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><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--for production--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;https://cdn.jsdelivr.net/npm/liquidjs/dist/liquid.browser.min.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!--for development--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;https://cdn.jsdelivr.net/npm/liquidjs/dist/liquid.browser.umd.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<blockquote class="note info"><strong class="note-title">Working Demo</strong><p>Heres a living demo on jsFiddle: <a href="https://jsfiddle.net/pd4jhzLs/1/" rel="external nofollow noreferrer" target="_blank">jsfiddle.net/pd4jhzLs/1/</a>, and the source code is also available in <a href="https://github.com/harttle/liquidjs/blob/master/demo/browser/" rel="external nofollow noreferrer" target="_blank">liquidjs/demo/browser/</a>.</p>
</blockquote>
@@ -130,32 +117,30 @@ engine
</blockquote>
<h2 id="LiquidJS-in-CLI" class="article-heading"><a href="#LiquidJS-in-CLI" class="headerlink" title="LiquidJS in CLI"></a>LiquidJS in CLI<a class="article-anchor" href="#LiquidJS-in-CLI" aria-hidden="true"></a></h2><p>LiquidJS can also be used to render a template directly from CLI using <code>npx</code>:</p>
<pre class="line-numbers language-bash" data-language="bash"><code class="language-bash">npx liquidjs <span class="token parameter variable">--template</span> <span class="token string">'&#123;&#123;"hello" | capitalize&#125;&#125;'</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<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">npx liquidjs --template <span class="string">&#x27;&#123;&#123;&quot;hello&quot; | capitalize&#125;&#125;&#x27;</span></span><br></pre></td></tr></table></figure>
<p>You can either pass the template inline (as shown above) or you can read it from a file by using the <code>@</code> character followed by a path, like so:</p>
<pre class="line-numbers language-bash" data-language="bash"><code class="language-bash">npx liquidjs <span class="token parameter variable">--template</span> @./some-template.liquid<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<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">npx liquidjs --template @./some-template.liquid</span><br></pre></td></tr></table></figure>
<p>You can also use the <code>@-</code> syntax to read the template from <code>stdin</code>:</p>
<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">'&#123;&#123;"hello" | capitalize&#125;&#125;'</span> <span class="token operator">|</span> npx liquidjs <span class="token parameter variable">--template</span> @-<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<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">&#x27;&#123;&#123;&quot;hello&quot; | capitalize&#125;&#125;&#x27;</span> | npx liquidjs --template @-</span><br></pre></td></tr></table></figure>
<p>A context can be passed in the same ways (i.e. inline, from a path or piped through <code>stdin</code>). The following three are equivalent:</p>
<pre class="line-numbers language-bash" data-language="bash"><code class="language-bash">npx liquidjs <span class="token parameter variable">--template</span> <span class="token string">'Hello, &#123;&#123; name &#125;&#125;!'</span> <span class="token parameter variable">--context</span> <span class="token string">'&#123;"name": "Snake"&#125;'</span>
npx liquidjs <span class="token parameter variable">--template</span> <span class="token string">'Hello, &#123;&#123; name &#125;&#125;!'</span> <span class="token parameter variable">--context</span> @./some-context.json
<span class="token builtin class-name">echo</span> <span class="token string">'&#123;"name": "Snake"&#125;'</span> <span class="token operator">|</span> npx liquidjs <span class="token parameter variable">--template</span> <span class="token string">'Hello, &#123;&#123; name &#125;&#125;!'</span> <span class="token parameter variable">--context</span> @-<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<figure class="highlight bash"><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">npx liquidjs --template <span class="string">&#x27;Hello, &#123;&#123; name &#125;&#125;!&#x27;</span> --context <span class="string">&#x27;&#123;&quot;name&quot;: &quot;Snake&quot;&#125;&#x27;</span></span><br><span class="line">npx liquidjs --template <span class="string">&#x27;Hello, &#123;&#123; name &#125;&#125;!&#x27;</span> --context @./some-context.json</span><br><span class="line"><span class="built_in">echo</span> <span class="string">&#x27;&#123;&quot;name&quot;: &quot;Snake&quot;&#125;&#x27;</span> | npx liquidjs --template <span class="string">&#x27;Hello, &#123;&#123; name &#125;&#125;!&#x27;</span> --context @-</span><br></pre></td></tr></table></figure>
<p>Note that you can only use the <code>stdin</code> specifier <code>@-</code> for a single argument. If you try to use it for both <code>--template</code> and <code>--context</code> you will get an error.</p>
<p>The rendered output is written to <code>stdout</code> by default, but you can also specify an output file (if the file exists, it will be overwritten):</p>
<pre class="line-numbers language-bash" data-language="bash"><code class="language-bash">npx liquidjs <span class="token parameter variable">--template</span> <span class="token string">'&#123;&#123;"hello" | capitalize&#125;&#125;'</span> <span class="token parameter variable">--output</span> ./hello.txt<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<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">npx liquidjs --template <span class="string">&#x27;&#123;&#123;&quot;hello&quot; | capitalize&#125;&#125;&#x27;</span> --output ./hello.txt</span><br></pre></td></tr></table></figure>
<p>You can also pass a number of options to customize template rendering behavior. For example, the <code>--js-truthy</code> option can be used to enable JavaScript truthiness:</p>
<pre class="line-numbers language-bash" data-language="bash"><code class="language-bash">npx liquidjs <span class="token parameter variable">--template</span> @./some-template.liquid --js-truthy<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<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">npx liquidjs --template @./some-template.liquid --js-truthy</span><br></pre></td></tr></table></figure>
<p>Most of the <a href="./options.html">options available through the JavaScript API</a> are also available from the CLI. For help on available options, use <code>npx liquidjs --help</code>.</p>
<h2 id="Miscellaneous" class="article-heading"><a href="#Miscellaneous" class="headerlink" title="Miscellaneous"></a>Miscellaneous<a class="article-anchor" href="#Miscellaneous" aria-hidden="true"></a></h2><p>A ReactJS demo is also added by <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/stevenanthonyrevo">@stevenanthonyrevo</a>, see <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-16T15:41:05.838Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="intro-to-liquid.html" class="article-footer-prev" title="Intro to Liquid"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="options.html" class="article-footer-next" title="Options"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+6 -52
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -110,21 +110,7 @@
<li><code>evalValueSync()</code></li>
</ul>
<h2 id="Implement-Sync-Compatible-Tags" class="article-heading"><a href="#Implement-Sync-Compatible-Tags" class="headerlink" title="Implement Sync-Compatible Tags"></a>Implement Sync-Compatible Tags<a class="article-anchor" href="#Implement-Sync-Compatible-Tags" aria-hidden="true"></a></h2><p>LiquidJS uses a generator-based async implementation to support both async and sync in one piece of tag implementation. For example, below <code>UpperTag</code> can be used in both <code>engine.renderSync()</code> and <code>engine.render()</code>.</p>
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token keyword">import</span> <span class="token punctuation">&#123;</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">&#125;</span> <span class="token keyword">from</span> <span class="token string">'liquidjs'</span>
<span class="token comment">// Usage: &#123;% upper "alice" %&#125;</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">&#123;</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">&#123;</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">&#125;</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">&#123;</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">&#125;</span>
<span class="token punctuation">&#125;</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>
<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> &#123; <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> &#125; <span class="keyword">from</span> <span class="string">&#x27;liquidjs&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Usage: &#123;% upper &quot;alice&quot; %&#125;</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">&#x27;upper&#x27;</span>, <span class="keyword">class</span> <span class="title class_">UpperTag</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Tag</span> &#123;</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>) &#123;</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"> &#125;</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>) &#123;</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"> &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>All builtin tags are implemented this way and safe to use in both sync and async (Ill call it <em>sync-compatible</em>). To make your custom tag <em>sync-compatible</em>, youll need to:</p>
<ul>
@@ -133,54 +119,22 @@ engine<span class="token punctuation">.</span><span class="token function">regis
<li>do not call any APIs that returns a Promise.</li>
</ul>
<h2 id="Call-APIs-that-return-a-Promise" class="article-heading"><a href="#Call-APIs-that-return-a-Promise" class="headerlink" title="Call APIs that return a Promise"></a>Call APIs that return a Promise<a class="article-anchor" href="#Call-APIs-that-return-a-Promise" aria-hidden="true"></a></h2><p>But LiquidJS is Promise-friendly, right? You can still call Promise-based functions and wait for that Promise within tag implementations. Just replace <code>await</code> with <code>yield</code>. e.g. were calling <code>fs.readFile()</code> which returns a <code>Promise</code>:</p>
<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">&#123;</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">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<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>) &#123;</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">&#x27;utf8&#x27;</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">&#125;</span><br></pre></td></tr></table></figure>
<p>Now that this <code>* render()</code> calls an API that returns a Promise, so its no longer <em>sync-compatible</em>.</p>
<blockquote class="note info"><strong class="note-title">Non Sync-Compatible Tags</strong><p>Non <em>sync-compatible</em> tags are also valid tags, will work just fine for asynchronous API calls. When called synchronously, tags that return a <code>Promise</code> will be rendered as <code>[object Promise]</code>.</p>
</blockquote>
<h2 id="Convert-LiquidJS-async-Generator-to-Promise" class="article-heading"><a href="#Convert-LiquidJS-async-Generator-to-Promise" class="headerlink" title="Convert LiquidJS async Generator to Promise"></a>Convert LiquidJS async Generator to Promise<a class="article-anchor" href="#Convert-LiquidJS-async-Generator-to-Promise" aria-hidden="true"></a></h2><p>You can convert a Generator to Promise by <a href="/api/functions/toPromise.html">toPromise</a>, for example:</p>
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token keyword">import</span> <span class="token punctuation">&#123;</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">&#125;</span> <span class="token keyword">from</span> <span class="token string">'liquidjs'</span>
<span class="token comment">// Usage: &#123;% upper "alice" %&#125;</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">&#123;</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">&#123;</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">&#125;</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">&#123;</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">&#125;</span>
<span class="token punctuation">&#125;</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>
<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> &#123; <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 &#125; <span class="keyword">from</span> <span class="string">&#x27;liquidjs&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Usage: &#123;% upper &quot;alice&quot; %&#125;</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">&#x27;upper&#x27;</span>, <span class="keyword">class</span> <span class="title class_">UpperTag</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Tag</span> &#123;</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>) &#123;</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"> &#125;</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>) &#123;</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"> &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="Async-only-Tags" class="article-heading"><a href="#Async-only-Tags" class="headerlink" title="Async only Tags"></a>Async only Tags<a class="article-anchor" href="#Async-only-Tags" aria-hidden="true"></a></h2><p>If your tag is intend to be used only asynchronously, it can be declared as <code>async render()</code> so you can use <code>await</code> in its implementation directly:</p>
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token keyword">import</span> <span class="token punctuation">&#123;</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">&#125;</span> <span class="token keyword">from</span> <span class="token string">'liquidjs'</span>
<span class="token comment">// Usage: &#123;% upper "alice" %&#125;</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">&#123;</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">&#123;</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">&#125;</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">&#123;</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">&lt;h1></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>title<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">&lt;/h1></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</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>
<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> &#123; 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> &#125; <span class="keyword">from</span> <span class="string">&#x27;liquidjs&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Usage: &#123;% upper &quot;alice&quot; %&#125;</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">&#x27;upper&#x27;</span>, <span class="keyword">class</span> <span class="title class_">UpperTag</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Tag</span> &#123;</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>) &#123;</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"> &#125;</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>) &#123;</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">`&lt;h1&gt;<span class="subst">$&#123;title&#125;</span>&lt;/h1&gt;`</span>)</span><br><span class="line"> &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.838Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="drops.html" class="article-footer-prev" title="Liquid Drops"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="whitespace-control.html" class="article-footer-next" title="Whitespace Control"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+2 -2
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -226,7 +226,7 @@
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.838Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="operators.html" class="article-footer-prev" title="Operators"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="dos.html" class="article-footer-next" title="DoS"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+7 -28
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -93,48 +93,27 @@
</header>
<div class="article-content" itemprop="articleBody">
<p>LiquidJS is compatible to the <a target="_blank" rel="noopener external nofollow noreferrer" href="https://expressjs.com/en/resources/template-engines.html">express template engines</a>. You can set liquidjs instance to the <a target="_blank" rel="noopener external nofollow noreferrer" href="https://expressjs.com/en/guide/using-template-engines.html">view engine</a> option:</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> <span class="token punctuation">&#123;</span> Liquid <span class="token punctuation">&#125;</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">// register liquid engine</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">// specify the views directory</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">// set liquid to default</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>
<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> &#123; <span class="title class_">Liquid</span> &#125; = <span class="built_in">require</span>(<span class="string">&#x27;liquidjs&#x27;</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">// register liquid engine</span></span><br><span class="line">app.<span class="title function_">engine</span>(<span class="string">&#x27;liquid&#x27;</span>, engine.<span class="title function_">express</span>()); </span><br><span class="line">app.<span class="title function_">set</span>(<span class="string">&#x27;views&#x27;</span>, <span class="string">&#x27;./views&#x27;</span>); <span class="comment">// specify the views directory</span></span><br><span class="line">app.<span class="title function_">set</span>(<span class="string">&#x27;view engine&#x27;</span>, <span class="string">&#x27;liquid&#x27;</span>); <span class="comment">// set liquid to default</span></span><br></pre></td></tr></table></figure>
<blockquote class="note info"><strong class="note-title">Working Demo</strong><p>Heres a working demo for LiquidJS usage in Express.js: <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="Template-Lookup" class="article-heading"><a href="#Template-Lookup" class="headerlink" title="Template Lookup"></a>Template Lookup<a class="article-anchor" href="#Template-Lookup" aria-hidden="true"></a></h2><p>The <a href="/api/interfaces/LiquidOptions.html#root">root</a> option will continue to work as templates root, as you can see in <a href="./render-a-file.html">Render A Template File</a>. Additionally, the <a target="_blank" rel="noopener external nofollow noreferrer" href="https://expressjs.com/en/guide/using-template-engines.html"><code>views</code></a> option in express.js (as shown above) will also be respected. Say you have a template directory like:</p>
<pre class="line-numbers language-none"><code class="language-none">.
├── views1&#x2F;
│ └── hello.liquid
└── views2&#x2F;
└── world.liquid<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<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>
<p>And youre setting template root for liquidjs to <code>views1</code> and expressjs to <code>views2</code>:</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> <span class="token punctuation">&#123;</span> Liquid <span class="token punctuation">&#125;</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">&#123;</span>
<span class="token literal-property property">root</span><span class="token operator">:</span> <span class="token string">'./views1/'</span>
<span class="token punctuation">&#125;</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> <span class="token comment">// specify the views directory</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">// set liquid to default</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>
<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> &#123; <span class="title class_">Liquid</span> &#125; = <span class="built_in">require</span>(<span class="string">&#x27;liquidjs&#x27;</span>);</span><br><span class="line"><span class="keyword">var</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>(&#123;</span><br><span class="line"> <span class="attr">root</span>: <span class="string">&#x27;./views1/&#x27;</span></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">engine</span>(<span class="string">&#x27;liquid&#x27;</span>, engine.<span class="title function_">express</span>()); </span><br><span class="line">app.<span class="title function_">set</span>(<span class="string">&#x27;views&#x27;</span>, <span class="string">&#x27;./views2&#x27;</span>); <span class="comment">// specify the views directory</span></span><br><span class="line">app.<span class="title function_">set</span>(<span class="string">&#x27;view engine&#x27;</span>, <span class="string">&#x27;liquid&#x27;</span>); <span class="comment">// set liquid to default</span></span><br></pre></td></tr></table></figure>
<p>Both of <code>hello.liquid</code> and <code>world.liquid</code> can be resolved and rendered:</p>
<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>
<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">&#x27;hello&#x27;</span>)</span><br><span class="line">res.<span class="title function_">render</span>(<span class="string">&#x27;world&#x27;</span>)</span><br></pre></td></tr></table></figure>
<h2 id="Caching" class="article-heading"><a href="#Caching" class="headerlink" title="Caching"></a>Caching<a class="article-anchor" href="#Caching" aria-hidden="true"></a></h2><p>Simply setting the <a href="/api/interfaces/LiquidOptions.html#cache">cache option</a> to true will enable template caching, as explained in <a href="./caching.html">Caching</a>. Its recommended to enable cache in production environment, which can be done by:</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> <span class="token punctuation">&#123;</span> Liquid <span class="token punctuation">&#125;</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">&#123;</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">&#125;</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>
<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> &#123; <span class="title class_">Liquid</span> &#125; = <span class="built_in">require</span>(<span class="string">&#x27;liquidjs&#x27;</span>);</span><br><span class="line"><span class="keyword">var</span> engine = <span class="keyword">new</span> <span class="title class_">Liquid</span>(&#123;</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">&#x27;production&#x27;</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.838Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="partials-and-layouts.html" class="article-footer-prev" title="Includes and Layouts"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="caching.html" class="article-footer-next" title="Caching"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>
+7 -10
View File
@@ -38,7 +38,7 @@
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 5.4.0"></head>
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
@@ -94,19 +94,16 @@
<div class="article-content" itemprop="articleBody">
<p>To keep source code neat and indented, were adding spaces to our templates. LiquidJS offers whitespace control capabilities to eliminate these unwanted whitespaces in output HTML.</p>
<h2 id="via-Markups" class="article-heading"><a href="#via-Markups" class="headerlink" title="via Markups"></a>via Markups<a class="article-anchor" href="#via-Markups" aria-hidden="true"></a></h2><p>By default, all tags and output markups lines will generate a NL (<code>\n</code>), and whitespaces if theres any indentation. For example:</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> author <span class="token operator">=</span> <span class="token string">"harttle"</span> <span class="token delimiter punctuation">%&#125;</span></span>
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;&#123;</span> author <span class="token delimiter punctuation">&#125;&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<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">&#123;% author = &quot;harttle&quot; %&#125;</span><br><span class="line">&#123;&#123; author &#125;&#125;</span><br></pre></td></tr></table></figure>
<p>Outputs (note the blank link):</p>
<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>
<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>
<p>We can include hyphens in your tag syntax (<code>{{-`, `-}}`, `{%-</code>, <code>-%&#125;</code>) to strip whitespace from left or right. For example:</p>
<pre class="line-numbers language-liquid" data-language="liquid"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;%</span> <span class="token keyword">assign</span> author <span class="token operator">=</span> <span class="token string">"harttle"</span> <span class="token delimiter punctuation">-%&#125;</span></span>
<span class="token liquid language-liquid"><span class="token delimiter punctuation">&#123;&#123;</span> author <span class="token delimiter punctuation">&#125;&#125;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<p>We can include hyphens in your tag syntax (<code>{{-</code>, <code>-&#125;&#125;</code>, <code>{%-</code>, <code>-%&#125;</code>) to strip whitespace from left or right. For example:</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">&#123;% assign author = &quot;harttle&quot; -%&#125;</span><br><span class="line">&#123;&#123; author &#125;&#125;</span><br></pre></td></tr></table></figure>
<p>Outputs:</p>
<pre class="line-numbers language-none"><code class="language-none">harttle<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<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>
<p>In this case, the <code>-%&#125;</code> strips the whitespace from the right side of the <code>assign</code> tag.</p>
<h2 id="via-Options" class="article-heading"><a href="#via-Options" class="headerlink" title="via Options"></a>via Options<a class="article-anchor" href="#via-Options" aria-hidden="true"></a></h2><p>Alternatively, LiquidJS provides these per engine options to enable whitespace control without sweeping changes of your templates:</p>
@@ -121,7 +118,7 @@ harttle<span aria-hidden="true" class="line-numbers-rows"><span></span><span></s
</div>
<footer class="article-footer">
<time class="article-footer-updated" datetime="2024-08-16T15:41:05.838Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<time class="article-footer-updated" datetime="2024-08-16T16:55:41.721Z" itemprop="dateModified">Last updated: 2024-08-16</time>
<a href="sync-and-async.html" class="article-footer-prev" title="Sync and Async"><i class="icon-chevron-left"></i><span>Prev</span></a><a href="plugins.html" class="article-footer-next" title="Plugins"><span>Next</span><i class="icon-chevron-right"></i></a>
</footer>
</div>