mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-16 12:50:38 -07:00
docs: website for LiquidJS
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
---
|
||||
title: Caching
|
||||
---
|
||||
|
||||
In a typical website project, we'll have a directory of view templates and they'll be rendered multiple times. In production environment the template files are not likely to be changed over time (other than re-deployments). Thus it makes sense to cache the file contents and the parsed templates (in a kind of AST) to improve performance.
|
||||
|
||||
LiquidJS provides multiple ways to cache the parsed templates to improve performance.
|
||||
|
||||
## Programmaticly
|
||||
|
||||
The [.parse()][parse], [.parseFile()][parseFile], [.parseFileSync()][parseFileSync] APIs are used to parse templates from string or files. The result template can be then rendered multiple times with different context.
|
||||
|
||||
Parse from string:
|
||||
|
||||
```javascript
|
||||
var tpl = engine.parse('{{name | capitalize}}');
|
||||
|
||||
engine.renderSync(tpl, {name: 'alice'}) // 'Alice'
|
||||
engine.renderSync(tpl, {name: 'bob'}) // 'Bob'
|
||||
```
|
||||
|
||||
Parse from file:
|
||||
|
||||
```javascript
|
||||
var tpl = engine.parseFileSync('hello'); // contents of `hello.liquid`: {{name}}
|
||||
|
||||
engine.renderSync(tpl, {name: 'alice'}) // 'Alice'
|
||||
engine.renderSync(tpl, {name: 'bob'}) // 'Bob'
|
||||
```
|
||||
|
||||
The template string/file is parsed only once and renderd multiple times using different context. Templates for different files can be stored into a `Map` and can be retrieved directly for subsequent renders.
|
||||
|
||||
## The `cache` Option
|
||||
|
||||
The [cache option][cache] can be set to instruct liquidjs to use cached parsed templates each time you call [renderFile][renderFile] or [renderFileSync][renderFileSync].
|
||||
|
||||
```javascript
|
||||
var { Liquid } = require('liquidjs');
|
||||
var engine = new Liquid({
|
||||
cache: true
|
||||
});
|
||||
|
||||
// liquidjs parses the hello.liquid, then renders it with {name: 'alice'}
|
||||
engine.renderFileSync('hello', {name: 'alice'})
|
||||
|
||||
// liquidjs finds the cached template, then renders it with {name: 'bob'}
|
||||
engine.renderFileSync('hello', {name: 'bob'})
|
||||
```
|
||||
|
||||
[parse]: ../api/classes/liquid_.liquid.html#parse
|
||||
[cache]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-cache
|
||||
[parseFile]: ../api/classes/liquid_.liquid.html#parseFile
|
||||
[parseFileSync]: ../api/classes/liquid_.liquid.html#parseFileSync
|
||||
[renderFile]: ../api/classes/liquid_.liquid.html#renderFile
|
||||
[renderFileSync]: ../api/classes/liquid_.liquid.html#renderFilesync
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
title: Contribution Guideline
|
||||
---
|
||||
|
||||
## Show Me Your Code
|
||||
|
||||
**Code Style**: LiquidJS applies [standard](https://github.com/standard/eslint-config-standard) and [@typescript-eslint/recommended](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/src/configs/recommended.json) rules, make sure it's still valid before commit:
|
||||
|
||||
```bash
|
||||
npm run lint
|
||||
```
|
||||
|
||||
**Testing**: Make sure test cases pass with your patch merged:
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
**Commit Message**: Please align to [the Angular Commit Message Guidelines](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#commits), especially note the [type identifier](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type), on which semantic-release bot depends.
|
||||
|
||||
## Star on Github 👉 [][liquidjs]
|
||||
|
||||
This is the easiest way to support us: boost its rank and expose it to more people, which in turn makes it better.
|
||||
|
||||
## Financial Support
|
||||
|
||||
LiquidJS is Open Source and Free and **without** capitalists support and **without** any ADs. To help it live and thrive, consider contribute on [Open Collective][oc] or [Patreon][pt]. To acknowledge your contribution, your name and avatar will be listed here and on [Github README][liquidjs].
|
||||
|
||||
<object type="image/svg+xml" data="https://opencollective.com/liquidjs/tiers/backer.svg?avatarHeight=72"></object>
|
||||
|
||||
[](https://www.patreon.com/bePatron?u=32321060)
|
||||
|
||||
[oc]: https://opencollective.com/liquidjs/
|
||||
[pt]: https://www.patreon.com/harttle
|
||||
[shopify/liquid]: https://shopify.github.io/liquid/
|
||||
[caniuse-promises]: http://caniuse.com/#feat=promises
|
||||
[pp]: https://github.com/taylorhakes/promise-polyfill
|
||||
[tutorial]: https://shopify.github.io/liquid/basics/introduction/
|
||||
[liquidjs]: https://github.com/harttle/liquidjs
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
title: Migrate to LiquidJS 9
|
||||
---
|
||||
|
||||
LiquidJS 9 has some fundamental improvements, including bugfixes, new features and performance improvement due to higher target(see #137). There're also some breaking changes.
|
||||
|
||||
## Features
|
||||
|
||||
* Sync rendering: renderSync, parseAndRenderSync, renderFileSync
|
||||
* New utils: Expression
|
||||
|
||||
## Fixes
|
||||
|
||||
* Rewrite boolean expression evaluation order, [#130](https://github.com/harttle/liquidjs/issues/130);
|
||||
* `break` and `continue` tags omitting output before them, [#123](https://github.com/harttle/liquidjs/issues/123);
|
||||
* Fixes errors in React.js demo during yarn install, [#145](https://github.com/harttle/liquidjs/issues/145);
|
||||
* Promise typed Drops are not await-ed some times.
|
||||
|
||||
## Performance
|
||||
|
||||
* Performance Improvements due to targeting to Node.js 8, see [#137](https://github.com/harttle/liquidjs/issues/137);
|
||||
* Memory footprint is reduced by 57.5%, see [#202](https://github.com/harttle/liquidjs/pull/202);
|
||||
* Render performance is improved by 100.3%, see [#205](https://github.com/harttle/liquidjs/pull/205).
|
||||
|
||||
## BREAKING CHANGES
|
||||
|
||||
* LiquidJS no longer has a default export, use `import {Liquid} from 'liquidjs'` instead. The `window.Liquid` for the UMD bundle is also changed to `window.liquidjs.Liquid`;
|
||||
* The duplicate static method `Liquid.evalValue` is removed, use the instance method `liquid.evalValue` instead;
|
||||
* Shipped to Node.js 8, the CJS bundle (main entry in Node.js) nolonger supports Node.js ≤ 6. ESM (dist/liquid.esm.js) and UMD (dist/liquid.js, dist/liquid.min.js) bundles are not affected.
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
title: Operators
|
||||
---
|
||||
|
||||
LiquidJS operators are very simple and different. There're 2 types of operators supported:
|
||||
|
||||
* Comparison operators: `==`, `!=`, `>`, `<`, `>=`, `<=`
|
||||
* Logic operators: `or`, `and`, `contains`
|
||||
|
||||
Thus numerical operators are not supported and you cannot even plus two numbers like this `{% raw %}{{a + b}}{% endraw %}`, instead we need a filter `{% raw %}{{ a | plus: b}}{% endraw %}`. Actually `+` is a valid variable name in LiquidJS.
|
||||
|
||||
## Precedence
|
||||
|
||||
1. Comparison operators. All comparison operations have the same precedence and higher than logic operators.
|
||||
2. Logic operators. All logic operators have the same precedence.
|
||||
|
||||
## Associativity
|
||||
|
||||
Logic operators are evaluated from right to left, see [shopify docs][operator-order].
|
||||
|
||||
[operator-order]: https://help.shopify.com/en/themes/liquid/basics/operators#order-of-operations
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
title: Overview
|
||||
---
|
||||
|
||||
LiquidJS is a simple, expressive, safe and shopify compatible template engine in pure JavaScript. The purpose of this repo is to provide a standard Liquid implementation for the JavaScript community.
|
||||
|
||||
## LiquidJS in Node.js
|
||||
|
||||
Install via npm:
|
||||
|
||||
```bash
|
||||
npm install --save liquidjs
|
||||
```
|
||||
|
||||
```javascript
|
||||
var { Liquid } = require('liquidjs');
|
||||
var engine = new Liquid();
|
||||
|
||||
engine
|
||||
.parseAndRender('{{name | capitalize}}', {name: 'alice'})
|
||||
.then(console.log); // outputs 'Alice'
|
||||
```
|
||||
|
||||
{% note info Working Demo %} Here's a working demo for LiquidJS usage in Node.js: <a href="https://github.com/harttle/liquidjs/blob/master/demo/nodejs/" target="_blank">liquidjs/demo/nodejs/</a>.{% endnote %}
|
||||
|
||||
Type definitions for LiquidJS are also exported and published, which makes it more enjoyable for TypeScript projects:
|
||||
|
||||
```typescript
|
||||
import { Liquid } from 'liquidjs';
|
||||
const engine = new Liquid();
|
||||
|
||||
engine
|
||||
.parseAndRender('{{name | capitalize}}', {name: 'alice'})
|
||||
.then(console.log); // outputs 'Alice'
|
||||
```
|
||||
|
||||
{% note info Working Demo %} Here's a working demo for LiquidJS usage in TypeScript: <a href="https://github.com/harttle/liquidjs/blob/master/demo/typescript/" target="_blank">liquidjs/demo/typescript/</a>.{% endnote %}
|
||||
|
||||
## LiquidJS in Browsers
|
||||
|
||||
Pre-built UMD bundles are also available and included in the npm package:
|
||||
|
||||
```html
|
||||
<!--for production-->
|
||||
<script src="//unpkg.com/liquidjs/dist/liquid.min.js"></script>
|
||||
<!--for development-->
|
||||
<script src="//unpkg.com/liquidjs/dist/liquid.js"></script>
|
||||
```
|
||||
|
||||
Or from jsDelivr CDN:
|
||||
|
||||
```html
|
||||
<!--for production-->
|
||||
<script src="https://cdn.jsdelivr.net/npm/liquidjs/dist/liquid.min.js"></script>
|
||||
<!--for development-->
|
||||
<script src="https://cdn.jsdelivr.net/npm/liquidjs/dist/liquid.js"></script>
|
||||
```
|
||||
|
||||
{% note info Working Demo %} Here's a living demo on jsFiddle: <a href="https://jsfiddle.net/x43eb0z6/" target="_blank">jsfiddle.net/x43eb0z6</a>, and the source code is also available in <a href="https://github.com/harttle/liquidjs/blob/master/demo/browser/" target="_blank">liquidjs/demo/browser/</a>.{% endnote %}
|
||||
|
||||
{% note warn Compatibility %} You may need a <a href="https://github.com/taylorhakes/promise-polyfill" target="_blank">Promise polyfill</a> for legacy browsers like IE and Android UC, see <a href="http://caniuse.com/#feat=promises" target="_blank">caniuse statistics</a>. {% endnote %}
|
||||
|
||||
## LiquidJS in CLI
|
||||
|
||||
LiquidJS is also available from CLI:
|
||||
|
||||
```bash
|
||||
echo '{{"hello" | capitalize}}' | npx liquidjs
|
||||
```
|
||||
|
||||
If you pass a path to a JSON file or a JSON string as the first argument, it will be used as the context for your template.
|
||||
|
||||
```bash
|
||||
echo 'Hello, {{ name }}.' | npx liquidjs '{"name": "Snake"}'
|
||||
```
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
A ReactJS demo is also added by [@stevenanthonyrevo](https://github.com/stevenanthonyrevo), see [liquidjs/demo/reactjs/](https://github.com/harttle/liquidjs/blob/master/demo/reactjs/).
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
title: Partials and Layouts
|
||||
---
|
||||
|
||||
## Render Partials
|
||||
|
||||
For the following template files:
|
||||
|
||||
```
|
||||
// file: color.liquid
|
||||
color: '{{ color }}' shape: '{{ shape }}'
|
||||
|
||||
// file: theme.liquid
|
||||
{% assign shape = 'circle' %}
|
||||
{% render 'color' %}
|
||||
{% render 'color' with 'red' %}
|
||||
{% render 'color', color: 'yellow', shape: 'square' %}
|
||||
```
|
||||
|
||||
The output will be:
|
||||
|
||||
```
|
||||
color: '' shape: 'circle'
|
||||
color: 'red' shape: 'circle'
|
||||
color: 'yellow' shape: 'square'
|
||||
```
|
||||
|
||||
More details please refer to the [render](../tags/render.html) tag.
|
||||
|
||||
## Layout Templates (Extends)
|
||||
|
||||
For the following template files:
|
||||
|
||||
```
|
||||
// file: default-layout.liquid
|
||||
Header
|
||||
{% block content %}My default content{% endblock %}
|
||||
Footer
|
||||
|
||||
// file: page.liquid
|
||||
{% layout "default-layout" %}
|
||||
{% block content %}My page content{% endblock %}
|
||||
```
|
||||
|
||||
The output of `page.liquid`:
|
||||
|
||||
```
|
||||
Header
|
||||
My page content
|
||||
Footer
|
||||
```
|
||||
|
||||
More details please refer to the [layout](../tags/layout.html) tag.
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: Plugins
|
||||
---
|
||||
|
||||
A number of tags and filters can be encapsulated into a **plugin**, which will be typically installed via npm. This article provides information about how to create and use a plugin.
|
||||
|
||||
## Write a Plugin
|
||||
|
||||
A liquidjs plugin is simple function which takes the [Liquid class][liquid] as the first parameter and the Liquid instance for `this`. We can call liquidjs APIs on `this` to make certain changes, especially [register filters and tags][register].
|
||||
|
||||
Now we'll make a plugin to upper case every letter of the input, save the following snippet to `upup.js`:
|
||||
|
||||
```javascript
|
||||
/**
|
||||
* Inside the plugin function, `this` refers to the Liquid instance.
|
||||
*
|
||||
* @param Liquid: provides facilities to implement tags and filters.
|
||||
*/
|
||||
module.exports = function (Liquid) {
|
||||
this.registerFilter('upup', x => x.toUpperCase());
|
||||
}
|
||||
```
|
||||
|
||||
## Use a Plugin
|
||||
|
||||
Simply pass the plugin function into the `.plugin()` method:
|
||||
|
||||
```javascript
|
||||
const engine = new Liquid()
|
||||
|
||||
engine.plugin(require('./upup.js'));
|
||||
engine
|
||||
.parseAndRender('{{ "foo" | upup }}')
|
||||
.then(console.log) // outputs "FOO"
|
||||
```
|
||||
|
||||
## Plugin List
|
||||
|
||||
Since this library excludes certain features that are available on the Shopify platform but not on the [Shopify/liquid](https://github.com/Shopify/liquid/) repo, see <https://github.com/harttle/liquidjs#differences-and-limitations>.
|
||||
|
||||
Here's a list of plugins that backfill those features. Feel free to add yours, this file is publicly editable.
|
||||
|
||||
* Sections Tags (WIP): https://github.com/harttle/liquidjs-section-tags
|
||||
* Color Filters: https://github.com/harttle/liquidjs-color-filters
|
||||
|
||||
[liquid]: ../api/classes/liquid_.liquid.html
|
||||
[register]: /harttle/liquidjs/wiki/Register-Filters-Tags
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
title: Register Filters/Tags
|
||||
---
|
||||
|
||||
## Register Tags
|
||||
|
||||
```javascript
|
||||
// Usage: {% upper name%}
|
||||
engine.registerTag('upper', {
|
||||
parse: function(tagToken, remainTokens) {
|
||||
this.str = tagToken.args; // name
|
||||
},
|
||||
render: async function(scope, hash) {
|
||||
var str = await this.liquid.evalValue(this.str, scope); // 'alice'
|
||||
return str.toUpperCase() // 'Alice'
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
* `parse`: Read tokens from `remainTokens` until your end token.
|
||||
* `render`: Combine scope data with your parsed tokens into HTML string.
|
||||
|
||||
See existing tag implementations here: <https://github.com/harttle/liquidjs/tree/master/src/builtin/tags>
|
||||
|
||||
## Register Filters
|
||||
|
||||
```javascript
|
||||
// Usage: {{ name | upper }}
|
||||
engine.registerFilter('upper', v => v.toUpperCase())
|
||||
```
|
||||
|
||||
Filter arguments will be passed to the registered filter function, for example:
|
||||
|
||||
```javascript
|
||||
// Usage: {{ 1 | add: 2, 3 }}
|
||||
engine.registerFilter('add', (initial, arg1, arg2) => initial + arg1 + arg2)
|
||||
```
|
||||
|
||||
See existing filter implementations here: <https://github.com/harttle/liquidjs/tree/master/src/builtin/filters>
|
||||
@@ -0,0 +1,108 @@
|
||||
---
|
||||
title: Render Files
|
||||
---
|
||||
|
||||
For a typical project there could be a directory of template files, you'll need to set the [template root][root] and call [renderFile][renderFile] or [renderFileSync][renderFileSync] to render a specific file.
|
||||
|
||||
## Render a File
|
||||
|
||||
For example you have a directory of templates like this:
|
||||
|
||||
```
|
||||
.
|
||||
├── index.js
|
||||
└── views/
|
||||
├── hello.liquid
|
||||
└── world.liquid
|
||||
```
|
||||
|
||||
`hello.liquid` contains a single line {%raw%}`name: {{name}}`{%endraw%}.
|
||||
Now save the following contents into `index.js`:
|
||||
|
||||
```javascript
|
||||
var engine = new Liquid({
|
||||
root: path.resolve(__dirname, 'views/'), // root for layouts/includes lookup
|
||||
extname: '.liquid' // used for layouts/includes, defaults ""
|
||||
});
|
||||
engine
|
||||
.renderFile("hello", {name: 'alice'}) // will read and render `views/hello.liquid`
|
||||
.then(console.log) // outputs "Alice"
|
||||
```
|
||||
|
||||
Run `node index.js` and you'll get output like this:
|
||||
|
||||
```
|
||||
> node index.js
|
||||
name: alice
|
||||
```
|
||||
|
||||
## Template Lookup
|
||||
|
||||
Template files names passed to [renderFile][renderFile], [parseFile][parseFile], [renderFileSync][renderFileSync], [parseFileSync][parseFileSync] APIs,
|
||||
and [include][include], [layout][layout] tags are resolved against [the root option][root].
|
||||
|
||||
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.
|
||||
|
||||
```javascript
|
||||
var engine = new Liquid({
|
||||
root: ['views/', 'views/partials/'],
|
||||
extname: '.liquid'
|
||||
});
|
||||
```
|
||||
|
||||
{% note tip Relative Paths %}Relative paths in <code>root</code> will be resolved against <code>cwd()</code>.{% endnote %}
|
||||
|
||||
When `{% raw %}{% render "foo" %}{% endraw %}` is renderd or `liquid.renderFile('foo')` is called, the following files will be looked up and the first existing file will be used:
|
||||
|
||||
- `cwd()`/views/foo.liquid
|
||||
- `cwd()`/views/partials/foo.liquid
|
||||
|
||||
If none of the above files exists, an `ENOENT` error will be throwed. Here's a demo for Node.js: [demo/nodejs](https://github.com/harttle/liquidjs/tree/master/demo/nodejs).
|
||||
|
||||
When LiquidJS is used in browser, say current location is <https://example.com/bar/index.html>, only the first `root` will be used and the file to be fetched is:
|
||||
|
||||
- <https://example.com/bar/foo.liquid>
|
||||
|
||||
If fetch fails, a 404/500 error or network failures for example, an `ENOENT` error will be throwed.
|
||||
Here's a demo for browsers: [demo/browser](https://github.com/harttle/liquidjs/tree/master/demo/browser).
|
||||
|
||||
## Abstract File System
|
||||
|
||||
LiquidJS defines an abstract file system interface in [src/fs/ifs.ts][ifs] and the default implementation is [src/fs/node.ts][fs-node] for Node.js and [src/fs/browser.ts][fs-browser] for the browser bundle.
|
||||
|
||||
The `Liquid` constructor provides a [fs][fs] option to specify the file system implementation. It's supposed to be used to define customized template fetching logic, i.e. fetch template from a database table, like:
|
||||
|
||||
```javascript
|
||||
var engine = new Liquid({
|
||||
fs: {
|
||||
readFileSync (file) {
|
||||
return db.model('Template').findByIdSync(file).text
|
||||
},
|
||||
await readFile (file) {
|
||||
const template = await db.model('Template').findById(file)
|
||||
return template.text
|
||||
},
|
||||
existsSync () {
|
||||
return true
|
||||
},
|
||||
await exists () {
|
||||
return true
|
||||
},
|
||||
resolve(root, file, ext) {
|
||||
return file
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
[fs]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-fs
|
||||
[ifs]: https://github.com/harttle/liquidjs/blob/master/src/fs/ifs.ts
|
||||
[fs-node]: https://github.com/harttle/liquidjs/blob/master/src/fs/node.ts
|
||||
[fs-browser]: https://github.com/harttle/liquidjs/blob/master/src/fs/browser.ts
|
||||
[layout]: https://help.shopify.com/en/themes/liquid/tags/theme-tags#layout
|
||||
[include]: https://help.shopify.com/themes/liquid/tags/theme-tags#include
|
||||
[renderFile]: ../api/classes/liquid_.liquid.html#renderFile
|
||||
[renderFileSync]: ../api/classes/liquid_.liquid.html#renderFilesync
|
||||
[parseFile]: ../api/classes/liquid_.liquid.html#parseFile
|
||||
[parseFileSync]: ../api/classes/liquid_.liquid.html#parseFileSync
|
||||
[root]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
title: Basic Syntax
|
||||
---
|
||||
|
||||
LiquidJS syntax is relatively simple. There're 2 types of markups in LiquidJS:
|
||||
|
||||
- **Tags**. A tag consists of a tag name and optional arguments wrapped between `{%raw%}{%{%endraw%}` and `%}`.
|
||||
- **Outputs**. An output consists of a value and a list of filters, which is optional, wrapped between `{%raw%}{{{%endraw%}` and `}}`.
|
||||
|
||||
## Outputs
|
||||
|
||||
**Outputs** are used to output variables, which can be transformed by filters, into HTML. The following template will insert the value of `username` into the input's value:
|
||||
|
||||
```liquid
|
||||
<input type="text" name="user" value="{{username}}">
|
||||
```
|
||||
|
||||
Values in output can be transformed by **filter**s before output. To append a string after the variable:
|
||||
|
||||
```liquid
|
||||
{{ username | append: ", welcome to LiquidJS!" }}
|
||||
```
|
||||
|
||||
Filters can be chained:
|
||||
|
||||
```liquid
|
||||
{{ username | append: ", welcome to LiquidJS!" | capitalize }}
|
||||
```
|
||||
|
||||
A complete list of filters supported by LiquidJS can be found [here](../filters/overview.html).
|
||||
|
||||
## Tags
|
||||
|
||||
**Tags** are used to control the template rendering process, manipulating template variables, inter-op with other templates, etc. For example `assign` can be used to define a variable which can be later used in the template:
|
||||
|
||||
```liquid
|
||||
{% assign foo = "FOO" %}
|
||||
```
|
||||
|
||||
Typically tags appear in pairs with a start tag and a corresponding end tag. For example:
|
||||
|
||||
```liquid
|
||||
{% if foo == "FOO" %}
|
||||
Variable `foo` equals "FOO"
|
||||
{% else %}
|
||||
Variable `foo` not equals "FOO"
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
A complete list of tags supported by LiquidJS can be found [here](../tags/overview.html).
|
||||
|
||||
[shopify/liquid]: https://github.com/Shopify/liquid
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
title: Truthy and Falsy
|
||||
---
|
||||
|
||||
Though [Liquid][sl] is platform-independent, there're [certain differences][diff] with [the Ruby version][ruby], one of which is the `truthy` value.
|
||||
|
||||
## The Truth Table
|
||||
|
||||
According to [Shopify document](https://shopify.github.io/liquid/basics/truthy-and-falsy/) everything other than `false` and `nil` is truthy. But in JavaScript we have a totally different type system, we have types like `undefined` and we don't differentiate `integer` and `float`, thus things are slightly different:
|
||||
|
||||
value | truthy | falsy
|
||||
--- | --- | ---
|
||||
`true` | ✔️ |
|
||||
`false` | | ✔️
|
||||
`null` | | ✔️
|
||||
`undefined` | | ✔️
|
||||
`string` | ✔️ |
|
||||
`empty string` | ✔️ |
|
||||
`0` | ✔️ |
|
||||
`integer` | ✔️ |
|
||||
`float` | ✔️ |
|
||||
`array` | ✔️ |
|
||||
`empty array` | ✔️ |
|
||||
|
||||
[ruby]: https://shopify.github.io/liquid
|
||||
[sl]: https://www.npmjs.com/package/liquidjs
|
||||
[diff]: https://github.com/harttle/liquidjs#differences-and-limitations
|
||||
@@ -0,0 +1,70 @@
|
||||
---
|
||||
title: Use in Express.js
|
||||
---
|
||||
|
||||
LiquidJS is compatible to the [express template engines](https://expressjs.com/en/resources/template-engines.html). You can set liquidjs instance to the [view engine][express-views] option:
|
||||
|
||||
```javascript
|
||||
var { Liquid } = require('liquidjs');
|
||||
var engine = new Liquid();
|
||||
|
||||
// register liquid engine
|
||||
app.engine('liquid', engine.express());
|
||||
app.set('views', './views'); // specify the views directory
|
||||
app.set('view engine', 'liquid'); // set liquid to default
|
||||
```
|
||||
|
||||
{% note info Working Demo %} Here's a working demo for LiquidJS usage in Express.js: <a href="https://github.com/harttle/liquidjs/blob/master/demo/express/" target="_blank">liquidjs/demo/express/</a>.{% endnote %}
|
||||
|
||||
## Template Lookup
|
||||
|
||||
The [root][root] option will continue to work as templates root, as you can see in [Render A Template File][render-a-file]. Additionally, the [`views`][express-views] option in express.js (as shown above) will also be respected. Say you have a template directory like:
|
||||
|
||||
```
|
||||
.
|
||||
├── views1/
|
||||
│ └── hello.liquid
|
||||
└── views2/
|
||||
└── world.liquid
|
||||
```
|
||||
|
||||
And you're setting template root for liquidjs to `views1` and expressjs to `views2`:
|
||||
|
||||
```javascript
|
||||
var { Liquid } = require('liquidjs');
|
||||
var engine = new Liquid({
|
||||
root: './views1/'
|
||||
});
|
||||
|
||||
app.engine('liquid', engine.express());
|
||||
app.set('views', './views2'); // specify the views directory
|
||||
app.set('view engine', 'liquid'); // set liquid to default
|
||||
```
|
||||
|
||||
Both of `hello.liquid` and `world.liquid` can be resolved and rendered:
|
||||
|
||||
```javascript
|
||||
res.render('hello')
|
||||
res.render('world')
|
||||
```
|
||||
|
||||
## Caching
|
||||
|
||||
Simply setting the [cache option][cache] to true will enable template caching, as explained in [Caching][Caching]. It's recommended to enable cache in production environment, which can be done by:
|
||||
|
||||
```javascript
|
||||
var { Liquid } = require('liquidjs');
|
||||
var engine = new Liquid({
|
||||
cache: process.env.NODE_ENV === 'production'
|
||||
});
|
||||
```
|
||||
|
||||
[cache]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-cache
|
||||
[express-views]: http://expressjs.com/en/guide/using-template-engines.html
|
||||
[parseFile]: ../api/classes/liquid_.liquid.html#parseFile
|
||||
[parseFileSync]: ../api/classes/liquid_.liquid.html#parseFileSync
|
||||
[layout]: https://help.shopify.com/en/themes/liquid/tags/theme-tags#layout
|
||||
[include]: https://help.shopify.com/themes/liquid/tags/theme-tags#include
|
||||
[root]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-root
|
||||
[render-a-file]: ./render-a-file.html
|
||||
[Caching]: ./caching.html
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
title: Whitespace Control
|
||||
---
|
||||
|
||||
To keep source code neat and indented, we're adding spaces to our templates. LiquidJS offers whitespace control capabilities to eliminate these unwanted whitespaces in output HTML.
|
||||
|
||||
## via Markups
|
||||
|
||||
By default, all tags and output markups lines will generate a NL (`\n`), and whitespaces if there's any indentation. For example:
|
||||
|
||||
```liquid
|
||||
{% author = "harttle" %}
|
||||
{{ author }}
|
||||
```
|
||||
|
||||
Outputs (note the blank link):
|
||||
|
||||
```
|
||||
|
||||
harttle
|
||||
```
|
||||
|
||||
We can include hyphens in your tag syntax (`{% raw %}{{-{% endraw %}`, `-}}`, `{% raw %}{%-{% endraw %}`, `-%}`) to strip whitespace from left or right. For example:
|
||||
|
||||
```liquid
|
||||
{% assign author = "harttle" -%}
|
||||
{{ author }}
|
||||
```
|
||||
|
||||
Outputs:
|
||||
|
||||
```
|
||||
harttle
|
||||
```
|
||||
|
||||
In this case, the `-%}` strips the whitespace from the right side of the `assign` tag.
|
||||
|
||||
## via Options
|
||||
|
||||
Alternatively, LiquidJS provides these per engine options to enable whitespace control without sweeping changes of your templates:
|
||||
|
||||
* `trimTagLeft`
|
||||
* `trimTagRight`
|
||||
* `trimValueRight`
|
||||
* `trimValueRight`
|
||||
|
||||
[LiquidJS][liquidjs] will **NOT** trim any whitespace by default, aka. above options all default to `false`. For details of these options, see the [options][options].
|
||||
|
||||
## Greedy Mode
|
||||
|
||||
In greedy mode (enabled by the [greedy option][greedy]), all consecutive whitespace chars (including `\n`) will be trimmed. Greedy mode is enabled by default to be compliant with [shopify/liquid][shopify/liquid].
|
||||
|
||||
[shopify/liquid]: https://github.com/Shopify/liquid
|
||||
[liquidjs]: https://github.com/harttle/liquidjs
|
||||
[options]: ../api/interfaces/liquid_options_.liquidoptions.html
|
||||
[greedy]: ../api/interfaces/liquid_options_.liquidoptions.html#Optional-greedy
|
||||
Reference in New Issue
Block a user