retold 4.0.4 → 4.0.8
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/.claude/launch.json +47 -0
- package/.claude/settings.local.json +45 -107
- package/CLAUDE.md +9 -7
- package/README.md +9 -7
- package/Retold-Modules-Manifest.json +616 -0
- package/docs/README.md +7 -1
- package/docs/{cover.md → _cover.md} +1 -1
- package/docs/_sidebar.md +30 -3
- package/docs/architecture/architecture.md +5 -2
- package/docs/architecture/dependencies/_generate-graph.js +186 -0
- package/docs/architecture/dependencies/_generate-svg.js +364 -0
- package/docs/architecture/dependencies/in-ecosystem-dependency-graph-generation.md +97 -0
- package/docs/architecture/dependencies/in-ecosystem-dependency-graph.json +3168 -0
- package/docs/architecture/dependencies/in-ecosystem-dependency-graph.md +221 -0
- package/docs/architecture/dependencies/in-ecosystem-dependency-graph.svg +664 -0
- package/docs/architecture/documentation-style-guide.md +65 -0
- package/docs/architecture/example-app-style-guide.md +154 -0
- package/docs/architecture/modules.md +33 -12
- package/docs/architecture/templating/data-access.md +196 -0
- package/docs/architecture/templating/data-formatting.md +350 -0
- package/docs/architecture/templating/data-generation.md +72 -0
- package/docs/architecture/templating/debugging.md +181 -0
- package/docs/architecture/templating/entity.md +99 -0
- package/docs/architecture/templating/iteration.md +170 -0
- package/docs/architecture/templating/jellyfish-deep-dive.md +271 -0
- package/docs/architecture/templating/jellyfish-templates.md +476 -0
- package/docs/architecture/templating/logic.md +185 -0
- package/docs/architecture/templating/ref-breakpoint.md +38 -0
- package/docs/architecture/templating/ref-data.md +51 -0
- package/docs/architecture/templating/ref-dateonlyformat.md +43 -0
- package/docs/architecture/templating/ref-dateonlyymd.md +39 -0
- package/docs/architecture/templating/ref-datetimeformat.md +59 -0
- package/docs/architecture/templating/ref-datetimeymd.md +44 -0
- package/docs/architecture/templating/ref-dejs.md +42 -0
- package/docs/architecture/templating/ref-digits.md +36 -0
- package/docs/architecture/templating/ref-dj.md +50 -0
- package/docs/architecture/templating/ref-dollars.md +36 -0
- package/docs/architecture/templating/ref-dt.md +38 -0
- package/docs/architecture/templating/ref-dvbk.md +46 -0
- package/docs/architecture/templating/ref-dwaf.md +45 -0
- package/docs/architecture/templating/ref-dwtf.md +45 -0
- package/docs/architecture/templating/ref-entity.md +47 -0
- package/docs/architecture/templating/ref-hce.md +29 -0
- package/docs/architecture/templating/ref-hcs.md +38 -0
- package/docs/architecture/templating/ref-join.md +45 -0
- package/docs/architecture/templating/ref-joinunique.md +34 -0
- package/docs/architecture/templating/ref-ls.md +37 -0
- package/docs/architecture/templating/ref-lv.md +38 -0
- package/docs/architecture/templating/ref-lvt.md +33 -0
- package/docs/architecture/templating/ref-ne.md +40 -0
- package/docs/architecture/templating/ref-pascalcaseidentifier.md +41 -0
- package/docs/architecture/templating/ref-pict.md +42 -0
- package/docs/architecture/templating/ref-pluckjoinunique.md +39 -0
- package/docs/architecture/templating/ref-rn.md +35 -0
- package/docs/architecture/templating/ref-rns.md +35 -0
- package/docs/architecture/templating/ref-sbr.md +36 -0
- package/docs/architecture/templating/ref-solve.md +46 -0
- package/docs/architecture/templating/ref-tbda.md +41 -0
- package/docs/architecture/templating/ref-tbr.md +43 -0
- package/docs/architecture/templating/ref-tbt.md +46 -0
- package/docs/architecture/templating/ref-template.md +40 -0
- package/docs/architecture/templating/ref-tfa.md +32 -0
- package/docs/architecture/templating/ref-tfm.md +43 -0
- package/docs/architecture/templating/ref-tif.md +45 -0
- package/docs/architecture/templating/ref-tifabs.md +41 -0
- package/docs/architecture/templating/ref-ts.md +41 -0
- package/docs/architecture/templating/ref-tsfm.md +42 -0
- package/docs/architecture/templating/ref-tswp.md +45 -0
- package/docs/architecture/templating/ref-tvs.md +48 -0
- package/docs/architecture/templating/ref-view.md +40 -0
- package/docs/architecture/templating/ref-vrs.md +39 -0
- package/docs/architecture/templating/solvers.md +153 -0
- package/docs/architecture/templating/template-composition.md +196 -0
- package/docs/architecture/templating/template-expressions.md +217 -0
- package/docs/architecture/templating/views.md +154 -0
- package/docs/examples/todolist/todo-list.md +1 -1
- package/docs/modules/apps.md +26 -0
- package/docs/modules/pict.md +18 -0
- package/docs/modules/utility.md +23 -1
- package/docs/retold-catalog.json +2541 -307
- package/docs/retold-keyword-index.json +267578 -117399
- package/modules/CLAUDE.md +1 -0
- package/modules/Checkout.sh +1 -0
- package/modules/Diff.sh +86 -0
- package/modules/Include-Retold-Module-List.sh +4 -2
- package/modules/Status.sh +1 -0
- package/modules/Update.sh +1 -0
- package/modules/apps/Apps.md +1 -0
- package/modules/utility/Utility.md +1 -0
- package/package.json +9 -11
- package/docs/retold-building-documentation.md +0 -33
- package/modules/.claude/settings.local.json +0 -52
- package/modules/Retold-Modules.md +0 -24
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# Template Composition Expressions
|
|
2
|
+
|
|
3
|
+
Composition expressions render other templates, enabling modular and reusable template designs. They are the primary mechanism for building complex output from simple, focused pieces.
|
|
4
|
+
|
|
5
|
+
## Template (T)
|
|
6
|
+
|
|
7
|
+
Renders a registered template by its hash. Optionally resolves data from an address to pass as the Record.
|
|
8
|
+
|
|
9
|
+
**Tags:** `{~Template:TEMPLATE_HASH~}` `{~T:TEMPLATE_HASH~}` or `{~T:TEMPLATE_HASH:DATA_ADDRESS~}`
|
|
10
|
+
|
|
11
|
+
**Parameters:**
|
|
12
|
+
|
|
13
|
+
| Parameter | Description |
|
|
14
|
+
|-----------|-------------|
|
|
15
|
+
| TEMPLATE_HASH | The hash of a registered template |
|
|
16
|
+
| DATA_ADDRESS | Optional. Address to resolve and pass as Record to the rendered template. |
|
|
17
|
+
|
|
18
|
+
**Examples:**
|
|
19
|
+
|
|
20
|
+
```javascript
|
|
21
|
+
_Pict.TemplateProvider.addTemplate('UserBadge',
|
|
22
|
+
'<span class="badge">{~D:Record.Name~} ({~D:Record.Role~})</span>');
|
|
23
|
+
|
|
24
|
+
_Pict.AppData.CurrentUser = { Name: 'Alice', Role: 'Admin' };
|
|
25
|
+
|
|
26
|
+
// Render with data from an address
|
|
27
|
+
_Pict.parseTemplate('{~T:UserBadge:AppData.CurrentUser~}');
|
|
28
|
+
// '<span class="badge">Alice (Admin)</span>'
|
|
29
|
+
|
|
30
|
+
// Without a data address, uses the current Record
|
|
31
|
+
_Pict.parseTemplate('{~T:UserBadge~}', { Name: 'Bob', Role: 'User' });
|
|
32
|
+
// '<span class="badge">Bob (User)</span>'
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
This is the most common composition expression. Use it to break large templates into smaller, reusable fragments.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## TemplateByDataAddress (TBDA)
|
|
40
|
+
|
|
41
|
+
Reads a **template string** (the actual template content) from a data address and parses it inline. The value at the address must be a valid template string.
|
|
42
|
+
|
|
43
|
+
**Tags:** `{~TemplateByDataAddress:ADDRESS~}` `{~TBDA:ADDRESS~}`
|
|
44
|
+
|
|
45
|
+
**Parameters:**
|
|
46
|
+
|
|
47
|
+
| Parameter | Description |
|
|
48
|
+
|-----------|-------------|
|
|
49
|
+
| ADDRESS | Path to a string containing template content |
|
|
50
|
+
|
|
51
|
+
**Examples:**
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
_Pict.AppData.CustomHeader = '<h1>{~D:AppData.SiteName~}</h1>';
|
|
55
|
+
_Pict.AppData.SiteName = 'My Bookstore';
|
|
56
|
+
|
|
57
|
+
_Pict.parseTemplate('{~TBDA:AppData.CustomHeader~}');
|
|
58
|
+
// '<h1>My Bookstore</h1>'
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This is useful when template content is stored in configuration, database records, or user-defined layouts. The resolved string is fully parsed -- it can contain any Jellyfish expressions.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## TemplateFromAddress (TFA)
|
|
66
|
+
|
|
67
|
+
Identical to TemplateByDataAddress. Reads template content from a data address and parses it.
|
|
68
|
+
|
|
69
|
+
**Tags:** `{~TemplateFromAddress:ADDRESS~}` `{~TFA:ADDRESS~}`
|
|
70
|
+
|
|
71
|
+
**Parameters:**
|
|
72
|
+
|
|
73
|
+
| Parameter | Description |
|
|
74
|
+
|-----------|-------------|
|
|
75
|
+
| ADDRESS | Path to a string containing template content |
|
|
76
|
+
|
|
77
|
+
**Examples:**
|
|
78
|
+
|
|
79
|
+
```javascript
|
|
80
|
+
_Pict.parseTemplate('{~TFA:Record.TemplateContent~}',
|
|
81
|
+
{ TemplateContent: '<strong>{~D:Record.Label~}</strong>', Label: 'Important' });
|
|
82
|
+
// '<strong>Important</strong>'
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## TemplateByReference (TBR)
|
|
88
|
+
|
|
89
|
+
Reads a **template hash** (the name of a registered template) from a data address, then renders that registered template.
|
|
90
|
+
|
|
91
|
+
**Tags:** `{~TemplateByReference:ADDRESS~}` `{~TBR:ADDRESS~}`
|
|
92
|
+
|
|
93
|
+
**Parameters:**
|
|
94
|
+
|
|
95
|
+
| Parameter | Description |
|
|
96
|
+
|-----------|-------------|
|
|
97
|
+
| ADDRESS | Path to a string containing a template hash |
|
|
98
|
+
|
|
99
|
+
**Examples:**
|
|
100
|
+
|
|
101
|
+
```javascript
|
|
102
|
+
_Pict.TemplateProvider.addTemplate('CardLayout',
|
|
103
|
+
'<div class="card">{~D:Record.Content~}</div>');
|
|
104
|
+
_Pict.TemplateProvider.addTemplate('ListLayout',
|
|
105
|
+
'<li>{~D:Record.Content~}</li>');
|
|
106
|
+
|
|
107
|
+
// The template to use is determined by data
|
|
108
|
+
_Pict.parseTemplate('{~TBR:Record.LayoutType~}',
|
|
109
|
+
{ LayoutType: 'CardLayout', Content: 'Hello' });
|
|
110
|
+
// '<div class="card">Hello</div>'
|
|
111
|
+
|
|
112
|
+
_Pict.parseTemplate('{~TBR:Record.LayoutType~}',
|
|
113
|
+
{ LayoutType: 'ListLayout', Content: 'Hello' });
|
|
114
|
+
// '<li>Hello</li>'
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The difference between TBR and TBDA: TBR resolves a template **name** from data and looks it up in the TemplateProvider. TBDA resolves the template **content** from data and parses it directly. Use TBR when the data controls which pre-registered template to use. Use TBDA when the data contains the actual template markup.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## TemplateFromMap (TFM)
|
|
122
|
+
|
|
123
|
+
Looks up a key in a map/object, retrieves the entry, and renders a template with that entry as the Record.
|
|
124
|
+
|
|
125
|
+
**Tags:** `{~TemplateFromMap:TEMPLATE_HASH:MAP_ADDRESS:KEY_ADDRESS~}` `{~TFM:TEMPLATE_HASH:MAP_ADDRESS:KEY_ADDRESS~}`
|
|
126
|
+
|
|
127
|
+
**Parameters:**
|
|
128
|
+
|
|
129
|
+
| Parameter | Description |
|
|
130
|
+
|-----------|-------------|
|
|
131
|
+
| TEMPLATE_HASH | Hash of the template to render |
|
|
132
|
+
| MAP_ADDRESS | Address of the map/object to look up in |
|
|
133
|
+
| KEY_ADDRESS | Address containing the key to use for the lookup |
|
|
134
|
+
|
|
135
|
+
**Examples:**
|
|
136
|
+
|
|
137
|
+
```javascript
|
|
138
|
+
_Pict.AppData.DinosaurIndex = {
|
|
139
|
+
'Dino-01': { Name: 'Brontosaurus', Era: 'Jurassic' },
|
|
140
|
+
'Dino-02': { Name: 'T-Rex', Era: 'Cretaceous' },
|
|
141
|
+
'Dino-03': { Name: 'Triceratops', Era: 'Cretaceous' }
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
_Pict.TemplateProvider.addTemplate('DinoCard',
|
|
145
|
+
'<div><strong>{~D:Record.Name~}</strong> ({~D:Record.Era~})</div>');
|
|
146
|
+
|
|
147
|
+
// Look up a dinosaur by ID and render its card
|
|
148
|
+
_Pict.parseTemplate(
|
|
149
|
+
'{~TFM:DinoCard:AppData.DinosaurIndex:Record.IDDinosaur~}',
|
|
150
|
+
{ IDDinosaur: 'Dino-01' });
|
|
151
|
+
// '<div><strong>Brontosaurus</strong> (Jurassic)</div>'
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
This pattern is common when rendering related records. Rather than embedding all related data in each record, store a map of related entities in AppData and look them up by key during rendering.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## TemplateByType (TBT)
|
|
159
|
+
|
|
160
|
+
Checks the JavaScript type of a value (`typeof`) and renders a template if the type matches. Optionally renders a fallback template if the type does not match.
|
|
161
|
+
|
|
162
|
+
**Tags:** `{~TemplateByType:DATA_ADDRESS:TYPE:TEMPLATE_IF_MATCH~}` `{~TBT:DATA_ADDRESS:TYPE:TEMPLATE_IF_MATCH~}` or `{~TBT:DATA_ADDRESS:TYPE:TEMPLATE_IF_MATCH:FALLBACK_DATA_ADDRESS:FALLBACK_TEMPLATE~}`
|
|
163
|
+
|
|
164
|
+
**Parameters:**
|
|
165
|
+
|
|
166
|
+
| Parameter | Description |
|
|
167
|
+
|-----------|-------------|
|
|
168
|
+
| DATA_ADDRESS | Address of the value to type-check |
|
|
169
|
+
| TYPE | Expected JavaScript type (`string`, `number`, `object`, `boolean`, `undefined`) |
|
|
170
|
+
| TEMPLATE_IF_MATCH | Template hash to render if the type matches |
|
|
171
|
+
| FALLBACK_DATA_ADDRESS | Optional. Data address for the fallback template |
|
|
172
|
+
| FALLBACK_TEMPLATE | Optional. Template hash to render if the type does not match |
|
|
173
|
+
|
|
174
|
+
**Examples:**
|
|
175
|
+
|
|
176
|
+
```javascript
|
|
177
|
+
_Pict.TemplateProvider.addTemplate('ShowString',
|
|
178
|
+
'<p>Text: {~D:Record.Value~}</p>');
|
|
179
|
+
_Pict.TemplateProvider.addTemplate('ShowNumber',
|
|
180
|
+
'<p>Number: {~Digits:Record.Value~}</p>');
|
|
181
|
+
_Pict.TemplateProvider.addTemplate('ShowDefault',
|
|
182
|
+
'<p>Unknown type</p>');
|
|
183
|
+
|
|
184
|
+
// Render different templates based on value type
|
|
185
|
+
_Pict.AppData.Item = { Value: 'Hello' };
|
|
186
|
+
_Pict.parseTemplate('{~TBT:AppData.Item.Value:string:ShowString~}');
|
|
187
|
+
// '<p>Text: Hello</p>'
|
|
188
|
+
|
|
189
|
+
// With fallback
|
|
190
|
+
_Pict.AppData.Item = { Value: 42 };
|
|
191
|
+
_Pict.parseTemplate(
|
|
192
|
+
'{~TBT:AppData.Item.Value:string:ShowString:AppData.Item:ShowNumber~}');
|
|
193
|
+
// '<p>Number: 42.00</p>'
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
TemplateByType is useful when rendering heterogeneous data where the same field may contain different types across records.
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# Template Expressions
|
|
2
|
+
|
|
3
|
+
Jellyfish ships with 44 built-in template expressions organized into ten categories. Each expression follows the same syntax: `{~TAG:parameters~}`. Most expressions have a long form and a shorthand (e.g. `Data` and `D`).
|
|
4
|
+
|
|
5
|
+
This page provides an overview of each category with links to the full documentation and individual reference pages.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Data Access Expressions
|
|
10
|
+
|
|
11
|
+
Data access expressions resolve values from Pict's address space and return them as strings. These are the most frequently used expressions in Jellyfish templates.
|
|
12
|
+
|
|
13
|
+
```html
|
|
14
|
+
<h1>{~D:AppData.PageTitle~}</h1>
|
|
15
|
+
<h1>{~DWAF:Record.Title^Untitled~}</h1>
|
|
16
|
+
<script>var config = {~DJ:AppData.Config~};</script>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
[Data Access Expressions — Full Documentation](architecture/templating/data-access.md)
|
|
20
|
+
|
|
21
|
+
| Expression | Tags | Description |
|
|
22
|
+
|-----------|------|-------------|
|
|
23
|
+
| [Data](architecture/templating/ref-data.md) | `D` | Resolve a value from the address space |
|
|
24
|
+
| [DataWithTemplateFallback](architecture/templating/ref-dwtf.md) | `DWTF` | Data with template fallback if falsy |
|
|
25
|
+
| [DataWithAbsoluteFallback](architecture/templating/ref-dwaf.md) | `DWAF` | Data with literal fallback if falsy |
|
|
26
|
+
| [DataValueByKey](architecture/templating/ref-dvbk.md) | `DVBK` | Dynamic key lookup on an object |
|
|
27
|
+
| [DataJson](architecture/templating/ref-dj.md) | `DJ` | JSON-serialize a value |
|
|
28
|
+
| [DataEncodeJavascriptString](architecture/templating/ref-dejs.md) | `DEJS` | Escape a value for JS string literals |
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Data Formatting Expressions
|
|
33
|
+
|
|
34
|
+
Formatting expressions transform resolved values for display -- numbers, dates, currencies, and string manipulation.
|
|
35
|
+
|
|
36
|
+
```html
|
|
37
|
+
<span>{~Dollars:Record.Price~}</span>
|
|
38
|
+
<time>{~DateTimeFormat:Record.PublishedDate^MMMM Do, YYYY~}</time>
|
|
39
|
+
<p>{~J:, ^Record.City^Record.State^Record.Country~}</p>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
[Data Formatting Expressions — Full Documentation](architecture/templating/data-formatting.md)
|
|
43
|
+
|
|
44
|
+
| Expression | Tags | Description |
|
|
45
|
+
|-----------|------|-------------|
|
|
46
|
+
| [Digits](architecture/templating/ref-digits.md) | `Digits` | Format number with 2 decimals and thousands separators |
|
|
47
|
+
| [Dollars](architecture/templating/ref-dollars.md) | `Dollars` | Format as US currency |
|
|
48
|
+
| [PascalCaseIdentifier](architecture/templating/ref-pascalcaseidentifier.md) | `PascalCaseIdentifier` | Convert string to PascalCase |
|
|
49
|
+
| [DateTimeYMD](architecture/templating/ref-datetimeymd.md) | `DateTimeYMD`, `DateYMD` | Format date as YYYY-MM-DD (timezone-aware) |
|
|
50
|
+
| [DateTimeFormat](architecture/templating/ref-datetimeformat.md) | `DateTimeFormat`, `DateFormat` | Format date with custom DayJS pattern |
|
|
51
|
+
| [DateOnlyYMD](architecture/templating/ref-dateonlyymd.md) | `DateOnlyYMD` | Format date-only as YYYY-MM-DD (UTC) |
|
|
52
|
+
| [DateOnlyFormat](architecture/templating/ref-dateonlyformat.md) | `DateOnlyFormat` | Format date-only with custom pattern (UTC) |
|
|
53
|
+
| [Join](architecture/templating/ref-join.md) | `J` | Join multiple values with a separator |
|
|
54
|
+
| [JoinUnique](architecture/templating/ref-joinunique.md) | `JU` | Join deduplicated values |
|
|
55
|
+
| [PluckJoinUnique](architecture/templating/ref-pluckjoinunique.md) | `PJU` | Pluck a property from array items, deduplicate, and join |
|
|
56
|
+
| [HtmlCommentStart](architecture/templating/ref-hcs.md) | `HCS` | Conditionally start an HTML comment |
|
|
57
|
+
| [HtmlCommentEnd](architecture/templating/ref-hce.md) | `HCE` | Conditionally end an HTML comment |
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Logic Expressions
|
|
62
|
+
|
|
63
|
+
Logic expressions evaluate conditions and control what content appears in the rendered output.
|
|
64
|
+
|
|
65
|
+
```html
|
|
66
|
+
{~TIfAbs:AdminPanel::AppData.UserRole^==^admin~}
|
|
67
|
+
{~NE:Record.HasAvatar^<img src="avatar.png">~}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
[Logic Expressions — Full Documentation](architecture/templating/logic.md)
|
|
71
|
+
|
|
72
|
+
| Expression | Tags | Description |
|
|
73
|
+
|-----------|------|-------------|
|
|
74
|
+
| [TemplateIf](architecture/templating/ref-tif.md) | `TIf` | Compare two data values, render template if true |
|
|
75
|
+
| [TemplateIfAbsolute](architecture/templating/ref-tifabs.md) | `TIfAbs` | Compare data value against a literal |
|
|
76
|
+
| [NotEmpty](architecture/templating/ref-ne.md) | `NE` | Output literal text if value is truthy |
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Iteration Expressions
|
|
81
|
+
|
|
82
|
+
Iteration expressions render a template once for each item in a collection.
|
|
83
|
+
|
|
84
|
+
```html
|
|
85
|
+
<ul>{~TS:ProductRow:AppData.Products~}</ul>
|
|
86
|
+
{~TSWP:ItemRow:AppData.Items:AppData.DisplayConfig~}
|
|
87
|
+
{~TVS:ValueDisplay:AppData.Tags~}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
[Iteration Expressions — Full Documentation](architecture/templating/iteration.md)
|
|
91
|
+
|
|
92
|
+
| Expression | Tags | Description |
|
|
93
|
+
|-----------|------|-------------|
|
|
94
|
+
| [TemplateSet](architecture/templating/ref-ts.md) | `TS` | Render template for each item in an array |
|
|
95
|
+
| [TemplateSetFromMap](architecture/templating/ref-tsfm.md) | `TSFM` | Look up array by key in map, render each item |
|
|
96
|
+
| [TemplateSetWithPayload](architecture/templating/ref-tswp.md) | `TSWP` | Render with extra payload data per item |
|
|
97
|
+
| [TemplateValueSet](architecture/templating/ref-tvs.md) | `TVS` | Iterate over values with Key/Value/Index/Count metadata |
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Template Composition Expressions
|
|
102
|
+
|
|
103
|
+
Composition expressions render other templates, enabling modular and reusable template designs.
|
|
104
|
+
|
|
105
|
+
```html
|
|
106
|
+
{~T:UserCard:AppData.CurrentUser~}
|
|
107
|
+
{~TBR:Record.TemplateName~}
|
|
108
|
+
{~TFM:DinoCard:AppData.DinosaurMap:Record.IDDinosaur~}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
[Template Composition Expressions — Full Documentation](architecture/templating/template-composition.md)
|
|
112
|
+
|
|
113
|
+
| Expression | Tags | Description |
|
|
114
|
+
|-----------|------|-------------|
|
|
115
|
+
| [Template](architecture/templating/ref-template.md) | `T` | Render a registered template by hash |
|
|
116
|
+
| [TemplateByDataAddress](architecture/templating/ref-tbda.md) | `TBDA` | Parse template content from a data address |
|
|
117
|
+
| [TemplateFromAddress](architecture/templating/ref-tfa.md) | `TFA` | Same as TBDA |
|
|
118
|
+
| [TemplateByReference](architecture/templating/ref-tbr.md) | `TBR` | Resolve template hash from data, render it |
|
|
119
|
+
| [TemplateFromMap](architecture/templating/ref-tfm.md) | `TFM` | Look up record in map, render template with it |
|
|
120
|
+
| [TemplateByType](architecture/templating/ref-tbt.md) | `TBT` | Render template based on value's JavaScript type |
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Solver Expressions
|
|
125
|
+
|
|
126
|
+
Solver expressions evaluate mathematical expressions using Fable's expression parser, with support for arithmetic, built-in functions, and variable references.
|
|
127
|
+
|
|
128
|
+
```html
|
|
129
|
+
<span>Total: {~S:Price*Quantity:Record~}</span>
|
|
130
|
+
<span>Area: {~S:ROUND(PI()*Radius*Radius,2):Record~}</span>
|
|
131
|
+
{~SBR:AppData.PricingFormula:AppData.OrderData~}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
[Solver Expressions — Full Documentation](architecture/templating/solvers.md)
|
|
135
|
+
|
|
136
|
+
| Expression | Tags | Description |
|
|
137
|
+
|-----------|------|-------------|
|
|
138
|
+
| [Solve](architecture/templating/ref-solve.md) | `S` | Evaluate a math expression |
|
|
139
|
+
| [SolveByReference](architecture/templating/ref-sbr.md) | `SBR` | Evaluate an equation string from data |
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Entity Expressions
|
|
144
|
+
|
|
145
|
+
Entity expressions integrate with Pict's Meadow API layer to fetch records from REST endpoints and render them with templates. These are inherently asynchronous.
|
|
146
|
+
|
|
147
|
+
```html
|
|
148
|
+
{~E:Book^42^BookCard~}
|
|
149
|
+
{~E:Book^Record.IDBook^BookCard~}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
[Entity Expressions — Full Documentation](architecture/templating/entity.md)
|
|
153
|
+
|
|
154
|
+
| Expression | Tags | Description |
|
|
155
|
+
|-----------|------|-------------|
|
|
156
|
+
| [Entity](architecture/templating/ref-entity.md) | `E` | Fetch an entity by type and ID, render with template |
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## View and Self-Reference Expressions
|
|
161
|
+
|
|
162
|
+
These expressions bridge templates with Pict's view system and JavaScript runtime.
|
|
163
|
+
|
|
164
|
+
```html
|
|
165
|
+
{~V:HeaderView~}
|
|
166
|
+
{~VRS:ChildView~}
|
|
167
|
+
<button onclick="{~P~}.views['MyView'].doSomething()">Click</button>
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
[View and Self-Reference Expressions — Full Documentation](architecture/templating/views.md)
|
|
171
|
+
|
|
172
|
+
| Expression | Tags | Description |
|
|
173
|
+
|-----------|------|-------------|
|
|
174
|
+
| [View](architecture/templating/ref-view.md) | `V` | Render a Pict view inline |
|
|
175
|
+
| [ViewRetainingScope](architecture/templating/ref-vrs.md) | `VRS` | Render a view while carrying scope through |
|
|
176
|
+
| [Pict](architecture/templating/ref-pict.md) | `P` | Reference to the Pict instance for event handlers |
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Debugging Expressions
|
|
181
|
+
|
|
182
|
+
Debugging expressions help during development by logging values, inserting breakpoints, and rendering object structures.
|
|
183
|
+
|
|
184
|
+
```html
|
|
185
|
+
{~LS:Processing user section~}
|
|
186
|
+
{~LV:AppData.CurrentUser~}
|
|
187
|
+
{~Breakpoint~}
|
|
188
|
+
{~DT:AppData.DebugData~}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
[Debugging Expressions — Full Documentation](architecture/templating/debugging.md)
|
|
192
|
+
|
|
193
|
+
| Expression | Tags | Description |
|
|
194
|
+
|-----------|------|-------------|
|
|
195
|
+
| [Breakpoint](architecture/templating/ref-breakpoint.md) | `Breakpoint` | Insert a debugger breakpoint |
|
|
196
|
+
| [LogStatement](architecture/templating/ref-ls.md) | `LS` | Log a literal message |
|
|
197
|
+
| [LogValue](architecture/templating/ref-lv.md) | `LV` | Log a resolved value with type info |
|
|
198
|
+
| [LogValueTree](architecture/templating/ref-lvt.md) | `LVT` | Log an object tree to console |
|
|
199
|
+
| [DataTree](architecture/templating/ref-dt.md) | `DT` | Render an object tree as HTML |
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Data Generation Expressions
|
|
204
|
+
|
|
205
|
+
Data generation expressions produce random values for testing, unique IDs, or placeholder content.
|
|
206
|
+
|
|
207
|
+
```html
|
|
208
|
+
<span>{~RN:1,100~}</span>
|
|
209
|
+
<code>REF-{~RNS:6~}</code>
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
[Data Generation Expressions — Full Documentation](architecture/templating/data-generation.md)
|
|
213
|
+
|
|
214
|
+
| Expression | Tags | Description |
|
|
215
|
+
|-----------|------|-------------|
|
|
216
|
+
| [RandomNumber](architecture/templating/ref-rn.md) | `RN` | Generate a random integer |
|
|
217
|
+
| [RandomNumberString](architecture/templating/ref-rns.md) | `RNS` | Generate a zero-padded random numeric string |
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# View and Self-Reference Expressions
|
|
2
|
+
|
|
3
|
+
These expressions bridge templates with Pict's view system and JavaScript runtime. They render views inline, retain scope across view boundaries, and provide the Pict instance reference for event handlers.
|
|
4
|
+
|
|
5
|
+
## View (V)
|
|
6
|
+
|
|
7
|
+
Renders a registered Pict view by its hash. The view's render output is captured as a string and inserted into the template.
|
|
8
|
+
|
|
9
|
+
**Tags:** `{~View:VIEW_HASH~}` `{~V:VIEW_HASH~}`
|
|
10
|
+
|
|
11
|
+
**Parameters:**
|
|
12
|
+
|
|
13
|
+
| Parameter | Description |
|
|
14
|
+
|-----------|-------------|
|
|
15
|
+
| VIEW_HASH | The hash identifier of a registered Pict view |
|
|
16
|
+
|
|
17
|
+
**Examples:**
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
// Register a view
|
|
21
|
+
let _HeaderView = _Pict.addView('HeaderView',
|
|
22
|
+
{
|
|
23
|
+
ViewIdentifier: 'HeaderView',
|
|
24
|
+
DefaultRenderable: 'HeaderContent',
|
|
25
|
+
Templates: [
|
|
26
|
+
{
|
|
27
|
+
Hash: 'HeaderContent',
|
|
28
|
+
Template: '<header><h1>{~D:AppData.SiteName~}</h1></header>'
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
Renderables: [
|
|
32
|
+
{
|
|
33
|
+
RenderableHash: 'HeaderContent',
|
|
34
|
+
TemplateHash: 'HeaderContent',
|
|
35
|
+
DestinationAddress: '#header'
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Embed the view in a template
|
|
41
|
+
_Pict.parseTemplate('<div class="page">{~V:HeaderView~}<main>Content</main></div>');
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The View expression triggers the view's render pipeline, capturing its output to a virtual render target. This output is then inserted at the expression's location in the template string.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## ViewRetainingScope (VRS)
|
|
49
|
+
|
|
50
|
+
Same as View, but passes the current scope through to the child view using `renderWithScope()`. The child view can access values from the parent's Scope namespace.
|
|
51
|
+
|
|
52
|
+
**Tags:** `{~ViewRetainingScope:VIEW_HASH~}` `{~VRS:VIEW_HASH~}`
|
|
53
|
+
|
|
54
|
+
**Parameters:**
|
|
55
|
+
|
|
56
|
+
| Parameter | Description |
|
|
57
|
+
|-----------|-------------|
|
|
58
|
+
| VIEW_HASH | The hash identifier of a registered Pict view |
|
|
59
|
+
|
|
60
|
+
**Examples:**
|
|
61
|
+
|
|
62
|
+
```javascript
|
|
63
|
+
// Parent template sets scope values
|
|
64
|
+
_Pict.parseTemplate(
|
|
65
|
+
'{~VRS:ChildView~}',
|
|
66
|
+
null, // no record
|
|
67
|
+
null, // no callback
|
|
68
|
+
null, // no context
|
|
69
|
+
{ theme: 'dark', layout: 'compact' } // scope
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
// Inside ChildView's templates, Scope values are accessible:
|
|
73
|
+
// '{~D:Scope.theme~}' resolves to 'dark'
|
|
74
|
+
// '{~D:Scope.layout~}' resolves to 'compact'
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Use VRS when a parent view needs to pass contextual configuration to child views without polluting AppData. Scope is sticky -- it travels through the rendering chain without being modified, so deeply nested views all see the same scope values set by the parent.
|
|
78
|
+
|
|
79
|
+
The plain `{~V:...~}` expression does not carry scope. Use it when the child view is self-contained and does not need context from its parent.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Pict / Self-Reference (P)
|
|
84
|
+
|
|
85
|
+
Returns the browser-side JavaScript reference to the Pict instance. This is essential for wiring event handlers in server-rendered HTML.
|
|
86
|
+
|
|
87
|
+
**Tags:** `{~Pict~}` `{~P~}`
|
|
88
|
+
|
|
89
|
+
**Parameters:** None. This expression takes no parameters.
|
|
90
|
+
|
|
91
|
+
**Default value:** `window._Pict`
|
|
92
|
+
|
|
93
|
+
**Examples:**
|
|
94
|
+
|
|
95
|
+
```html
|
|
96
|
+
<!-- Simple click handler -->
|
|
97
|
+
<button onclick="{~P~}.views['CartView'].addItem({~D:Record.IDProduct~})">
|
|
98
|
+
Add to Cart
|
|
99
|
+
</button>
|
|
100
|
+
|
|
101
|
+
<!-- Calling a view method with data -->
|
|
102
|
+
<a href="#" onclick="{~P~}.views['Nav'].navigate('{~DEJS:Record.Route~}'); return false;">
|
|
103
|
+
{~D:Record.Label~}
|
|
104
|
+
</a>
|
|
105
|
+
|
|
106
|
+
<!-- Accessing Pict state from inline JS -->
|
|
107
|
+
<script>
|
|
108
|
+
var currentUser = {~P~}.AppData.User;
|
|
109
|
+
</script>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
// Default
|
|
114
|
+
_Pict.parseTemplate('{~P~}');
|
|
115
|
+
// 'window._Pict'
|
|
116
|
+
|
|
117
|
+
// Custom browser address (for nested Pict instances)
|
|
118
|
+
_Pict.browserAddress = 'window._Pict.children[0]';
|
|
119
|
+
_Pict.parseTemplate('{~P~}');
|
|
120
|
+
// 'window._Pict.children[0]'
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The Pict expression solves the problem of connecting server-rendered templates to client-side behavior. Without it, onclick handlers and inline scripts would need to hardcode the Pict instance path, which breaks when Pict instances are nested or when the global reference changes.
|
|
124
|
+
|
|
125
|
+
### Common Patterns
|
|
126
|
+
|
|
127
|
+
**View method calls from rendered HTML:**
|
|
128
|
+
|
|
129
|
+
```javascript
|
|
130
|
+
_Pict.TemplateProvider.addTemplate('ActionButton', [
|
|
131
|
+
'<button onclick="{~P~}.views[\'TodoView\'].toggleComplete(\'{~DEJS:Record.GUID~}\')">',
|
|
132
|
+
' {~D:Record.Title~}',
|
|
133
|
+
'</button>'
|
|
134
|
+
].join('\n'));
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Form submission:**
|
|
138
|
+
|
|
139
|
+
```javascript
|
|
140
|
+
_Pict.TemplateProvider.addTemplate('SearchForm', [
|
|
141
|
+
'<form onsubmit="{~P~}.views[\'SearchView\'].search(this.q.value); return false;">',
|
|
142
|
+
' <input name="q" type="text" />',
|
|
143
|
+
' <button type="submit">Search</button>',
|
|
144
|
+
'</form>'
|
|
145
|
+
].join('\n'));
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Data attributes for JavaScript initialization:**
|
|
149
|
+
|
|
150
|
+
```html
|
|
151
|
+
<div data-pict-ref="{~P~}" data-view="ChartView">
|
|
152
|
+
{~V:ChartView~}
|
|
153
|
+
</div>
|
|
154
|
+
```
|
|
@@ -82,7 +82,7 @@ npm install
|
|
|
82
82
|
npm run build
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
-
Open **http://localhost:8086** in a browser. The server serves the built client as static files. The web client includes a sortable task list with search and pagination, an add/edit form, and week/month/year calendar views.
|
|
85
|
+
Open **http://localhost:8086** in a browser. The server serves the built client as static files. The web client includes a sortable task list with search and pagination, an add/edit form, and week/month/year calendar views. You may have to restart the server for the client to begin serving, depending on your environment.
|
|
86
86
|
|
|
87
87
|
See [Web Client](examples/todolist/todo-list-web-client.md) for details.
|
|
88
88
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Apps — Applications
|
|
2
|
+
|
|
3
|
+
Full-stack applications built on the Retold ecosystem, combining Fable, Meadow, Orator, and Pict into complete systems.
|
|
4
|
+
|
|
5
|
+
## Modules
|
|
6
|
+
|
|
7
|
+
### [Retold Content System](/apps/retold-content-system/)
|
|
8
|
+
|
|
9
|
+
Content management system built on the Retold ecosystem.
|
|
10
|
+
|
|
11
|
+
**npm:** `retold-content-system`
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
### [Retold Remote](/apps/retold-remote/)
|
|
16
|
+
|
|
17
|
+
Remote access application built on the Retold ecosystem.
|
|
18
|
+
|
|
19
|
+
**npm:** `retold-remote`
|
|
20
|
+
|
|
21
|
+
## All Apps Modules
|
|
22
|
+
|
|
23
|
+
| Module | Description |
|
|
24
|
+
|--------|-------------|
|
|
25
|
+
| [retold-content-system](/apps/retold-content-system/) | Content management system built on the Retold ecosystem |
|
|
26
|
+
| [retold-remote](/apps/retold-remote/) | Remote access application built on the Retold ecosystem |
|
package/docs/modules/pict.md
CHANGED
|
@@ -185,6 +185,22 @@ Markdown parsing and content rendering with Mermaid diagrams and KaTeX math equa
|
|
|
185
185
|
|
|
186
186
|
---
|
|
187
187
|
|
|
188
|
+
### [Pict-Section-Code](/pict/pict-section-code/)
|
|
189
|
+
|
|
190
|
+
Code editor and syntax highlighter wrapping CodeJar. Provides editable code editors and read-only syntax-highlighted displays with built-in support for JavaScript, JSON, HTML, CSS, and SQL. Supports custom highlighter functions and two-way data binding to Pict AppData.
|
|
191
|
+
|
|
192
|
+
**npm:** `pict-section-code`
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
### [Pict-Section-MarkdownEditor](/pict/pict-section-markdowneditor/)
|
|
197
|
+
|
|
198
|
+
Segmented markdown editor built on CodeMirror v6. Splits documents into independently editable segments with drag-and-drop reorder, formatting toolbar, image upload hooks, and live rich previews with Mermaid diagrams and KaTeX math. Supports read-only mode, rendered view toggle, and server-side image upload integration.
|
|
199
|
+
|
|
200
|
+
**npm:** `pict-section-markdowneditor`
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
188
204
|
### [Pict-Section-Flow](/pict/pict-section-flow/)
|
|
189
205
|
|
|
190
206
|
Flow diagram section for visual workflow and process representations.
|
|
@@ -228,6 +244,8 @@ Flow diagram section for visual workflow and process representations.
|
|
|
228
244
|
| [pict-service-commandlineutility](/pict/pict-service-commandlineutility/) | CLI utility tools |
|
|
229
245
|
| [pict-section-recordset](/pict/pict-section-recordset/) | CRUD record management views |
|
|
230
246
|
| [pict-section-content](/pict/pict-section-content/) | Markdown parsing and content rendering |
|
|
247
|
+
| [pict-section-code](/pict/pict-section-code/) | Code editor and syntax highlighter wrapping CodeJar |
|
|
248
|
+
| [pict-section-markdowneditor](/pict/pict-section-markdowneditor/) | Segmented markdown editor built on CodeMirror v6 |
|
|
231
249
|
| [pict-section-form](/pict/pict-section-form/) | Configuration-driven dynamic forms |
|
|
232
250
|
| [pict-section-tuigrid](/pict/pict-section-tuigrid/) | Toast UI Grid tabular data |
|
|
233
251
|
| [pict-router](/pict/pict-router/) | Hash-based URL routing |
|
package/docs/modules/utility.md
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
# Utility — Build & Documentation Tools
|
|
2
2
|
|
|
3
|
-
The utility group provides supporting tools for building, documenting, testing, and supervising Retold applications.
|
|
3
|
+
The utility group provides supporting tools for building, documenting, testing, caching, templating, and supervising Retold applications.
|
|
4
4
|
|
|
5
5
|
## Modules
|
|
6
6
|
|
|
7
|
+
### [CacheTrax](/utility/cachetrax/)
|
|
8
|
+
|
|
9
|
+
Lightweight in-memory object cache combining a hash map for O(1) key lookups with a double linked list for ordered eviction. Supports automatic size-based pruning on insert, time-based expiration, touch-to-refresh, and custom pruning functions.
|
|
10
|
+
|
|
11
|
+
**Key features:** O(1) hash-indexed reads, configurable `maxLength` and `maxAge`, FIFO eviction, custom prune functions, Fable service integration, browser compatible.
|
|
12
|
+
|
|
13
|
+
**npm:** `cachetrax` · **Version:** 1.0.x
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
7
17
|
### [Indoctrinate](/utility/indoctrinate/)
|
|
8
18
|
|
|
9
19
|
Documentation scaffolding and generation. Scans source trees, catalogs content with automatic label-based metadata, and generates structured output in multiple formats. Powers the Retold documentation hub by generating cross-module catalogs and keyword search indexes.
|
|
@@ -24,6 +34,16 @@ JSON manifest for consistent data description and parsing across all application
|
|
|
24
34
|
|
|
25
35
|
---
|
|
26
36
|
|
|
37
|
+
### [Precedent](/utility/precedent/)
|
|
38
|
+
|
|
39
|
+
Meta-templating engine for processing text streams with pattern-based template expressions. Define start/end pattern markers with string or function parsers, and Precedent handles nested pattern resolution automatically using a word tree architecture.
|
|
40
|
+
|
|
41
|
+
**Key features:** Pattern-based start/end markers, string or function parsers, nested pattern support with prefix precedence, data passing to handlers, zero external dependencies, browser compatible.
|
|
42
|
+
|
|
43
|
+
**npm:** `precedent` · **Version:** 1.0.x
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
27
47
|
### [Quackage](/utility/quackage/)
|
|
28
48
|
|
|
29
49
|
Standardized build tool for Retold modules. Handles browser bundling (Browserify), transpilation, unit testing, file management, JSON view assembly, and documentation generation from a single CLI.
|
|
@@ -48,7 +68,9 @@ Process supervision tool for running commands on schedule with LLM integration.
|
|
|
48
68
|
|
|
49
69
|
| Module | Description |
|
|
50
70
|
|--------|-------------|
|
|
71
|
+
| [cachetrax](/utility/cachetrax/) | Hash-indexed object cache with time and size based expiration |
|
|
51
72
|
| [indoctrinate](/utility/indoctrinate/) | Documentation scaffolding with content cataloging and cross-module search |
|
|
52
73
|
| [manyfest](/utility/manyfest/) | JSON manifest for data description, validation, and address-based access |
|
|
74
|
+
| [precedent](/utility/precedent/) | Meta-templating engine with pattern-based start/end markers and word tree matching |
|
|
53
75
|
| [quackage](/utility/quackage/) | Build tool for browser bundles, testing, and packaging |
|
|
54
76
|
| [ultravisor](/utility/ultravisor/) | Process supervision with scheduled tasks and LLM integration |
|