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
+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>