mirror of
https://github.com/harttle/liquidjs.git
synced 2026-10-03 00:55:13 -07:00
docs(readme): README overhaul, used-by grid, and docs homepage (#914)
* docs(readme): lead with quick start and scannable structure Restructure the README to match common OSS conventions: tagline and badges above the fold, copy-paste Quick start, Features list, and a compact Used by section. Remove the star plea, centered logo, and per-project marketing blurbs that pushed useful content down. Co-authored-by: Cursor <[email protected]> * docs(readme): playground GIF, used-by grid, and docs homepage sync Add data/used-by.json with build:used-by for README and docs homepage, playground demo capture, and shared home-section layout. Used by lists products with site logos; Financial Support keeps org and individual sponsors. Co-authored-by: Cursor <[email protected]> * chore: use .local for playground capture scratch files Co-authored-by: Cursor <[email protected]> * fix: satisfy eslint in build-used-by and capture scripts Co-authored-by: Cursor <[email protected]> * chore: drop one-off playground capture script Co-authored-by: Cursor <[email protected]> * refactor(docs): copy Used by from README like financial contributors Drop data/used-by.json and build-used-by.js; build-contributors.js now extracts USED-BY-BEGIN/END to used-by.swig. Co-authored-by: Cursor <[email protected]> * refactor(docs): inline Used by section, drop home-section partial Co-authored-by: Cursor <[email protected]> * fix(docs): drop redundant logo styles from .contributors Co-authored-by: Cursor <[email protected]> * fix(docs): build liquid bundle before hexo serve Co-authored-by: Cursor <[email protected]> * refactor(docs): drop playground window chrome from capture demo Co-authored-by: Cursor <[email protected]> * refactor(docs): revert playground capture changes to master behavior Restore Ace output pane, drop Prism and output-preview styling. Simplify docs:dev to rely on docs prestart. Co-authored-by: Cursor <[email protected]> * refactor(docs): rely on docs prebuild for liquid bundle and contributors Co-authored-by: Cursor <[email protected]> * feat(docs): show playground output as Prism-highlighted HTML code Co-authored-by: Cursor <[email protected]> * feat(docs): polish playground layout and regenerate README demo GIF * fix(docs): align playground GIF capture with live editor styling * fix(docs): unify playground pane padding and hold output on errors Match editor inset to the output panel, drop Prism from output preview, keep the last render while typing invalid template/context, and refresh the README demo GIF. * fix(docs): regenerate playground GIF with held output during typing * feat(docs): sync Used by logos and polish playground Inline README Used by grid on the docs homepage, refine playground layout and live output behavior, and drop the unused build-used-by script from package scripts. Co-authored-by: Cursor <[email protected]> * fix(docs): restore Rock RMS logo and remove duplicate entry Restore the official Rock RMS wordmark (GetImage.ashx?id=72534) instead of the SparkDevNetwork GitHub org avatar that was wrongly substituted for it. Co-authored-by: Cursor <[email protected]> * fix(docs): regenerate playground GIF with live indicator states Restore the capture script for the new pane-indicator layout so the README demo shows correct idle/active/pending/ok colors and pulsing animations while typing. * fix(docs): static playground GIF with correct indicator colors Capture one frame per keystroke with animations disabled so dot states (idle/active/pending/ok) match the live playground without pulsing. Co-authored-by: Cursor <[email protected]> * docs: use square Rock RMS icon in Used by section Co-authored-by: Cursor <[email protected]> * fix(docs): ensure capture indicator colors apply instantly Disable indicator transitions and cancel active animations before setting data-state so pending yellow is not stuck on the prior ok green. Co-authored-by: Cursor <[email protected]> * docs: point Microsoft Used by link to microsoft.com The merged tile title covers Power Pages and Azure API Management; href should go to Microsoft home, not Power Pages only. Co-authored-by: Cursor <[email protected]> * docs: remove Dailycontributors from Used by section No evidence they run on LiquidJS; they are an OpenCollective sponsor only. Co-authored-by: Cursor <[email protected]> * docs: reword intro to say Liquid, not Shopify Liquid Move Shopify into the compatibility list and drop the shopify/liquid link from README; align package.json description. Co-authored-by: Cursor <[email protected]> * fix(docs): restore playground output as Prism-highlighted HTML Co-authored-by: Cursor <[email protected]> * docs: add extensible to README intro and package description EOF Co-authored-by: Cursor <[email protected]> * chore: move playground capture script to .local Co-authored-by: Cursor <[email protected]> * fix(docs): drop unused Ace mode-html from playground Output pane uses Prism, not Ace; template and context editors still need liquid/json modes and basePath for themes. Co-authored-by: Cursor <[email protected]> * docs: sync intro sentence across package and site metadata Align package.json, docs config, manifest, llms.txt, and AGENTS.md tagline to the README canonical description. Co-authored-by: Cursor <[email protected]> * docs: trim verbose intro in intro-to-liquid tutorial Remove README tagline and repo-purpose copy duplicated by the recent metadata sync. Co-authored-by: Cursor <[email protected]> * docs: shorten homepage banner subtitle Trim docs site banner and short taglines after the em dash; keep full description for meta tags and npm/README. * docs: simplify playground GIF caption in README Co-authored-by: Cursor <[email protected]> * docs: dedupe homepage subtitle and description into _config.yml Remove redundant front matter from index.pug; theme falls back to site config for banner and meta tags. Co-authored-by: Cursor <[email protected]> --------- Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -15,6 +15,7 @@ node_modules/
|
|||||||
docs/themes/navy/source/js/liquid.browser.min.js
|
docs/themes/navy/source/js/liquid.browser.min.js
|
||||||
docs/themes/navy/layout/partial/all-contributors.swig
|
docs/themes/navy/layout/partial/all-contributors.swig
|
||||||
docs/themes/navy/layout/partial/financial-contributors.swig
|
docs/themes/navy/layout/partial/financial-contributors.swig
|
||||||
|
docs/themes/navy/layout/partial/used-by.swig
|
||||||
dist/
|
dist/
|
||||||
demo/*/yarn.json
|
demo/*/yarn.json
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# LiquidJS
|
# LiquidJS
|
||||||
|
|
||||||
Shopify / GitHub Pages compatible Liquid template engine. TypeScript in `src/`, bundles in `dist/`. Docs site in `docs/` (Hexo, `navy` theme).
|
A simple, expressive, extensible Liquid template engine for JavaScript — Shopify, Jekyll and GitHub Pages compatible, for Node.js, browsers, and the CLI, with TypeScript support. TypeScript in `src/`, bundles in `dist/`. Docs site in `docs/` (Hexo, `navy` theme).
|
||||||
|
|
||||||
## Layout
|
## Layout
|
||||||
|
|
||||||
|
|||||||
@@ -1,72 +1,86 @@
|
|||||||
# liquidjs
|
# LiquidJS
|
||||||
|
|
||||||
|
A simple, expressive, extensible Liquid template engine for JavaScript — Shopify, Jekyll and GitHub Pages compatible, for Node.js, browsers, and the CLI, with TypeScript support.
|
||||||
|
|
||||||
[](https://www.npmjs.org/package/liquidjs)
|
[](https://www.npmjs.org/package/liquidjs)
|
||||||
[](https://www.npmjs.org/package/liquidjs)
|
[](https://www.npmjs.org/package/liquidjs)
|
||||||
[](https://coveralls.io/github/harttle/liquidjs?branch=master)
|
|
||||||
[](https://github.com/harttle/liquidjs/actions/workflows/ci-build.yml?query=branch%3Amaster)
|
[](https://github.com/harttle/liquidjs/actions/workflows/ci-build.yml?query=branch%3Amaster)
|
||||||
[](https://github.com/harttle/liquidjs/blob/master/LICENSE)
|
[](https://coveralls.io/github/harttle/liquidjs?branch=master)
|
||||||
[](https://github.com/harttle/liquidjs)
|
[](https://github.com/harttle/liquidjs/blob/master/LICENSE)
|
||||||
|
|
||||||
A simple, expressive and safe [Shopify][shopify/liquid] / GitHub Pages compatible template engine in pure JavaScript.
|
[Documentation][doc] · [Playground](https://liquidjs.com/playground.html) · [Setup guide][setup] · [Contributing][contribution]
|
||||||
**The purpose of this repo** is to provide a standard Liquid implementation for the JavaScript community so that [Jekyll sites](https://jekyllrb.com), [GitHub Pages](https://pages.github.com/) and [Shopify templates](https://themes.shopify.com/) can be ported to Node.js without pain.
|
|
||||||
|
|
||||||
* [Documentation][doc]
|
<a href="https://liquidjs.com/playground.html">
|
||||||
* Please star [LiquidJS on GitHub][github]!
|
<img src="docs/source/playground-demo.gif" alt="LiquidJS playground: edit a template and context, see live HTML output" width="980" style="display: block; margin: 0 auto;" />
|
||||||
* Financial support via [GitHub Sponsors](https://github.com/sponsors/harttle).
|
</a>
|
||||||
|
|
||||||
<p align="center"><a href="https://liquidjs.com"><img height="155px" width="155px" src="https://liquidjs.com/icon/mstile-310x310.png" alt="logo"></a></p>
|
<p align="center"><sub>Try the <a href="https://liquidjs.com/playground.html">online playground</a>.</sub></p>
|
||||||
|
|
||||||
## What's it like?
|
## Quick start
|
||||||
|
|
||||||
Basically there're two types of Liquid syntax: tags enclosed by `{% %}` and outputs enclosed by `{{ }}`. A Liquid template looks like:
|
```js
|
||||||
|
import { Liquid } from 'liquidjs'
|
||||||
|
|
||||||
```liquid
|
const engine = new Liquid()
|
||||||
{% if username %}
|
const html = await engine.parseAndRender(
|
||||||
{{ username | append: ", welcome to LiquidJS!" | capitalize }}
|
'Hello, {{ name | capitalize }}!',
|
||||||
{% endif %}
|
{ name: 'liquid' }
|
||||||
|
)
|
||||||
|
//=> 'Hello, Liquid!'
|
||||||
```
|
```
|
||||||
|
|
||||||
[A live demo](https://liquidjs.com/playground.html) is also available and here's a [quick tutorial](https://liquidjs.com/tutorials/intro-to-liquid.html) for Liquid syntax.
|
|
||||||
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Install from npm in Node.js:
|
**Node.js**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install liquidjs
|
npm install liquidjs
|
||||||
```
|
```
|
||||||
|
|
||||||
Or use the UMD bundle from jsDelivr:
|
**Browser** (jsDelivr UMD bundle)
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script src="https://cdn.jsdelivr.net/npm/liquidjs/dist/liquid.browser.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/liquidjs/dist/liquid.browser.min.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
Or render directly from CLI using npx:
|
**CLI**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx liquidjs --template 'Hello, {{ name }}!' --context '{"name": "Snake"}'
|
npx liquidjs --template 'Hello, {{ name }}!' --context '{"name": "Liquid"}'
|
||||||
```
|
```
|
||||||
|
|
||||||
For more details, refer to the [Setup Guide][setup].
|
See the [setup guide][setup] for partials, layouts, caching, and other options.
|
||||||
|
|
||||||
## Who's Using LiquidJS?
|
## Used by
|
||||||
|
|
||||||
- [Eleventy](https://www.11ty.dev/): Eleventy, a simpler static site generator.
|
<!-- USED-BY-BEGIN -->
|
||||||
- [Github Docs](https://github.com/github/docs): The open-source repo for docs.github.com.
|
<p align="center" style="line-height: 2.5;">
|
||||||
- [Kibana](https://github.com/elastic/kibana): Elastic's analytics and visualization platform for Elasticsearch; workflow features use LiquidJS for Liquid templates.
|
<a href="https://www.11ty.dev/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/35147177?v=4&s=100" height="80" style="vertical-align: middle;" alt="Eleventy" title="Eleventy"/></a>
|
||||||
- [Opensense](https://www.opensense.com/): The smarter way to send email.
|
<a href="https://www.opensense.com/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://images.opencollective.com/opensense-inc/bf840ae/logo/256.png?height=100" height="80" style="vertical-align: middle;" alt="Opensense" title="Opensense"/></a>
|
||||||
- [Directus](https://docs.directus.io/): an instant REST+GraphQL API and intuitive no-code data collaboration app for any SQL database.
|
<a href="https://www.microsoft.com/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/6154722?v=4&s=100" height="80" style="vertical-align: middle;" alt="Power Pages, Azure API Management developer portal" title="Power Pages, Azure API Management developer portal"/></a>
|
||||||
- [Rock](https://www.rockrms.com/): An open source CMS, Relationship Management System (RMS) and Church Management System (ChMS) all rolled into one.
|
<a href="https://docs.github.com/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/9919?v=4&s=100" height="80" style="vertical-align: middle;" alt="GitHub Docs" title="GitHub Docs"/></a>
|
||||||
- [Mitosis](https://github.com/BuilderIO/mitosis): Write components once, run everywhere. Compiles to React, Vue, Qwik, Solid, Angular, Svelte, and more.
|
<a href="https://github.com/elastic/kibana" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/6764390?v=4&s=100" height="80" style="vertical-align: middle;" alt="Kibana" title="Kibana"/></a>
|
||||||
- [Pattern Lab](https://patternlab.io/): a frontend workshop environment that helps you build, view, test, and showcase your design system's UI components.
|
<a href="https://www.shopify.com/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/8085?v=4&s=100" height="80" style="vertical-align: middle;" alt="Shopify CLI, Checkout Blocks" title="Shopify CLI, Checkout Blocks"/></a>
|
||||||
- [Builder.io](https://www.builder.io/m/developers): the first and only headless CMS with a visual editor that lets you drag and drop with your components, directly within your current site or app. Completely API-driven, for cleaner code and simpler workflows.
|
<a href="https://customer.io/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/1152079?v=4&s=100" height="80" style="vertical-align: middle;" alt="Customer IO" title="Customer IO"/></a>
|
||||||
- [Microsoft Power Pages](https://learn.microsoft.com/en-us/power-pages/introduction): a secure, enterprise-grade, low-code software as a service (SaaS) platform for creating, hosting, and administering modern external-facing business websites.
|
<br/>
|
||||||
- [Azure API Management developer portal](https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-developer-portal): an automatically generated, fully customizable website with the documentation of your APIs.
|
<a href="https://syntax.fm/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/130389858?v=4&s=100" height="80" style="vertical-align: middle;" alt="Syntax Podcast" title="Syntax Podcast"/></a>
|
||||||
- [WISMOlabs](https://wismolabs.com/): Post Purchase Experience platform for eCommerce retailers enhancing customer satisfaction by using LiquidJS to provide customizable post-purchase experiences through programmable email, SMS, order tracking pages, and webhooks.
|
<a href="https://www.testmuai.com/?utm_medium=sponsor&utm_source=liquidjs" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/27130435?s=200&v=4" width="80" style="vertical-align: middle;" alt="TestMu AI" title="TestMu AI"/></a>
|
||||||
- [Freshet](https://chromewebstore.google.com/detail/freshet/mpclplhdencffbilobpcapccnihpelcg): *JSON in, page out* — a Chrome extension that uses LiquidJS templates per URL pattern, so the JSON becomes a rendered, useful page.
|
<a href="https://chudovo.com/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://images.opencollective.com/Chudovo/avatar/256.png?height=100" width="160" style="vertical-align: middle;background: white;padding: 8px 16px;" alt="Chudovo" title="Chudovo"/></a>
|
||||||
|
<a href="https://www.pakstyle.pk/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://images.opencollective.com/pakstyle/2b81605/logo/256.png?height=100" height="80" style="vertical-align: middle;" alt="PakStyle.pk" title="PakStyle.pk"/></a>
|
||||||
|
<a href="https://www.escorta.com/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://images.opencollective.com/escortacom/avatar/256.png?height=100" height="45" style="vertical-align: middle;" alt="EscortA.com" title="EscortA.com"/></a>
|
||||||
|
<a href="https://opencollective.com/touchless" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://images.opencollective.com/touchless/273bc74/logo/256.png?height=100" height="80" style="vertical-align: middle;" alt="Touchless" title="Touchless"/></a>
|
||||||
|
<br/>
|
||||||
|
<a href="https://www.dropkiq.com/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://images.opencollective.com/1bertlol/43a8ea8/logo/256.png?height=100" height="80" style="vertical-align: middle;" alt="Dropkiq" title="Dropkiq"/></a>
|
||||||
|
<a href="https://directus.io/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/15967950?v=4&s=100" height="80" style="vertical-align: middle;" alt="Directus" title="Directus"/></a>
|
||||||
|
<a href="https://www.builder.io/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F51a002f4a17f4fc4a829b8891a1c25ee" height="80" style="vertical-align: middle;" alt="Builder.io, Mitosis" title="Builder.io, Mitosis"/></a>
|
||||||
|
<a href="https://patternlab.io/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/4733935?v=4&s=100" height="80" style="vertical-align: middle;" alt="Pattern Lab" title="Pattern Lab"/></a>
|
||||||
|
<a href="https://www.rockrms.com/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://www.rockrms.com/GetImage.ashx?id=72533" height="80" style="vertical-align: middle;" alt="Rock RMS" title="Rock RMS"/></a>
|
||||||
|
<a href="https://wismolabs.com/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://cdn-ldlap.nitrocdn.com/DsLJMZpUUekfsitqBnNmsRAnzbwPoIzE/assets/images/optimized/rev-5df8687/wismolabs.com/wp-content/uploads/2023/03/favicon-300x300.png" height="80" style="vertical-align: middle;" alt="WISMOlabs" title="WISMOlabs"/></a>
|
||||||
|
<a href="https://chromewebstore.google.com/detail/freshet/mpclplhdencffbilobpcapccnihpelcg" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://raw.githubusercontent.com/MattAltermatt/freshet/main/public/icon-128.png" height="80" style="vertical-align: middle;" alt="Freshet" title="Freshet"/></a>
|
||||||
|
</p>
|
||||||
|
<!-- USED-BY-END -->
|
||||||
|
|
||||||
Feel free to create a PR or contact me to add your use case into this list!
|
Products and projects running on LiquidJS. [Open a PR](https://github.com/harttle/liquidjs/edit/master/README.md) to add yours.
|
||||||
|
|
||||||
## Financial Support
|
## Financial Support
|
||||||
|
|
||||||
@@ -78,7 +92,7 @@ If you personally love LiquidJS or it's benefiting your business, please conside
|
|||||||
<a href="https://www.opensense.com/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://images.opencollective.com/opensense-inc/bf840ae/logo/256.png?height=100" height="80" style="vertical-align: middle;" alt="Opensense Inc." title="Opensense"/></a>
|
<a href="https://www.opensense.com/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://images.opencollective.com/opensense-inc/bf840ae/logo/256.png?height=100" height="80" style="vertical-align: middle;" alt="Opensense Inc." title="Opensense"/></a>
|
||||||
<a href="https://github.com/microsoft" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/6154722?v=4&s=100" height="80" style="vertical-align: middle;" alt="Microsoft" title="Microsoft"/></a>
|
<a href="https://github.com/microsoft" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/6154722?v=4&s=100" height="80" style="vertical-align: middle;" alt="Microsoft" title="Microsoft"/></a>
|
||||||
<a href="https://sentry.io/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/1396951?v=4&s=100" height="80" style="vertical-align: middle;" alt="Sentry" title="Sentry"/></a>
|
<a href="https://sentry.io/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/1396951?v=4&s=100" height="80" style="vertical-align: middle;" alt="Sentry" title="Sentry"/></a>
|
||||||
<a href="https://www.checkoutblocks.com/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/114603307?v=4&s=100" height="80" style="vertical-align: middle;" alt="Checkout Blocks" title="Checkout Blocks"/></a>
|
<a href="https://github.com/Checkout-Blocks" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/114603307?v=4&s=100" height="80" style="vertical-align: middle;" alt="Checkout Blocks" title="Checkout Blocks"/></a>
|
||||||
<a href="https://customer.io/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/1152079?v=4&s=100" height="80" style="vertical-align: middle;" alt="Customer IO" title="Customer IO"/></a>
|
<a href="https://customer.io/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/1152079?v=4&s=100" height="80" style="vertical-align: middle;" alt="Customer IO" title="Customer IO"/></a>
|
||||||
<a href="https://syntax.fm/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/130389858?v=4&s=100" height="80" style="vertical-align: middle;" alt="Syntax Podcast" title="Syntax Podcast"/></a>
|
<a href="https://syntax.fm/" style="display: inline-block; vertical-align: middle; margin: 8px;"><img src="https://avatars.githubusercontent.com/u/130389858?v=4&s=100" height="80" style="vertical-align: middle;" alt="Syntax Podcast" title="Syntax Podcast"/></a>
|
||||||
<br/>
|
<br/>
|
||||||
@@ -234,8 +248,10 @@ Want to contribute? see [Contribution Guidelines][contribution]. Thanks goes to
|
|||||||
|
|
||||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||||
|
|
||||||
[shopify/liquid]: https://shopify.github.io/liquid/
|
## License
|
||||||
[plugins]: https://liquidjs.com/tutorials/plugins.html#Plugin-List
|
|
||||||
|
[MIT](LICENSE) © [Jun Yang](https://github.com/harttle)
|
||||||
|
|
||||||
[setup]: https://liquidjs.com/tutorials/setup.html
|
[setup]: https://liquidjs.com/tutorials/setup.html
|
||||||
[doc]: https://liquidjs.com
|
[doc]: https://liquidjs.com
|
||||||
[github]: https://github.com/harttle/liquidjs
|
[github]: https://github.com/harttle/liquidjs
|
||||||
|
|||||||
@@ -33,7 +33,9 @@ function transformFinancial (html) {
|
|||||||
|
|
||||||
const allContributors = transformContributors(extractSection(readme, 'ALL-CONTRIBUTORS-LIST:START', 'ALL-CONTRIBUTORS-LIST:END'))
|
const allContributors = transformContributors(extractSection(readme, 'ALL-CONTRIBUTORS-LIST:START', 'ALL-CONTRIBUTORS-LIST:END'))
|
||||||
const financialContributors = transformFinancial(extractSection(readme, 'FINANCIAL-CONTRIBUTORS-BEGIN', 'FINANCIAL-CONTRIBUTORS-END'))
|
const financialContributors = transformFinancial(extractSection(readme, 'FINANCIAL-CONTRIBUTORS-BEGIN', 'FINANCIAL-CONTRIBUTORS-END'))
|
||||||
|
const usedBy = transformFinancial(extractSection(readme, 'USED-BY-BEGIN', 'USED-BY-END'))
|
||||||
|
|
||||||
const outDir = path.join(root, 'docs/themes/navy/layout/partial')
|
const outDir = path.join(root, 'docs/themes/navy/layout/partial')
|
||||||
fs.writeFileSync(path.join(outDir, 'all-contributors.swig'), allContributors)
|
fs.writeFileSync(path.join(outDir, 'all-contributors.swig'), allContributors)
|
||||||
fs.writeFileSync(path.join(outDir, 'financial-contributors.swig'), financialContributors)
|
fs.writeFileSync(path.join(outDir, 'financial-contributors.swig'), financialContributors)
|
||||||
|
fs.writeFileSync(path.join(outDir, 'used-by.swig'), usedBy)
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
title: LiquidJS
|
title: LiquidJS
|
||||||
subtitle: "A simple, expressive, and safe template engine for JavaScript."
|
subtitle: "A simple, expressive, extensible Liquid template engine for JavaScript"
|
||||||
description: "LiquidJS is a simple, expressive, and safe template engine for JavaScript, compatible with Shopify and GitHub Pages."
|
description: "A simple, expressive, extensible Liquid template engine for JavaScript — Shopify, Jekyll and GitHub Pages compatible, for Node.js, browsers, and the CLI, with TypeScript support."
|
||||||
author: Harttle
|
author: Harttle
|
||||||
language: en
|
language: en
|
||||||
timezone: UTC
|
timezone: UTC
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
layout: index
|
layout: index
|
||||||
description: LiquidJS is a simple, expressive and safe Shopify / GitHub Pages compatible template engine in pure JavaScript.
|
|
||||||
subtitle: A simple, expressive and safe template engine.
|
|
||||||
---
|
---
|
||||||
ul#intro-feature-list
|
ul#intro-feature-list
|
||||||
li.intro-feature-wrap
|
li.intro-feature-wrap
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# LiquidJS
|
# LiquidJS
|
||||||
|
|
||||||
> A simple, expressive and safe Shopify / Github Pages compatible template engine in pure JavaScript.
|
> A simple, expressive, extensible Liquid template engine for JavaScript
|
||||||
|
|
||||||
## Tutorials
|
## Tutorials
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"short_name": "LiquidJS",
|
"short_name": "LiquidJS",
|
||||||
"name": "LiquidJS",
|
"name": "LiquidJS",
|
||||||
"description": "A simple, expressive and safe Shopify / GitHub Pages compatible template engine in pure JavaScript.",
|
"description": "A simple, expressive, extensible Liquid template engine for JavaScript",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "/icon/apple-touch-icon-57x57.png",
|
"src": "/icon/apple-touch-icon-57x57.png",
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
@@ -3,9 +3,9 @@ title: The Liquid Template Language
|
|||||||
describe: A short introduction to the Liquid template language and some simple demos.
|
describe: A short introduction to the Liquid template language and some simple demos.
|
||||||
---
|
---
|
||||||
|
|
||||||
LiquidJS is a simple, expressive and safe [Shopify][shopify/liquid] / GitHub Pages compatible template engine in pure JavaScript. The purpose of this repo is to provide a standard Liquid implementation for the JavaScript community. Liquid is originally implemented in Ruby and used by GitHub Pages, Jekyll and Shopify, see [Differences with Shopify/liquid][diff].
|
Liquid is a template language originally implemented in Ruby and used by Shopify, Jekyll, and GitHub Pages. LiquidJS implements it in JavaScript; see [Differences with Shopify/liquid][diff] for compatibility notes.
|
||||||
|
|
||||||
LiquidJS syntax is relatively simple. There are 2 types of markups in LiquidJS:
|
There are 2 types of markups in LiquidJS:
|
||||||
|
|
||||||
- **Tags**. A tag consists of a tag name and optional arguments wrapped between `{%raw%}{%{%endraw%}` and `%}`.
|
- **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**. An output consists of a value and a list of filters, which is optional, wrapped between `{%raw%}{{{%endraw%}` and `}}`.
|
||||||
@@ -56,5 +56,4 @@ Typically tags appear in pairs with a start tag and a corresponding end tag. For
|
|||||||
|
|
||||||
A complete list of tags supported by LiquidJS can be found [here](../tags/overview.html).
|
A complete list of tags supported by LiquidJS can be found [here](../tags/overview.html).
|
||||||
|
|
||||||
[shopify/liquid]: https://github.com/Shopify/liquid
|
|
||||||
[diff]: ./differences.html
|
[diff]: ./differences.html
|
||||||
|
|||||||
Vendored
+5
-1
@@ -13,10 +13,14 @@ index:
|
|||||||
description: 'Thanks to these wonderful people! See <a href="tutorials/contribution-guidelines.html">contribution guidelines</a> if you'd like to help.'
|
description: 'Thanks to these wonderful people! See <a href="tutorials/contribution-guidelines.html">contribution guidelines</a> if you'd like to help.'
|
||||||
sponsors:
|
sponsors:
|
||||||
title: Sponsors
|
title: Sponsors
|
||||||
description: 'If you personally love LiquidJS or it's benefiting your business, please <a href="https://github.com/sponsors/harttle">sponsor us</a>!'
|
description: 'Organizations and individuals who <a href="https://github.com/sponsors/harttle">sponsor LiquidJS</a>. Thank you!'
|
||||||
|
used_by:
|
||||||
|
title: Used by
|
||||||
|
description: 'Products and projects running on LiquidJS. <a href="https://github.com/harttle/liquidjs/edit/master/README.md">Open a PR</a> to add yours.'
|
||||||
|
|
||||||
playground:
|
playground:
|
||||||
title: Playground
|
title: Playground
|
||||||
|
lead: Edit a template and context JSON — rendered HTML updates as you type.
|
||||||
loading: Loading...
|
loading: Loading...
|
||||||
|
|
||||||
page:
|
page:
|
||||||
|
|||||||
Vendored
+18
-5
@@ -1,6 +1,6 @@
|
|||||||
<header id="banner" class="wrapper">
|
<header id="banner" class="wrapper">
|
||||||
<div class="inner inner-content">
|
<div class="inner inner-content">
|
||||||
<h2 id="banner-title">{{ page.subtitle }}</h2>
|
<h2 id="banner-title">{{ page.subtitle | default(config.subtitle) }}</h2>
|
||||||
<div id="banner-share">{{ partial('partial/share') }}</div>
|
<div id="banner-share">{{ partial('partial/share') }}</div>
|
||||||
<div id="banner-start">
|
<div id="banner-start">
|
||||||
<code id="banner-start-command">npm install liquidjs</code><a id="banner-start-link" href="./tutorials/setup.html"><i class="icon-arrow-right"></i></a>
|
<code id="banner-start-command">npm install liquidjs</code><a id="banner-start-link" href="./tutorials/setup.html"><i class="icon-arrow-right"></i></a>
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="contributors-wrap">
|
<div id="used-by-wrap">
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div class="inner inner-content">
|
<div class="inner inner-content">
|
||||||
<div class="section-header">
|
<div class="section-header">
|
||||||
<h3>{{__('index.contributors.title')}}</h3>
|
<h3>{{__('index.used_by.title')}}</h3>
|
||||||
<p class="description">{{__('index.contributors.description')}}</p>
|
<p class="description">{{__('index.used_by.description')}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="contributors">
|
<div class="contributors">
|
||||||
{{ partial('partial/all-contributors') }}
|
{{ partial('partial/used-by') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -40,3 +40,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="contributors-wrap">
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="inner inner-content">
|
||||||
|
<div class="section-header">
|
||||||
|
<h3>{{__('index.contributors.title')}}</h3>
|
||||||
|
<p class="description">{{__('index.contributors.description')}}</p>
|
||||||
|
</div>
|
||||||
|
<div class="contributors">
|
||||||
|
{{ partial('partial/all-contributors') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
{% if page.layout === 'playground' %}
|
{% if page.layout === 'playground' %}
|
||||||
{{ js('js/liquid.browser.min.js') }}
|
{{ js('js/liquid.browser.min.js') }}
|
||||||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/src-min/ace.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/[email protected]/src-min/ace.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/[email protected]/src-min/mode-liquid.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/[email protected]/src-min/mode-json.js"></script>
|
||||||
|
<script>ace.config.set('basePath', 'https://cdn.jsdelivr.net/npm/[email protected]/src-min/');</script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/[email protected]/prism.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/[email protected]/components/prism-markup.min.js"></script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{{ js('js/main') }}
|
{{ js('js/main') }}
|
||||||
|
|||||||
+1
-5
@@ -1,7 +1,3 @@
|
|||||||
{
|
{
|
||||||
"people": [
|
"name": "liquid"
|
||||||
"alice",
|
|
||||||
"bob",
|
|
||||||
"carol"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-9
@@ -1,9 +1 @@
|
|||||||
<ul>
|
<p>Hello, {{ name | capitalize }}!</p>
|
||||||
{%- for person in people %}
|
|
||||||
<li>
|
|
||||||
<a href="{{person | prepend: "https://example.com/"}}">
|
|
||||||
{{ person | capitalize }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{%- endfor%}
|
|
||||||
</ul>
|
|
||||||
|
|||||||
+37
-13
@@ -1,21 +1,45 @@
|
|||||||
<div id="playground" role="main">
|
<div id="playground" role="main">
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<h1 class="inner">{{__('playground.title')}}</h1>
|
<header class="playground-hero inner">
|
||||||
|
<div class="playground-hero-text">
|
||||||
|
<h1>{{__('playground.title')}}</h1>
|
||||||
|
<p class="playground-lead">{{__('playground.lead')}}</p>
|
||||||
|
</div>
|
||||||
|
<p class="playground-version version"></p>
|
||||||
|
</header>
|
||||||
<div class="loader" role=status aria-busy=true></div>
|
<div class="loader" role=status aria-busy=true></div>
|
||||||
<div id="editors" class="inner hide" aria-hide=true>
|
<div id="editors" class="inner hide" aria-hide=true>
|
||||||
<div class="area-tpl editor-wrapper">
|
<div class="playground-workspace">
|
||||||
<h2>Template</h2>
|
<div class="playground-pane area-tpl">
|
||||||
<div class="editor" id="editorEl">{{ raw('partial/demo.liquid') }}</div>
|
<div class="pane-head">
|
||||||
</div>
|
<span class="pane-indicator" data-state="idle" aria-hidden="true"></span>
|
||||||
<div class="area-data editor-wrapper">
|
<h2>Template</h2>
|
||||||
<h2>Context</h2>
|
</div>
|
||||||
<div class="editor" id="dataEl">{{ raw('partial/demo.json') }}</div>
|
<div class="pane-body">
|
||||||
</div>
|
<div class="editor" id="editorEl">{{ raw('partial/demo.liquid') }}</div>
|
||||||
<div class="area-output editor-wrapper">
|
</div>
|
||||||
<h2>Output</h2>
|
</div>
|
||||||
<div class="editor" id="previewEl">{{__('playground.loading')}}</div>
|
<div class="playground-pane area-data">
|
||||||
|
<div class="pane-head">
|
||||||
|
<span class="pane-indicator" data-state="idle" aria-hidden="true"></span>
|
||||||
|
<h2>Context</h2>
|
||||||
|
</div>
|
||||||
|
<div class="pane-body">
|
||||||
|
<div class="editor" id="dataEl">{{ raw('partial/demo.json') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="playground-pane area-output">
|
||||||
|
<div class="pane-head">
|
||||||
|
<span class="pane-indicator" data-state="idle" aria-hidden="true"></span>
|
||||||
|
<h2>Output</h2>
|
||||||
|
</div>
|
||||||
|
<div class="pane-body">
|
||||||
|
<div class="output-preview" id="previewEl">
|
||||||
|
<pre class="highlight"><code class="language-markup" id="previewCode">{{__('playground.loading')}}</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="inner version"></p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+2
-2
@@ -126,7 +126,7 @@
|
|||||||
background: var(--color-link-hover)
|
background: var(--color-link-hover)
|
||||||
color: #fff
|
color: #fff
|
||||||
|
|
||||||
#sponsors-wrap, #contributors-wrap
|
#used-by-wrap, #sponsors-wrap, #contributors-wrap
|
||||||
background: var(--color-navy-lighter)
|
background: var(--color-navy-lighter)
|
||||||
border-top: 1px solid #161d24
|
border-top: 1px solid #161d24
|
||||||
border-bottom: 1px solid #161d24
|
border-bottom: 1px solid #161d24
|
||||||
@@ -181,7 +181,7 @@
|
|||||||
|
|
||||||
#contributors-wrap
|
#contributors-wrap
|
||||||
border: none
|
border: none
|
||||||
overflow: hidden;
|
overflow: hidden
|
||||||
|
|
||||||
.contributors
|
.contributors
|
||||||
tr
|
tr
|
||||||
|
|||||||
+260
-55
@@ -1,107 +1,312 @@
|
|||||||
#playground
|
#playground
|
||||||
|
--playground-gap: 12px
|
||||||
|
--playground-radius: 10px
|
||||||
|
--playground-inset: 16px
|
||||||
background: var(--color-content-bg)
|
background: var(--color-content-bg)
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
box-shadow: var(--panel-shadow)
|
box-shadow: var(--panel-shadow)
|
||||||
|
|
||||||
.wrapper
|
.wrapper
|
||||||
margin-bottom: 40px
|
margin-bottom: 32px
|
||||||
|
@media mq-mobile
|
||||||
|
margin-bottom: 20px
|
||||||
|
|
||||||
|
.playground-hero
|
||||||
|
display: flex
|
||||||
|
flex-wrap: wrap
|
||||||
|
align-items: flex-end
|
||||||
|
justify-content: space-between
|
||||||
|
gap: 16px 24px
|
||||||
|
padding-top: 32px
|
||||||
|
padding-bottom: 20px
|
||||||
|
@media mq-mobile
|
||||||
|
padding-top: 16px
|
||||||
|
padding-bottom: 12px
|
||||||
|
gap: 10px
|
||||||
|
align-items: flex-start
|
||||||
|
|
||||||
|
.playground-hero-text
|
||||||
|
flex: 1 1 280px
|
||||||
|
min-width: 0
|
||||||
|
|
||||||
h1
|
h1
|
||||||
font-size: 36px
|
font-size: 28px
|
||||||
font-weight: 300
|
|
||||||
margin-top: 40px
|
|
||||||
margin-bottom: 24px
|
|
||||||
color: var(--color-default)
|
|
||||||
|
|
||||||
h2
|
|
||||||
font-size: 0.8125rem
|
|
||||||
font-weight: 600
|
font-weight: 600
|
||||||
text-transform: uppercase
|
letter-spacing: -0.02em
|
||||||
letter-spacing: 0.04em
|
margin: 0 0 8px
|
||||||
color: var(--color-gray)
|
color: var(--color-default)
|
||||||
|
@media mq-mobile
|
||||||
|
font-size: 22px
|
||||||
|
margin-bottom: 4px
|
||||||
|
|
||||||
|
.playground-lead
|
||||||
margin: 0
|
margin: 0
|
||||||
|
font-size: 15px
|
||||||
|
line-height: 1.5
|
||||||
|
color: var(--color-gray)
|
||||||
|
@media mq-mobile
|
||||||
|
font-size: 14px
|
||||||
|
line-height: 1.45
|
||||||
|
|
||||||
|
.playground-version
|
||||||
|
flex: 0 0 auto
|
||||||
|
margin: 0
|
||||||
|
font-size: 12px
|
||||||
|
line-height: 1.4
|
||||||
|
font-family: font-mono
|
||||||
|
padding: 6px 12px
|
||||||
|
border-radius: 999px
|
||||||
|
background: var(--playground-surface)
|
||||||
|
border: 1px solid var(--color-border)
|
||||||
|
color: var(--color-gray)
|
||||||
|
a
|
||||||
|
color: var(--color-default)
|
||||||
|
text-decoration: none
|
||||||
|
font-weight: 500
|
||||||
|
&:hover
|
||||||
|
color: var(--color-link)
|
||||||
|
text-decoration: none
|
||||||
|
|
||||||
#editors
|
#editors
|
||||||
display: grid
|
|
||||||
overflow: hidden
|
|
||||||
margin-bottom: 0
|
margin-bottom: 0
|
||||||
height: 75vh
|
|
||||||
min-height: 480px
|
.playground-workspace
|
||||||
|
display: grid
|
||||||
|
gap: var(--playground-gap)
|
||||||
grid-template-columns: 1fr 1fr
|
grid-template-columns: 1fr 1fr
|
||||||
grid-template-rows: 3fr 2fr
|
grid-template-rows: 3fr 2fr
|
||||||
grid-gap: 16px
|
|
||||||
align-items: stretch
|
align-items: stretch
|
||||||
|
@media mq-normal
|
||||||
|
overflow: hidden
|
||||||
|
height: 75vh
|
||||||
|
max-height: unquote('calc(100vh - 200px)')
|
||||||
|
min-height: 520px
|
||||||
@media mq-mobile
|
@media mq-mobile
|
||||||
height: auto
|
|
||||||
min-height: 0
|
|
||||||
grid-template-columns: 1fr
|
grid-template-columns: 1fr
|
||||||
grid-template-rows: auto
|
grid-template-rows: auto
|
||||||
grid-gap: 20px
|
gap: 12px
|
||||||
|
|
||||||
.area-tpl
|
.area-tpl
|
||||||
grid-row: 1
|
grid-row: 1
|
||||||
grid-column: 1
|
grid-column: 1
|
||||||
min-height: 0
|
min-height: 0
|
||||||
|
--pane-dot: var(--color-link)
|
||||||
.area-data
|
.area-data
|
||||||
grid-row: 2
|
grid-row: 2
|
||||||
grid-column: 1
|
grid-column: 1
|
||||||
min-height: 0
|
min-height: 0
|
||||||
|
--pane-dot: var(--highlight-orange)
|
||||||
.area-output
|
.area-output
|
||||||
grid-column: 2
|
grid-column: 2
|
||||||
grid-row: 1 / -1
|
grid-row: 1 / -1
|
||||||
min-height: 0
|
min-height: 0
|
||||||
|
min-width: 0
|
||||||
|
--pane-dot: var(--highlight-green)
|
||||||
@media mq-mobile
|
@media mq-mobile
|
||||||
grid-row: auto
|
grid-row: auto
|
||||||
grid-column: 1
|
grid-column: 1
|
||||||
|
|
||||||
.editor-wrapper
|
.playground-pane
|
||||||
display: flex
|
display: flex
|
||||||
gap: 8px
|
|
||||||
flex-direction: column
|
flex-direction: column
|
||||||
min-height: 0
|
min-height: 0
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
.editor
|
background: var(--playground-pane-head)
|
||||||
flex: 1 1 auto
|
border: 1px solid var(--code-border)
|
||||||
min-height: 0
|
border-radius: var(--playground-radius)
|
||||||
position: relative
|
box-shadow: var(--code-shadow)
|
||||||
code-block-chrome()
|
|
||||||
overflow: hidden
|
|
||||||
@media mq-mobile
|
|
||||||
min-height: 240px
|
|
||||||
.ace_editor
|
|
||||||
font-family: font-mono
|
|
||||||
font-size: 14px
|
|
||||||
line-height: 1.5
|
|
||||||
border-radius: 6px
|
|
||||||
.ace_scrollbar
|
|
||||||
z-index: 2
|
|
||||||
|
|
||||||
.version
|
.pane-head
|
||||||
font-size: 0.8125rem
|
display: flex
|
||||||
line-height: 1.5
|
align-items: center
|
||||||
|
gap: 10px
|
||||||
|
flex-shrink: 0
|
||||||
|
height: 36px
|
||||||
|
padding: 0 var(--playground-inset)
|
||||||
|
border-bottom: 1px solid var(--code-border)
|
||||||
|
@media mq-mobile
|
||||||
|
height: 32px
|
||||||
|
padding: 0 10px
|
||||||
|
h2
|
||||||
|
font-size: 13px
|
||||||
|
font-weight: 600
|
||||||
|
letter-spacing: 0.01em
|
||||||
|
text-transform: none
|
||||||
|
color: var(--color-default)
|
||||||
|
margin: 0
|
||||||
|
@media mq-mobile
|
||||||
|
font-size: 12px
|
||||||
|
|
||||||
|
.pane-indicator
|
||||||
|
width: 8px
|
||||||
|
height: 8px
|
||||||
|
border-radius: 50%
|
||||||
|
flex-shrink: 0
|
||||||
|
background: unquote('color-mix(in srgb, var(--pane-dot) 38%, var(--color-border))')
|
||||||
|
transition: background 0.25s ease, box-shadow 0.25s ease, transform 0.25s ease
|
||||||
|
|
||||||
|
&[data-state="active"]
|
||||||
|
background: var(--pane-dot)
|
||||||
|
animation: playground-dot-typing 0.85s ease-in-out infinite
|
||||||
|
|
||||||
|
&[data-state="pending"]
|
||||||
|
background: var(--highlight-yellow)
|
||||||
|
|
||||||
|
&[data-state="ok"]
|
||||||
|
background: var(--highlight-green)
|
||||||
|
animation: playground-dot-ok 0.45s ease-out
|
||||||
|
|
||||||
|
&[data-state="error"]
|
||||||
|
background: var(--highlight-red)
|
||||||
|
animation: playground-dot-error 0.35s ease-out
|
||||||
|
|
||||||
|
.area-output .pane-indicator
|
||||||
|
&[data-state="pending"]
|
||||||
|
animation: playground-dot-pending 0.55s ease-in-out infinite
|
||||||
|
|
||||||
|
@keyframes playground-dot-typing
|
||||||
|
0%, 100%
|
||||||
|
transform: scale(1)
|
||||||
|
box-shadow: 0 0 0 0 unquote('color-mix(in srgb, var(--pane-dot) 0%, transparent)')
|
||||||
|
50%
|
||||||
|
transform: scale(1.2)
|
||||||
|
box-shadow: 0 0 0 4px unquote('color-mix(in srgb, var(--pane-dot) 28%, transparent)')
|
||||||
|
|
||||||
|
@keyframes playground-dot-pending
|
||||||
|
0%, 100%
|
||||||
|
transform: scale(1)
|
||||||
|
opacity: 0.75
|
||||||
|
50%
|
||||||
|
transform: scale(1.12)
|
||||||
|
opacity: 1
|
||||||
|
|
||||||
|
@keyframes playground-dot-ok
|
||||||
|
0%
|
||||||
|
transform: scale(0.85)
|
||||||
|
box-shadow: 0 0 0 0 unquote('color-mix(in srgb, var(--highlight-green) 50%, transparent)')
|
||||||
|
70%
|
||||||
|
transform: scale(1.15)
|
||||||
|
box-shadow: 0 0 0 5px unquote('color-mix(in srgb, var(--highlight-green) 0%, transparent)')
|
||||||
|
100%
|
||||||
|
transform: scale(1)
|
||||||
|
box-shadow: none
|
||||||
|
|
||||||
|
@keyframes playground-dot-error
|
||||||
|
0%, 100%
|
||||||
|
transform: translateX(0)
|
||||||
|
20%
|
||||||
|
transform: translateX(-2px)
|
||||||
|
40%
|
||||||
|
transform: translateX(2px)
|
||||||
|
60%
|
||||||
|
transform: translateX(-1px)
|
||||||
|
80%
|
||||||
|
transform: translateX(1px)
|
||||||
|
|
||||||
|
.pane-body
|
||||||
|
flex: 1 1 auto
|
||||||
|
min-height: 0
|
||||||
|
min-width: 0
|
||||||
|
display: flex
|
||||||
|
flex-direction: column
|
||||||
|
overflow: hidden
|
||||||
|
background: var(--highlight-background)
|
||||||
|
|
||||||
|
.area-tpl .pane-body,
|
||||||
|
.area-data .pane-body
|
||||||
|
padding: var(--playground-inset)
|
||||||
|
box-sizing: border-box
|
||||||
|
@media mq-mobile
|
||||||
|
padding: 12px
|
||||||
|
|
||||||
|
.area-tpl .ace_gutter,
|
||||||
|
.area-data .ace_gutter
|
||||||
|
display: none
|
||||||
|
width: 0
|
||||||
|
min-width: 0
|
||||||
|
|
||||||
|
.area-tpl .ace_editor,
|
||||||
|
.area-data .ace_editor,
|
||||||
|
.area-tpl .ace_scroller,
|
||||||
|
.area-data .ace_scroller,
|
||||||
|
.area-tpl .ace_content,
|
||||||
|
.area-data .ace_content,
|
||||||
|
.area-tpl .ace_text-layer,
|
||||||
|
.area-data .ace_text-layer
|
||||||
|
background: transparent
|
||||||
|
|
||||||
|
.editor
|
||||||
|
flex: 1 1 auto
|
||||||
|
min-height: 0
|
||||||
|
position: relative
|
||||||
|
overflow: hidden
|
||||||
|
@media mq-mobile
|
||||||
|
min-height: 180px
|
||||||
|
|
||||||
|
.output-preview
|
||||||
|
flex: 1 1 auto
|
||||||
|
min-height: 0
|
||||||
|
min-width: 0
|
||||||
|
width: 100%
|
||||||
|
overflow: auto
|
||||||
|
@media mq-mobile
|
||||||
|
min-height: 120px
|
||||||
|
pre.highlight
|
||||||
|
margin: 0
|
||||||
|
min-height: 100%
|
||||||
|
width: 100%
|
||||||
|
box-sizing: border-box
|
||||||
|
padding: var(--playground-inset)
|
||||||
|
border: none
|
||||||
|
box-shadow: none
|
||||||
|
border-radius: 0
|
||||||
|
background: transparent
|
||||||
|
color: var(--highlight-foreground)
|
||||||
|
overflow-x: hidden
|
||||||
|
overflow-y: auto
|
||||||
|
white-space: pre-wrap
|
||||||
|
overflow-wrap: break-word
|
||||||
|
@media mq-mobile
|
||||||
|
padding: 12px
|
||||||
|
code
|
||||||
|
display: block
|
||||||
|
width: 100%
|
||||||
|
box-sizing: border-box
|
||||||
|
font-family: font-mono
|
||||||
|
font-size: 14px
|
||||||
|
line-height: 1.55
|
||||||
|
color: var(--highlight-foreground)
|
||||||
|
background: transparent
|
||||||
|
padding: 0
|
||||||
|
white-space: inherit
|
||||||
|
overflow-wrap: inherit
|
||||||
|
@media mq-mobile
|
||||||
|
font-size: 13px
|
||||||
|
|
||||||
|
.ace_editor
|
||||||
font-family: font-mono
|
font-family: font-mono
|
||||||
color: var(--color-gray)
|
font-size: 14px
|
||||||
margin-top: 20px
|
line-height: 1.55
|
||||||
margin-bottom: 32px
|
border-radius: 0
|
||||||
a
|
@media mq-mobile
|
||||||
color: inherit
|
font-size: 13px
|
||||||
text-decoration: none
|
.ace_scrollbar
|
||||||
&:hover
|
z-index: 2
|
||||||
color: var(--color-link)
|
|
||||||
text-decoration: underline
|
|
||||||
|
|
||||||
.hide
|
.hide
|
||||||
display: none
|
display: none
|
||||||
|
|
||||||
.loader
|
.loader
|
||||||
width: 48px
|
width: 40px
|
||||||
height: 48px
|
height: 40px
|
||||||
margin: 150px auto 200px
|
margin: 120px auto 160px
|
||||||
border: 3px solid var(--color-border)
|
border: 2px solid var(--color-border)
|
||||||
border-top-color: var(--color-link)
|
border-top-color: var(--color-link)
|
||||||
border-radius: 50%
|
border-radius: 50%
|
||||||
animation: spin 0.8s infinite linear
|
animation: playground-spin 0.7s infinite linear
|
||||||
|
@media mq-mobile
|
||||||
|
margin: 60px auto 80px
|
||||||
|
|
||||||
@keyframes spin
|
@keyframes playground-spin
|
||||||
100%
|
100%
|
||||||
transform: rotate(360deg)
|
transform: rotate(360deg)
|
||||||
|
|||||||
+4
@@ -37,6 +37,8 @@ vendor-prefixes = webkit moz ms official
|
|||||||
--highlight-aqua: #0550ae
|
--highlight-aqua: #0550ae
|
||||||
--highlight-blue: #0550ae
|
--highlight-blue: #0550ae
|
||||||
--highlight-purple: #8250df
|
--highlight-purple: #8250df
|
||||||
|
--playground-surface: #f3f4f6
|
||||||
|
--playground-pane-head: #fff
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
@@ -75,6 +77,8 @@ vendor-prefixes = webkit moz ms official
|
|||||||
--highlight-aqua: #79c0ff
|
--highlight-aqua: #79c0ff
|
||||||
--highlight-blue: #79c0ff
|
--highlight-blue: #79c0ff
|
||||||
--highlight-purple: #d2a8ff
|
--highlight-purple: #d2a8ff
|
||||||
|
--playground-surface: hsl(218, 26%, 10%)
|
||||||
|
--playground-pane-head: hsl(218, 22%, 16%)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+119
-16
@@ -38,8 +38,8 @@
|
|||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
// playground
|
// playground
|
||||||
/* global liquidjs, ace */
|
/* global liquidjs, ace, Prism */
|
||||||
if (!location.pathname.match(/playground.html$/)) return;
|
if (!/\/playground(?:\.html)?$/.test(location.pathname)) return;
|
||||||
updateVersion(liquidjs.version);
|
updateVersion(liquidjs.version);
|
||||||
const engine = new liquidjs.Liquid({
|
const engine = new liquidjs.Liquid({
|
||||||
memoryLimit: 1e5,
|
memoryLimit: 1e5,
|
||||||
@@ -48,14 +48,19 @@
|
|||||||
const colorScheme = window.matchMedia('(prefers-color-scheme: dark)');
|
const colorScheme = window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
const editor = createEditor('editorEl', 'liquid');
|
const editor = createEditor('editorEl', 'liquid');
|
||||||
const dataEditor = createEditor('dataEl', 'json');
|
const dataEditor = createEditor('dataEl', 'json');
|
||||||
const preview = createEditor('previewEl', 'html');
|
const previewCode = document.getElementById('previewCode');
|
||||||
preview.setReadOnly(true);
|
const indicatorTpl = document.querySelector('.area-tpl .pane-indicator');
|
||||||
preview.renderer.setShowGutter(false);
|
const indicatorData = document.querySelector('.area-data .pane-indicator');
|
||||||
preview.renderer.setPadding(16);
|
const indicatorOutput = document.querySelector('.area-output .pane-indicator');
|
||||||
|
|
||||||
const editors = [editor, dataEditor, preview];
|
const editors = [editor, dataEditor];
|
||||||
|
let previewValue = '';
|
||||||
|
let hadPreview = false;
|
||||||
|
let renderTimer = null;
|
||||||
|
const RENDER_DELAY = 180;
|
||||||
colorScheme.addEventListener('change', function() {
|
colorScheme.addEventListener('change', function() {
|
||||||
editors.forEach(applyEditorTheme);
|
editors.forEach(applyEditorTheme);
|
||||||
|
if (previewValue) setPreview(previewValue);
|
||||||
});
|
});
|
||||||
|
|
||||||
const init = parseArgs(location.hash.slice(1));
|
const init = parseArgs(location.hash.slice(1));
|
||||||
@@ -63,9 +68,11 @@
|
|||||||
editor.setValue(init.tpl, 1);
|
editor.setValue(init.tpl, 1);
|
||||||
dataEditor.setValue(init.data, 1);
|
dataEditor.setValue(init.data, 1);
|
||||||
}
|
}
|
||||||
editor.on('change', update);
|
editor.on('change', onTemplateChange);
|
||||||
dataEditor.on('change', update);
|
dataEditor.on('change', onContextChange);
|
||||||
update();
|
editor.on('focus', function () { setIndicator(indicatorTpl, 'active'); });
|
||||||
|
dataEditor.on('focus', function () { setIndicator(indicatorData, 'active'); });
|
||||||
|
scheduleUpdate();
|
||||||
ready();
|
ready();
|
||||||
|
|
||||||
function ready() {
|
function ready() {
|
||||||
@@ -87,6 +94,8 @@
|
|||||||
|
|
||||||
function applyEditorTheme(editor) {
|
function applyEditorTheme(editor) {
|
||||||
editor.setTheme(getEditorTheme());
|
editor.setTheme(getEditorTheme());
|
||||||
|
editor.renderer.setPadding(0);
|
||||||
|
editor.container.style.background = 'transparent';
|
||||||
}
|
}
|
||||||
|
|
||||||
function createEditor(id, lang) {
|
function createEditor(id, lang) {
|
||||||
@@ -96,15 +105,61 @@
|
|||||||
fontFamily: '"Source Code Pro", ui-monospace, Monaco, Menlo, Consolas, monospace',
|
fontFamily: '"Source Code Pro", ui-monospace, Monaco, Menlo, Consolas, monospace',
|
||||||
fontSize: '14px',
|
fontSize: '14px',
|
||||||
showPrintMargin: false,
|
showPrintMargin: false,
|
||||||
|
showGutter: false,
|
||||||
|
highlightActiveLine: false,
|
||||||
tabSize: 2,
|
tabSize: 2,
|
||||||
useSoftTabs: true,
|
useSoftTabs: true,
|
||||||
scrollPastEnd: 0.25
|
scrollPastEnd: 0
|
||||||
});
|
});
|
||||||
editor.getSession().setMode('ace/mode/' + lang);
|
editor.getSession().setMode('ace/mode/' + lang);
|
||||||
editor.renderer.setScrollMargin(8, 8, 0, 0);
|
editor.renderer.setShowGutter(false);
|
||||||
|
if (editor.renderer.$gutter) {
|
||||||
|
editor.renderer.$gutter.style.display = 'none';
|
||||||
|
}
|
||||||
|
editor.renderer.setScrollMargin(0, 0, 0, 0);
|
||||||
|
bindClipboard(editor);
|
||||||
return editor;
|
return editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bindClipboard(editor) {
|
||||||
|
editor.commands.addCommand({
|
||||||
|
name: 'copy',
|
||||||
|
bindKey: {win: 'Ctrl-C', mac: 'Command-C'},
|
||||||
|
exec: function (ed) {
|
||||||
|
const text = ed.getCopyText();
|
||||||
|
if (!text) return;
|
||||||
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
|
navigator.clipboard.writeText(text);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
readOnly: true
|
||||||
|
});
|
||||||
|
editor.commands.addCommand({
|
||||||
|
name: 'cut',
|
||||||
|
bindKey: {win: 'Ctrl-X', mac: 'Command-X'},
|
||||||
|
exec: function (ed) {
|
||||||
|
const text = ed.getCopyText();
|
||||||
|
if (!text) return;
|
||||||
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
|
navigator.clipboard.writeText(text).then(function () {
|
||||||
|
ed.insert('');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
editor.commands.addCommand({
|
||||||
|
name: 'paste',
|
||||||
|
bindKey: {win: 'Ctrl-V', mac: 'Command-V'},
|
||||||
|
exec: function (ed) {
|
||||||
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
|
navigator.clipboard.readText().then(function (text) {
|
||||||
|
ed.insert(text);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function parseArgs(hash) {
|
function parseArgs(hash) {
|
||||||
if (!hash) return;
|
if (!hash) return;
|
||||||
try {
|
try {
|
||||||
@@ -118,16 +173,64 @@
|
|||||||
return utoa(obj.tpl) + ',' + utoa(obj.data);
|
return utoa(obj.tpl) + ',' + utoa(obj.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setPreview(value) {
|
||||||
|
previewValue = value;
|
||||||
|
previewCode.textContent = value;
|
||||||
|
if (window.Prism) {
|
||||||
|
delete previewCode.dataset.highlighted;
|
||||||
|
window.Prism.highlightElement(previewCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setIndicator(indicator, state) {
|
||||||
|
if (indicator) indicator.dataset.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTemplateChange() {
|
||||||
|
setIndicator(indicatorTpl, 'active');
|
||||||
|
if (indicatorData.dataset.state !== 'error') setIndicator(indicatorData, 'idle');
|
||||||
|
setIndicator(indicatorOutput, 'pending');
|
||||||
|
scheduleUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onContextChange() {
|
||||||
|
setIndicator(indicatorData, 'active');
|
||||||
|
if (indicatorTpl.dataset.state !== 'error') setIndicator(indicatorTpl, 'idle');
|
||||||
|
setIndicator(indicatorOutput, 'pending');
|
||||||
|
scheduleUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
function scheduleUpdate() {
|
||||||
|
clearTimeout(renderTimer);
|
||||||
|
renderTimer = setTimeout(update, RENDER_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
async function update() {
|
async function update() {
|
||||||
const tpl = editor.getValue();
|
const tpl = editor.getValue();
|
||||||
const data = dataEditor.getValue();
|
const data = dataEditor.getValue();
|
||||||
history.replaceState({}, '', '#' + serializeArgs({tpl, data}));
|
history.replaceState({}, '', '#' + serializeArgs({tpl, data}));
|
||||||
|
let parsed;
|
||||||
try {
|
try {
|
||||||
const html = await engine.parseAndRender(tpl, JSON.parse(data));
|
parsed = JSON.parse(data);
|
||||||
preview.setValue(html, 1);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
preview.setValue(err.stack, 1);
|
setIndicator(indicatorData, 'error');
|
||||||
throw err;
|
setIndicator(indicatorTpl, 'idle');
|
||||||
|
setIndicator(indicatorOutput, 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const html = await engine.parseAndRender(tpl, parsed);
|
||||||
|
if (html !== '' || !hadPreview) {
|
||||||
|
setPreview(html);
|
||||||
|
if (html !== '') hadPreview = true;
|
||||||
|
}
|
||||||
|
setIndicator(indicatorTpl, 'idle');
|
||||||
|
setIndicator(indicatorData, 'idle');
|
||||||
|
setIndicator(indicatorOutput, 'ok');
|
||||||
|
} catch (err) {
|
||||||
|
setIndicator(indicatorTpl, 'error');
|
||||||
|
setIndicator(indicatorData, 'idle');
|
||||||
|
setIndicator(indicatorOutput, 'error');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -2,7 +2,7 @@
|
|||||||
"name": "liquidjs",
|
"name": "liquidjs",
|
||||||
"version": "10.27.0",
|
"version": "10.27.0",
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"description": "A simple, expressive and safe Shopify / Github Pages compatible template engine in pure JavaScript.",
|
"description": "A simple, expressive, extensible Liquid template engine for JavaScript — Shopify, Jekyll and GitHub Pages compatible, for Node.js, browsers, and the CLI, with TypeScript support.",
|
||||||
"main": "dist/liquid.node.js",
|
"main": "dist/liquid.node.js",
|
||||||
"module": "dist/liquid.node.mjs",
|
"module": "dist/liquid.node.mjs",
|
||||||
"es2015": "dist/liquid.browser.mjs",
|
"es2015": "dist/liquid.browser.mjs",
|
||||||
@@ -29,12 +29,15 @@
|
|||||||
"build:min": "BUNDLES=min rollup -c rollup.config.mjs",
|
"build:min": "BUNDLES=min rollup -c rollup.config.mjs",
|
||||||
"build:umd": "BUNDLES=umd rollup -c rollup.config.mjs",
|
"build:umd": "BUNDLES=umd rollup -c rollup.config.mjs",
|
||||||
"build:charmap": "./bin/character-gen.js > src/util/character.ts",
|
"build:charmap": "./bin/character-gen.js > src/util/character.ts",
|
||||||
"build:docs": "run-s build:docs-liquid build:contributors build:apidoc build:changelog build:docs-hexo",
|
"prepare:docs": "run-s build:docs-liquid build:contributors build:apidoc build:changelog",
|
||||||
|
"build:docs": "run-s prepare:docs build:docs-hexo",
|
||||||
"build:docs-liquid": "cross-env BUNDLES=min rollup -c rollup.config.mjs && shx cp dist/liquid.browser.min.js docs/themes/navy/source/js/",
|
"build:docs-liquid": "cross-env BUNDLES=min rollup -c rollup.config.mjs && shx cp dist/liquid.browser.min.js docs/themes/navy/source/js/",
|
||||||
"build:contributors": "node bin/build-contributors.js",
|
"build:contributors": "node bin/build-contributors.js",
|
||||||
"build:apidoc": "shx rm -rf docs/source/api && typedoc --plugin typedoc-plugin-missing-exports ./src --gitRevision master --out docs/source/api",
|
"build:apidoc": "shx rm -rf docs/source/api && typedoc --plugin typedoc-plugin-missing-exports ./src --gitRevision master --out docs/source/api",
|
||||||
"build:changelog": "node bin/build-changelog.js",
|
"build:changelog": "node bin/build-changelog.js",
|
||||||
"build:docs-hexo": "cd docs && npm ci && npm run build && shx cp CNAME public/"
|
"build:docs-hexo": "cd docs && npm ci && npm run build && shx cp CNAME public/",
|
||||||
|
"serve:docs": "cd docs && npm run start",
|
||||||
|
"dev:docs": "run-s prepare:docs serve:docs"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"liquidjs": "./bin/liquid.js",
|
"liquidjs": "./bin/liquid.js",
|
||||||
|
|||||||
Reference in New Issue
Block a user