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]>
This commit is contained in:
Yang Jun
2026-06-22 19:54:46 +08:00
co-authored by Cursor
parent 18258eedc3
commit ff52a00ac4
19 changed files with 719 additions and 140 deletions
+1
View File
@@ -6,6 +6,7 @@
"version": "7.3.0"
},
"scripts": {
"prebuild": "npm --prefix .. run build:contributors && npm --prefix .. run build:used-by",
"build": "hexo generate",
"start": "hexo serve",
"lint": "eslint .",
Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

+4 -1
View File
@@ -13,7 +13,10 @@ index:
description: 'Thanks to these wonderful people! See <a href="tutorials/contribution-guidelines.html">contribution guidelines</a> if you&#39;d like to help.'
sponsors:
title: Sponsors
description: 'If you personally love LiquidJS or it&#39;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/data/used-by.json">Open a PR</a> to add yours.'
playground:
title: Playground
+37 -42
View File
@@ -1,42 +1,37 @@
<header id="banner" class="wrapper">
<div class="inner inner-content">
<h2 id="banner-title">{{ page.subtitle }}</h2>
<div id="banner-share">{{ partial('partial/share') }}</div>
<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>
</div>
</div>
</header>
<div id="content-wrap">
<div class="wrapper">
<div class="inner inner-content">
{{ page.content }}
</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>
<div id="sponsors-wrap">
<div class="wrapper">
<div class="inner inner-content">
<div class="section-header">
<h3>{{__('index.sponsors.title')}}</h3>
<p class="description">{{__('index.sponsors.description')}}</p>
</div>
<div class="contributors">
{{ partial('partial/financial-contributors') }}
</div>
</div>
</div>
</div>
<header id="banner" class="wrapper">
<div class="inner inner-content">
<h2 id="banner-title">{{ page.subtitle }}</h2>
<div id="banner-share">{{ partial('partial/share') }}</div>
<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>
</div>
</div>
</header>
<div id="content-wrap">
<div class="wrapper">
<div class="inner inner-content">
{{ page.content }}
</div>
</div>
</div>
{{ partial('partial/home-section', {
wrapId: 'used-by',
variant: 'logos',
+2
View File
@@ -1,6 +1,8 @@
{% if page.layout === 'playground' %}
{{ 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]/prism.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/components/prism-markup.min.js"></script>
{% endif %}
{{ js('js/main') }}
+1 -5
View File
@@ -1,7 +1,3 @@
{
"people": [
"alice",
"bob",
"carol"
]
"name": "liquid"
}
+1 -9
View File
@@ -1,9 +1 @@
<ul>
{%- for person in people %}
<li>
<a href="{{person | prepend: "https://example.com/"}}">
{{ person | capitalize }}
</a>
</li>
{%- endfor%}
</ul>
<p>Hello, {{ name | capitalize }}!</p>
+19
View File
@@ -0,0 +1,19 @@
<div id="{{ wrapId }}-wrap" class="home-section home-section--{{ variant }}">
<div class="wrapper">
<div class="inner inner-content">
<div class="section-header">
<h3>{{ title }}</h3>
<p class="description">{{ description | safe }}</p>
</div>
<div class="contributors">
{% if contentPartial == 'used-by' %}
{{ partial('partial/used-by') }}
{% elif contentPartial == 'financial-contributors' %}
{{ partial('partial/financial-contributors') }}
{% else %}
{{ partial('partial/all-contributors') }}
{% endif %}
</div>
</div>
</div>
</div>
+14 -6
View File
@@ -4,16 +4,24 @@
<div class="loader" role=status aria-busy=true></div>
<div id="editors" class="inner hide" aria-hide=true>
<div class="area-tpl editor-wrapper">
<h2>Template</h2>
<div class="editor" id="editorEl">{{ raw('partial/demo.liquid') }}</div>
<div class="pane-window">
<span class="pane-tab">Template</span>
<div class="editor" id="editorEl">{{ raw('partial/demo.liquid') }}</div>
</div>
</div>
<div class="area-data editor-wrapper">
<h2>Context</h2>
<div class="editor" id="dataEl">{{ raw('partial/demo.json') }}</div>
<div class="pane-window">
<span class="pane-tab">Context</span>
<div class="editor" id="dataEl">{{ raw('partial/demo.json') }}</div>
</div>
</div>
<div class="area-output editor-wrapper">
<h2>Output</h2>
<div class="editor" id="previewEl">{{__('playground.loading')}}</div>
<div class="pane-window">
<span class="pane-tab">Output</span>
<div class="output-preview" id="previewEl">
<pre class="highlight"><code class="language-markup" id="previewCode">{{__('playground.loading')}}</code></pre>
</div>
</div>
</div>
</div>
<p class="inner version"></p>
+23 -6
View File
@@ -126,7 +126,8 @@
background: var(--color-link-hover)
color: #fff
#sponsors-wrap, #contributors-wrap
#used-by-wrap, #sponsors-wrap, #contributors-wrap,
.home-section
background: var(--color-navy-lighter)
border-top: 1px solid #161d24
border-bottom: 1px solid #161d24
@@ -166,24 +167,40 @@
&:hover
color: var(--color-link-hover)
#sponsors-wrap
.home-section--logos, #sponsors-wrap, #used-by-wrap
background: var(--color-content-bg)
.inner
h3
color: var(--color-default)
p
color: var(--color-gray)
.open-collective
max-width: 100%
@media (prefers-color-scheme: dark)
p
color: var(--color-default)
#contributors-wrap
.home-section--people, #contributors-wrap
border: none
overflow: hidden;
overflow: hidden
.contributors
p
margin: 0
line-height: 2.5
text-align: center
a
display: inline-block
vertical-align: middle
margin: 8px
a img
display: inline-block
height: 72px
width: auto
max-width: 160px
vertical-align: middle
object-fit: contain
background: transparent
border-radius: 0
margin-bottom: 0
tr
display: flex
flex-wrap: wrap
+70 -23
View File
@@ -13,14 +13,6 @@
margin-bottom: 24px
color: var(--color-default)
h2
font-size: 0.8125rem
font-weight: 600
text-transform: uppercase
letter-spacing: 0.04em
color: var(--color-gray)
margin: 0
#editors
display: grid
overflow: hidden
@@ -56,25 +48,80 @@
.editor-wrapper
display: flex
gap: 8px
flex-direction: column
min-height: 0
overflow: hidden
.editor
flex: 1 1 auto
min-height: 0
position: relative
code-block-chrome()
overflow: hidden
@media mq-mobile
min-height: 240px
.pane-window
flex: 1 1 auto
min-height: 0
position: relative
display: flex
flex-direction: column
playground-window-chrome()
overflow: hidden
@media mq-mobile
min-height: 240px
.pane-tab
position: absolute
z-index: 5
top: 0
left: 0
right: 0
height: 36px
line-height: 36px
text-align: center
font-size: 0.75rem
font-weight: 600
letter-spacing: 0.02em
color: var(--color-gray)
pointer-events: none
user-select: none
.editor
flex: 1 1 auto
min-height: 0
position: relative
overflow: hidden
.ace_editor
font-family: font-mono
font-size: 14px
line-height: 1.5
border-radius: 6px
.ace_scrollbar
z-index: 2
top: 0
bottom: 0
height: auto !important
.output-preview
flex: 1 1 auto
min-height: 0
cursor: default
overflow: auto
pre.highlight
margin: 0
min-height: 100%
padding: 16px
border: none
box-shadow: none
border-radius: 0 0 6px 6px
background: var(--highlight-background)
code
display: block
font-size: 14px
line-height: 1.5
background: transparent
padding: 0
white-space: pre
.ace_editor
font-family: font-mono
font-size: 14px
line-height: 1.5
border-radius: 6px
.ace_gutter
display: none !important
width: 0 !important
.ace_scroller
left: 0 !important
.ace_scrollbar
z-index: 2
.version
font-size: 0.8125rem
+17
View File
@@ -102,3 +102,20 @@ code-block-chrome()
border-radius: 6px
border: 1px solid var(--code-border)
box-shadow: var(--code-shadow)
playground-window-chrome()
code-block-chrome()
padding-top: 36px
&:before
content: ''
position: absolute
z-index: 4
top: 0
left: 0
right: 0
height: 36px
background: var(--highlight-background)
border-bottom: 1px solid var(--code-border)
border-radius: 6px 6px 0 0
pointer-events: none
background-image: radial-gradient(circle at 12px 18px, #ff5f57 5px, transparent 5px), radial-gradient(circle at 28px 18px, #febc2e 5px, transparent 5px), radial-gradient(circle at 44px 18px, #28c840 5px, transparent 5px)
+22 -10
View File
@@ -48,20 +48,17 @@
const colorScheme = window.matchMedia('(prefers-color-scheme: dark)');
const editor = createEditor('editorEl', 'liquid');
const dataEditor = createEditor('dataEl', 'json');
const preview = createEditor('previewEl', 'html');
preview.setReadOnly(true);
preview.renderer.setShowGutter(false);
preview.renderer.setPadding(16);
const previewCode = document.getElementById('previewCode');
const editors = [editor, dataEditor, preview];
const editors = [editor, dataEditor];
colorScheme.addEventListener('change', function() {
editors.forEach(applyEditorTheme);
});
const init = parseArgs(location.hash.slice(1));
if (init) {
editor.setValue(init.tpl, 1);
dataEditor.setValue(init.data, 1);
editor.setValue(init.tpl, -1);
dataEditor.setValue(init.data, -1);
}
editor.on('change', update);
dataEditor.on('change', update);
@@ -76,7 +73,10 @@
const editorsEl = document.querySelector('#editors');
editorsEl.classList.remove('hide');
editorsEl.setAttribute('aria-hide', false);
editors.forEach(function(ed) { ed.resize(); });
editors.forEach(function(ed) {
ed.clearSelection();
ed.resize();
});
}
function getEditorTheme() {
@@ -96,11 +96,15 @@
fontFamily: '"Source Code Pro", ui-monospace, Monaco, Menlo, Consolas, monospace',
fontSize: '14px',
showPrintMargin: false,
showGutter: false,
highlightActiveLine: false,
highlightSelectedWord: false,
tabSize: 2,
useSoftTabs: true,
scrollPastEnd: 0.25
});
editor.getSession().setMode('ace/mode/' + lang);
editor.renderer.setShowGutter(false);
editor.renderer.setScrollMargin(8, 8, 0, 0);
return editor;
}
@@ -118,15 +122,23 @@
return utoa(obj.tpl) + ',' + utoa(obj.data);
}
function setPreview(value) {
previewCode.textContent = value;
if (window.Prism) {
delete previewCode.dataset.highlighted;
window.Prism.highlightElement(previewCode);
}
}
async function update() {
const tpl = editor.getValue();
const data = dataEditor.getValue();
history.replaceState({}, '', '#' + serializeArgs({tpl, data}));
try {
const html = await engine.parseAndRender(tpl, JSON.parse(data));
preview.setValue(html, 1);
setPreview(html);
} catch (err) {
preview.setValue(err.stack, 1);
setPreview(err.stack);
throw err;
}
}