Files
liquidjs/tutorials/drops.html
T

320 lines
41 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head prefix="og: https://ogp.me/ns#">
<meta charset="utf-8">
<title>Liquid Drops | LiquidJS</title>
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="LiquidJS is a simple, expressive and safe Shopify / GitHub Pages compatible template engine in pure JavaScript.">
<link rel="dns-prefetch" href="https://cdn.jsdelivr.net/">
<link rel="manifest" href="/manifest.json">
<!-- Canonical links -->
<link rel="canonical" href="https://liquidjs.com/tutorials/drops.html">
<!-- Alternative links -->
<link rel="alternative" hreflang="en" href="https://liquidjs.com/tutorials/drops">
<link rel="alternative" hreflang="zh-cn" href="https://liquidjs.com/zh-cn/tutorials/drops">
<!-- Icon -->
<link rel="apple-touch-icon" sizes="57x57" href="../icon/apple-touch-icon-57x57.png">
<link rel="apple-touch-icon" sizes="114x114" href="../icon/apple-touch-icon-114x114.png">
<link rel="apple-touch-icon" sizes="72x72" href="../icon/apple-touch-icon-72x72.png">
<link rel="apple-touch-icon" sizes="144x144" href="../icon/apple-touch-icon-144x144.png">
<link rel="apple-touch-icon" sizes="60x60" href="../icon/apple-touch-icon-60x60.png">
<link rel="apple-touch-icon" sizes="120x120" href="../icon/apple-touch-icon-120x120.png">
<link rel="apple-touch-icon" sizes="76x76" href="../icon/apple-touch-icon-76x76.png">
<link rel="apple-touch-icon" sizes="152x152" href="../icon/apple-touch-icon-152x152.png">
<link rel="icon" type="image/png" href="../icon/favicon-196x196.png" sizes="196x196">
<link rel="icon" type="image/png" href="../icon/favicon-160x160.png" sizes="160x160">
<link rel="icon" type="image/png" href="../icon/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="../icon/favicon-16x16.png" sizes="16x16">
<link rel="icon" type="image/png" href="../icon/favicon-32x32.png" sizes="32x32">
<meta name="msapplication-TileColor" content="#2f83cd">
<meta name="msapplication-TileImage" content="../icon/mstile-144x144.png">
<link rel="stylesheet" href="../css/navy.css">
<link rel="alternate" href="../atom.xml" title="LiquidJS" type="application/atom+xml">
<meta name="generator" content="Hexo 7.3.0"></head>
<body>
<div id="container">
<header id="header" class="wrapper">
<div id="header-inner" class="inner">
<h1 id="logo-wrap">
<a href="../index.html" id="logo">LiquidJS</a>
</h1>
<nav id="main-nav">
<a href="../tutorials/intro-to-liquid.html" class="main-nav-link">Tutorials</a><a href="../tags/overview.html" class="main-nav-link">Tags</a><a href="../filters/overview.html" class="main-nav-link">Filters</a><a href="../playground.html" class="main-nav-link">Playground</a><a href="../api/classes/Liquid.html" class="main-nav-link">API</a>
<div id="search-input-wrap">
<i id="search-input-icon" class="icon-search"></i>
<input type="search" id="search-input" placeholder="Search...">
</div>
</nav>
<div class="main-nav-link icon-nav-link">
<label><i class="icon-network"></i> <span class="icon-nav-title">English</span></label>
<select id="lang-select" data-canonical="tutorials/drops.html">
<option value="en" selected>English</option>
<option value="zh-cn">简体中文</option>
</select>
</div>
<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs" class="main-nav-link icon-nav-link"><i class="icon-github"></i> <span class="icon-nav-title">GitHub</span></a>
<a id="mobile-nav-toggle">
<span class="mobile-nav-toggle-bar"></span>
<span class="mobile-nav-toggle-bar"></span>
<span class="mobile-nav-toggle-bar"></span>
</a>
</div>
</header>
<div id="content-wrap">
<div id="content" class="wrapper">
<div id="content-inner">
<aside id="sidebar" role="navigation">
<div class="inner">
<strong class="sidebar-title">Getting Started</strong><a href="intro-to-liquid.html" class="sidebar-link">Intro to Liquid</a><a href="setup.html" class="sidebar-link">Setup</a><a href="options.html" class="sidebar-link">Options</a><a href="render-file.html" class="sidebar-link">Render Files</a><a href="partials-and-layouts.html" class="sidebar-link">Includes and Layouts</a><a href="use-in-expressjs.html" class="sidebar-link">Use in Express.js</a><strong class="sidebar-title">Advanced</strong><a href="caching.html" class="sidebar-link">Caching</a><a href="escaping.html" class="sidebar-link">Escaping</a><a href="register-filters-tags.html" class="sidebar-link">Register Filters/Tags</a><a href="access-scope-in-filters.html" class="sidebar-link">Access Scope in Filters</a><a href="parse-parameters.html" class="sidebar-link">Parse Parameters</a><a href="render-tag-content.html" class="sidebar-link">Render Tag Content</a><a href="drops.html" class="sidebar-link current">Liquid Drops</a><a href="sync-and-async.html" class="sidebar-link">Sync and Async</a><a href="whitespace-control.html" class="sidebar-link">Whitespace Control</a><a href="plugins.html" class="sidebar-link">Plugins</a><a href="operators.html" class="sidebar-link">Operators</a><a href="truthy-and-falsy.html" class="sidebar-link">Truthy and Falsy</a><a href="dos.html" class="sidebar-link">DoS</a><a href="static-analysis.html" class="sidebar-link">Static Analysis</a><strong class="sidebar-title">Miscellaneous</strong><a href="migrate-to-9.html" class="sidebar-link">Migrate to LiquidJS 9</a><a href="changelog.html" class="sidebar-link">Changelog</a><a href="differences.html" class="sidebar-link">Differences with Shopify/liquid</a><a href="contribution-guidelines.html" class="sidebar-link">Contribution Guidelines</a>
</div>
</aside>
<article class="article-container" itemscope itemtype="https://schema.org/Article">
<div class="article-inner">
<div class="article">
<div class="inner">
<header class="article-header">
<h1 class="article-title" itemprop="name">Liquid Drops</h1>
<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/harttle/liquidjs/edit/master/docs/source/tutorials/drops.md" class="article-edit-link" title="Improve this doc"><i class="icon-pencil"></i></a>
</header>
<div class="article-content" itemprop="articleBody">
<p>LiquidJS also provides a mechanism similar to <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/Shopify/liquid/wiki/Introduction-to-Drops">Shopify Drops</a>, allowing template authors to incorporate custom functionality in resolving variable values.</p>
<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>
<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>
<blockquote class="note tip"><strong class="note-title">Async Methods</strong><p>LiquidJS is fully async-friendly. You can safely return a Promise in your Drop methods or define your methods in Drop as <code>async</code>.</p>
</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>
<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>
<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>
<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>
<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>
<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>
<li><code>valueOf()</code> is a method exclusive to Drops; whereas <code>toLiquid()</code> can be used on any scope object.</li>
<li><code>valueOf()</code> is called when the variable itself is about to be rendered, replacing itself; whereas <code>toLiquid()</code> is called when its properties are about to be read.</li>
</ul></blockquote>
<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>
<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>
<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>
<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="2026-05-03T04:05:26.811Z" itemprop="dateModified">Last updated: 2026-05-03</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>
</div>
<aside id="article-toc" role="navigation">
<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="#Basic-Usage"><span class="toc-text">Basic Usage</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#liquidMethodMissing"><span class="toc-text">liquidMethodMissing</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#valueOf-NaN"><span class="toc-text">valueOf</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#toLiquid"><span class="toc-text">toLiquid</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Special-Drops"><span class="toc-text">Special Drops</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#blank"><span class="toc-text">blank</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#empty"><span class="toc-text">empty</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#nil"><span class="toc-text">nil</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Other-Drops"><span class="toc-text">Other Drops</span></a></li></ol></li></ol>
</div>
<a href="#" id="article-toc-top">Back to Top</a>
</div>
</aside>
</div>
</article>
</div>
</div>
</div>
<footer id="footer" class="wrapper">
<div class="inner">
<div id="footer-copyright">
&copy; 2026 <a href="https://github.com/harttle/liquidjs/graphs/contributors" rel="external nofollow noreferrer" target="_blank">Harttle</a><br>
Documentation licensed under <a href="https://creativecommons.org/licenses/by/4.0/" rel="external nofollow noreferrer" target="_blank">CC BY 4.0</a>.
</div>
<div id="footer-links">
<a href="https://twitter.com/harttleharttle" rel="external nofollow noreferrer" class="footer-link" target="_blank"><i class="icon-twitter"></i></a>
<a href="https://opencollective.com/liquidjs" rel="external nofollow noreferrer" class="footer-link" target="_blank"><i class="icon-opencollective"></i></a>
<a href="https://github.com/harttle/liquidjs" rel="external nofollow noreferrer" class="footer-link" target="_blank"><i class="icon-github"></i></a>
</div>
</div>
</footer>
</div>
<div id="mobile-nav-dimmer"></div>
<nav id="mobile-nav">
<div id="mobile-nav-inner">
<ul id="mobile-nav-list">
<a href="../tutorials/intro-to-liquid.html" class="mobile-nav-link">Tutorials</a><a href="../tags/overview.html" class="mobile-nav-link">Tags</a><a href="../filters/overview.html" class="mobile-nav-link">Filters</a><a href="../playground.html" class="mobile-nav-link">Playground</a><a href="../api/classes/Liquid.html" class="mobile-nav-link">API</a>
</ul>
<div class="mobile-sidebar-list">
<strong class="mobile-nav-title">Getting Started</strong><a href="intro-to-liquid.html" class="mobile-nav-link">Intro to Liquid</a><a href="setup.html" class="mobile-nav-link">Setup</a><a href="options.html" class="mobile-nav-link">Options</a><a href="render-file.html" class="mobile-nav-link">Render Files</a><a href="partials-and-layouts.html" class="mobile-nav-link">Includes and Layouts</a><a href="use-in-expressjs.html" class="mobile-nav-link">Use in Express.js</a><strong class="mobile-nav-title">Advanced</strong><a href="caching.html" class="mobile-nav-link">Caching</a><a href="escaping.html" class="mobile-nav-link">Escaping</a><a href="register-filters-tags.html" class="mobile-nav-link">Register Filters/Tags</a><a href="access-scope-in-filters.html" class="mobile-nav-link">Access Scope in Filters</a><a href="parse-parameters.html" class="mobile-nav-link">Parse Parameters</a><a href="render-tag-content.html" class="mobile-nav-link">Render Tag Content</a><a href="drops.html" class="mobile-nav-link current">Liquid Drops</a><a href="sync-and-async.html" class="mobile-nav-link">Sync and Async</a><a href="whitespace-control.html" class="mobile-nav-link">Whitespace Control</a><a href="plugins.html" class="mobile-nav-link">Plugins</a><a href="operators.html" class="mobile-nav-link">Operators</a><a href="truthy-and-falsy.html" class="mobile-nav-link">Truthy and Falsy</a><a href="dos.html" class="mobile-nav-link">DoS</a><a href="static-analysis.html" class="mobile-nav-link">Static Analysis</a><strong class="mobile-nav-title">Miscellaneous</strong><a href="migrate-to-9.html" class="mobile-nav-link">Migrate to LiquidJS 9</a><a href="changelog.html" class="mobile-nav-link">Changelog</a><a href="differences.html" class="mobile-nav-link">Differences with Shopify/liquid</a><a href="contribution-guidelines.html" class="mobile-nav-link">Contribution Guidelines</a>
</div>
</div>
<div id="mobile-button-list">
<a href="https://github.com/harttle/liquidjs" class="mobile-nav-link" rel="external" target="_blank"><i class="icon-github"></i></a>
<a href="https://opencollective.com/liquidjs" class="mobile-nav-link" rel="external" target="_blank"><i class="icon-opencollective"></i></a>
<div id="mobile-lang-select-wrap" class="mobile-nav-link">
<label for="mobile-lang-select"><i class="icon-network"></i></label>
<select id="mobile-lang-select" data-canonical="tutorials/drops.html">
<option value="en" selected>English</option>
<option value="zh-cn">简体中文</option>
</select>
</div>
</div>
</nav>
<script src="../js/main.js"></script>
<script src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js"></script>
<script>
document.getElementById('search-input-wrap').classList.add('on');
docsearch({
appId: 'QJ35YOZTU4',
apiKey: '8c6cbb824b4c5023f0bb2ef29e228bef',
indexName: 'liquidjs',
inputSelector: '#search-input',
debug: false
});
</script>
</body>
</html>