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:
Yang Jun
2026-06-23 17:39:19 +08:00
committed by GitHub
co-authored by Cursor
parent 3a0d80d1f4
commit afec88b04c
21 changed files with 526 additions and 161 deletions
+119 -16
View File
@@ -38,8 +38,8 @@
(function() {
// playground
/* global liquidjs, ace */
if (!location.pathname.match(/playground.html$/)) return;
/* global liquidjs, ace, Prism */
if (!/\/playground(?:\.html)?$/.test(location.pathname)) return;
updateVersion(liquidjs.version);
const engine = new liquidjs.Liquid({
memoryLimit: 1e5,
@@ -48,14 +48,19 @@
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 indicatorTpl = document.querySelector('.area-tpl .pane-indicator');
const indicatorData = document.querySelector('.area-data .pane-indicator');
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() {
editors.forEach(applyEditorTheme);
if (previewValue) setPreview(previewValue);
});
const init = parseArgs(location.hash.slice(1));
@@ -63,9 +68,11 @@
editor.setValue(init.tpl, 1);
dataEditor.setValue(init.data, 1);
}
editor.on('change', update);
dataEditor.on('change', update);
update();
editor.on('change', onTemplateChange);
dataEditor.on('change', onContextChange);
editor.on('focus', function () { setIndicator(indicatorTpl, 'active'); });
dataEditor.on('focus', function () { setIndicator(indicatorData, 'active'); });
scheduleUpdate();
ready();
function ready() {
@@ -87,6 +94,8 @@
function applyEditorTheme(editor) {
editor.setTheme(getEditorTheme());
editor.renderer.setPadding(0);
editor.container.style.background = 'transparent';
}
function createEditor(id, lang) {
@@ -96,15 +105,61 @@
fontFamily: '"Source Code Pro", ui-monospace, Monaco, Menlo, Consolas, monospace',
fontSize: '14px',
showPrintMargin: false,
showGutter: false,
highlightActiveLine: false,
tabSize: 2,
useSoftTabs: true,
scrollPastEnd: 0.25
scrollPastEnd: 0
});
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;
}
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) {
if (!hash) return;
try {
@@ -118,16 +173,64 @@
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() {
const tpl = editor.getValue();
const data = dataEditor.getValue();
history.replaceState({}, '', '#' + serializeArgs({tpl, data}));
let parsed;
try {
const html = await engine.parseAndRender(tpl, JSON.parse(data));
preview.setValue(html, 1);
parsed = JSON.parse(data);
} catch (err) {
preview.setValue(err.stack, 1);
throw err;
setIndicator(indicatorData, 'error');
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');
}
}