@rettangoli/sites 1.0.0-rc2 → 1.0.0-rc4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/package.json +1 -1
- package/src/builtinTemplateFunctions.js +78 -0
- package/templates/default/README.md +4 -0
package/README.md
CHANGED
|
@@ -115,10 +115,14 @@ Available in YAML templates/pages without extra setup:
|
|
|
115
115
|
- `jsonStringify(value, space = 0)`
|
|
116
116
|
- `formatDate(value, format = "YYYYMMDDHHmmss", useUtc = true)`
|
|
117
117
|
- `now(format = "YYYYMMDDHHmmss", useUtc = true)`
|
|
118
|
+
- `sort(list, key, order = "asc")`
|
|
119
|
+
- `md(content)`
|
|
118
120
|
- `toQueryString(object)`
|
|
119
121
|
|
|
120
122
|
`formatDate` tokens: `YYYY`, `MM`, `DD`, `HH`, `mm`, `ss`.
|
|
121
123
|
`decodeURI`/`decodeURIComponent` return the original input when decoding fails.
|
|
124
|
+
`sort` supports `order` as `asc` or `desc` (default: `asc`), accepts dot-path keys (for example `data.date`), and returns a new array.
|
|
125
|
+
`md` returns raw rendered HTML from Markdown for template insertion.
|
|
122
126
|
|
|
123
127
|
## Screenshots
|
|
124
128
|
|
package/package.json
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import MarkdownIt from 'markdown-it';
|
|
2
|
+
|
|
3
|
+
const markdownRenderer = new MarkdownIt();
|
|
4
|
+
|
|
1
5
|
function toDate(value) {
|
|
2
6
|
if (value instanceof Date) {
|
|
3
7
|
return value;
|
|
@@ -71,6 +75,78 @@ function safeDecode(value, decoder) {
|
|
|
71
75
|
}
|
|
72
76
|
}
|
|
73
77
|
|
|
78
|
+
function readSortValue(item, key, keyParts) {
|
|
79
|
+
if (key == null) {
|
|
80
|
+
return item;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (item == null) {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!keyParts) {
|
|
88
|
+
return item?.[key];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (Object.prototype.hasOwnProperty.call(item, key)) {
|
|
92
|
+
return item[key];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
let current = item;
|
|
96
|
+
for (const part of keyParts) {
|
|
97
|
+
if (!part) {
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
current = current?.[part];
|
|
101
|
+
}
|
|
102
|
+
return current;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function sortImpl(value, key, order = 'asc') {
|
|
106
|
+
if (!Array.isArray(value)) {
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const normalizedOrder = String(order ?? 'asc').toLowerCase() === 'desc' ? 'desc' : 'asc';
|
|
111
|
+
const factor = normalizedOrder === 'asc' ? 1 : -1;
|
|
112
|
+
const keyParts = typeof key === 'string' && key.includes('.') ? key.split('.') : null;
|
|
113
|
+
|
|
114
|
+
return [...value].sort((left, right) => {
|
|
115
|
+
const leftRaw = readSortValue(left, key, keyParts);
|
|
116
|
+
const rightRaw = readSortValue(right, key, keyParts);
|
|
117
|
+
|
|
118
|
+
if (leftRaw == null && rightRaw == null) return 0;
|
|
119
|
+
if (leftRaw == null) return 1;
|
|
120
|
+
if (rightRaw == null) return -1;
|
|
121
|
+
|
|
122
|
+
const leftDate = Date.parse(String(leftRaw));
|
|
123
|
+
const rightDate = Date.parse(String(rightRaw));
|
|
124
|
+
const canCompareAsDate = !Number.isNaN(leftDate) && !Number.isNaN(rightDate);
|
|
125
|
+
|
|
126
|
+
if (canCompareAsDate) {
|
|
127
|
+
if (leftDate === rightDate) return 0;
|
|
128
|
+
return leftDate > rightDate ? factor : -factor;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (typeof leftRaw === 'number' && typeof rightRaw === 'number') {
|
|
132
|
+
if (leftRaw === rightRaw) return 0;
|
|
133
|
+
return leftRaw > rightRaw ? factor : -factor;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const leftText = String(leftRaw);
|
|
137
|
+
const rightText = String(rightRaw);
|
|
138
|
+
const result = leftText.localeCompare(rightText);
|
|
139
|
+
if (result === 0) return 0;
|
|
140
|
+
return result > 0 ? factor : -factor;
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function mdImpl(content) {
|
|
145
|
+
return {
|
|
146
|
+
__html: markdownRenderer.render(String(content ?? '')),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
74
150
|
export const builtinTemplateFunctions = {
|
|
75
151
|
encodeURI: (value) => encodeURI(String(value ?? '')),
|
|
76
152
|
encodeURIComponent: (value) => encodeURIComponent(String(value ?? '')),
|
|
@@ -79,6 +155,8 @@ export const builtinTemplateFunctions = {
|
|
|
79
155
|
jsonStringify,
|
|
80
156
|
formatDate: formatDateImpl,
|
|
81
157
|
now: (format = 'YYYYMMDDHHmmss', useUtc = true) => formatDateImpl(new Date(), format, useUtc),
|
|
158
|
+
sort: sortImpl,
|
|
159
|
+
md: mdImpl,
|
|
82
160
|
toQueryString,
|
|
83
161
|
};
|
|
84
162
|
|
|
@@ -227,10 +227,14 @@ Use these directly in `${...}` expressions:
|
|
|
227
227
|
- `jsonStringify(value, space = 0)`
|
|
228
228
|
- `formatDate(value, format = "YYYYMMDDHHmmss", useUtc = true)`
|
|
229
229
|
- `now(format = "YYYYMMDDHHmmss", useUtc = true)`
|
|
230
|
+
- `sort(list, key, order = "asc")`
|
|
231
|
+
- `md(content)`
|
|
230
232
|
- `toQueryString(object)`
|
|
231
233
|
|
|
232
234
|
Date format tokens: `YYYY`, `MM`, `DD`, `HH`, `mm`, `ss`.
|
|
233
235
|
`decodeURI`/`decodeURIComponent` return the original input when decoding fails.
|
|
236
|
+
`sort` supports `order` as `asc` or `desc` (default: `asc`), accepts dot-path keys (for example `data.date`), and returns a new array.
|
|
237
|
+
`md` returns raw rendered HTML from Markdown for template insertion.
|
|
234
238
|
|
|
235
239
|
## Static Files
|
|
236
240
|
|