@dosgato/templating 0.0.39 → 0.0.42
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/dist/apitemplate.d.ts +0 -5
- package/dist/apitemplate.js +0 -10
- package/dist/component.d.ts +89 -48
- package/dist/component.js +42 -39
- package/dist/links.d.ts +10 -0
- package/dist/links.js +19 -1
- package/dist/render.d.ts +23 -6
- package/package.json +3 -3
- package/dist/editbar.d.ts +0 -11
- package/dist/editbar.js +0 -23
package/dist/apitemplate.d.ts
CHANGED
|
@@ -188,11 +188,6 @@ export declare type AnyMigration = ComponentMigration | PageMigration | DataMigr
|
|
|
188
188
|
export declare type LinkGatheringFn = (data: any) => LinkDefinition[];
|
|
189
189
|
export declare type FulltextGatheringFn = (data: any) => string[];
|
|
190
190
|
export declare type GraphQLQueryFn = <T>(query: string, variables?: any) => Promise<T>;
|
|
191
|
-
/**
|
|
192
|
-
* This function is used by API template definitions to help them identify links inside large blocks
|
|
193
|
-
* of text and return them for indexing.
|
|
194
|
-
*/
|
|
195
|
-
export declare function extractLinksFromText(text: string | undefined): LinkDefinition[];
|
|
196
191
|
/**
|
|
197
192
|
* This function is used by API template definitions to help them identify all the searchable
|
|
198
193
|
* words in a large block of text and return them for indexing.
|
package/dist/apitemplate.js
CHANGED
|
@@ -5,16 +5,6 @@ export var ValidationMessageType;
|
|
|
5
5
|
ValidationMessageType["WARNING"] = "warning";
|
|
6
6
|
ValidationMessageType["SUCCESS"] = "success";
|
|
7
7
|
})(ValidationMessageType || (ValidationMessageType = {}));
|
|
8
|
-
/**
|
|
9
|
-
* This function is used by API template definitions to help them identify links inside large blocks
|
|
10
|
-
* of text and return them for indexing.
|
|
11
|
-
*/
|
|
12
|
-
export function extractLinksFromText(text) {
|
|
13
|
-
if (!text)
|
|
14
|
-
return [];
|
|
15
|
-
const matches = text.matchAll(/{.*"type"\s?:\s+"\w+".*?}/gi);
|
|
16
|
-
return Array.from(matches).map(m => JSON.parse(m[0]));
|
|
17
|
-
}
|
|
18
8
|
/**
|
|
19
9
|
* This function is used by API template definitions to help them identify all the searchable
|
|
20
10
|
* words in a large block of text and return them for indexing.
|
package/dist/component.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { EditBarOpts } from './editbar.js';
|
|
2
1
|
import { ResourceProvider } from './provider.js';
|
|
3
2
|
import { APIClient } from './render.js';
|
|
4
3
|
/**
|
|
@@ -9,22 +8,10 @@ import { APIClient } from './render.js';
|
|
|
9
8
|
* parent and child components linked.
|
|
10
9
|
*/
|
|
11
10
|
export declare abstract class Component<DataType extends ComponentData = any, FetchedType = any, RenderContextType extends ContextBase = any> extends ResourceProvider {
|
|
12
|
-
static templateKey: string;
|
|
13
|
-
static templateName: string;
|
|
14
|
-
areas: Map<string, Component<any, any, any>[]>;
|
|
15
|
-
data: Omit<DataType, 'areas'>;
|
|
16
|
-
fetched: FetchedType;
|
|
17
|
-
renderCtx: RenderContextType;
|
|
18
|
-
path: string;
|
|
19
|
-
parent?: Component;
|
|
20
|
-
page?: Page;
|
|
21
|
-
hadError: boolean;
|
|
22
11
|
/**
|
|
23
|
-
*
|
|
24
|
-
* determine whether you are doing your work in edit mode or regular rendering mode.
|
|
25
|
-
* The editBar and newBar methods will automatically use it to blank out the editing UI.
|
|
12
|
+
* Provide this when you create a template to identify what you are defining.
|
|
26
13
|
*/
|
|
27
|
-
|
|
14
|
+
static templateKey: string;
|
|
28
15
|
/**
|
|
29
16
|
* The rendering server will provide an instance of the APIClient interface so that
|
|
30
17
|
* you can run any API GraphQL query you like in your `fetch` function. There are also
|
|
@@ -36,25 +23,23 @@ export declare abstract class Component<DataType extends ComponentData = any, Fe
|
|
|
36
23
|
*/
|
|
37
24
|
api: APIClient;
|
|
38
25
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* This function will be provided by the rendering service.
|
|
43
|
-
*
|
|
44
|
-
* Do NOT mutate the data returned by this function, as it may be cached and given to
|
|
45
|
-
* other Component instances.
|
|
26
|
+
* This property will be set during page render and you may refer to it at any time to
|
|
27
|
+
* determine whether you are doing your work in edit mode or regular rendering mode.
|
|
28
|
+
* The editBar and newBar methods will automatically use it to blank out the editing UI.
|
|
46
29
|
*/
|
|
47
|
-
|
|
30
|
+
editMode: boolean;
|
|
48
31
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
32
|
+
* When hydrating an inherited component, the renderer will set this to the id of the page it
|
|
33
|
+
* came from. You may use this information in any of the phases to alter your behavior if needed.
|
|
51
34
|
*
|
|
52
|
-
*
|
|
35
|
+
* For instance, you may decide that your fetch function needs some extra information from the
|
|
36
|
+
* originating page instead of the page you're being inherited into (your `this.page` will
|
|
37
|
+
* be the page currently being rendered, NOT the page the inheritable component came from).
|
|
53
38
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
39
|
+
* This property is also used to alter the edit bar. Inherited components may never be edited
|
|
40
|
+
* except on their original page, so the edit bar will render with a link to the original page.
|
|
56
41
|
*/
|
|
57
|
-
|
|
42
|
+
inheritedFrom?: string;
|
|
58
43
|
/**
|
|
59
44
|
* The first phase of rendering a component is the fetch phase. Each component may
|
|
60
45
|
* provide a fetch method that looks up data it needs from external sources. This step
|
|
@@ -64,12 +49,27 @@ export declare abstract class Component<DataType extends ComponentData = any, Fe
|
|
|
64
49
|
* Place any needed data into the return object, and it will be available to you as `this.fetched`
|
|
65
50
|
* during the rendering phase.
|
|
66
51
|
*
|
|
67
|
-
* Note that this.page will be available, and
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
52
|
+
* Note that `this.page` will be available, and `this.api` has dataloaded methods for retrieving
|
|
53
|
+
* data from the API if, for instance, you need to inherit information from a parent or root
|
|
54
|
+
* page. If you need to inherit and render entire components from ancestor pages,
|
|
55
|
+
* you must register them. See the comment for `this.registerInherited`
|
|
56
|
+
*
|
|
57
|
+
* Try to minimize the number of round trips you make here, make use of Promise.all and such;
|
|
58
|
+
* remember that the api functions are mostly dataloaded so calling them simultaneously is
|
|
59
|
+
* advantageous where possible.
|
|
71
60
|
*/
|
|
72
61
|
fetch(): Promise<FetchedType>;
|
|
62
|
+
/**
|
|
63
|
+
* Some components may be inheritable to subpages within the same site. For instance, a site's
|
|
64
|
+
* social media links may appear on every page's footer. To accomplish this in your template,
|
|
65
|
+
* you need to fetch ancestor page data in your fetch phase, identify the component data you want
|
|
66
|
+
* to inherit, and then call this function within your fetch to let the renderer know it needs to
|
|
67
|
+
* process those components (hydrate them, call their fetch functions, and include them in the render).
|
|
68
|
+
*
|
|
69
|
+
* The inherited components will be added to the appropriate area's array in the renderedAreas
|
|
70
|
+
* parameter of your render function.
|
|
71
|
+
*/
|
|
72
|
+
registerInherited: (area: string, components: ComponentData[], top?: true) => void;
|
|
73
73
|
/**
|
|
74
74
|
* The second phase of rendering a component is the context phase. This step is TOP-DOWN and
|
|
75
75
|
* NON-MUTATING. Each component will receive the parent component's context and then pass a
|
|
@@ -92,7 +92,7 @@ export declare abstract class Component<DataType extends ComponentData = any, Fe
|
|
|
92
92
|
* render will be passed to parent components so that the HTML can be included during the
|
|
93
93
|
* render of the parent component.
|
|
94
94
|
*/
|
|
95
|
-
abstract render(renderedAreas: Map<string,
|
|
95
|
+
abstract render(renderedAreas: Map<string, RenderedComponent[]>): string;
|
|
96
96
|
/**
|
|
97
97
|
* Sometimes pages are requested with an alternate extension like .rss or .ics. In these
|
|
98
98
|
* situations, each component should consider whether it should output anything. For
|
|
@@ -106,14 +106,9 @@ export declare abstract class Component<DataType extends ComponentData = any, Fe
|
|
|
106
106
|
* will be skipped.
|
|
107
107
|
*/
|
|
108
108
|
renderVariation(extension: string, renderedAreas: Map<string, string>): string;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
* render, or renderVariation functions throw, the error will be logged but the page render will
|
|
113
|
-
* continue. You generally do not need to use this function, just throw when appropriate.
|
|
114
|
-
*/
|
|
115
|
-
logError(e: Error): void;
|
|
116
|
-
protected passError(e: Error, path: string): void;
|
|
109
|
+
renderComponents(components?: RenderedComponent[], opts?: {
|
|
110
|
+
hideInheritBars?: boolean;
|
|
111
|
+
}): string;
|
|
117
112
|
/**
|
|
118
113
|
* During rendering, each component should determine the CSS blocks that it needs. This may
|
|
119
114
|
* change depending on the data. For instance, if you need some CSS to style up an image, but
|
|
@@ -122,6 +117,8 @@ export declare abstract class Component<DataType extends ComponentData = any, Fe
|
|
|
122
117
|
*
|
|
123
118
|
* This is evaluated after the fetch and context phases but before the rendering phase. If you
|
|
124
119
|
* need any async data to make this determination, be sure to fetch it during the fetch phase.
|
|
120
|
+
*
|
|
121
|
+
* You should check `this.editMode` if you need to load CSS that alters edit bars.
|
|
125
122
|
*/
|
|
126
123
|
cssBlocks(): string[];
|
|
127
124
|
/**
|
|
@@ -130,11 +127,11 @@ export declare abstract class Component<DataType extends ComponentData = any, Fe
|
|
|
130
127
|
jsBlocks(): string[];
|
|
131
128
|
/**
|
|
132
129
|
* Components may override this function to give their edit bars a custom
|
|
133
|
-
* label instead of using the
|
|
130
|
+
* label instead of using the template name
|
|
134
131
|
*
|
|
135
132
|
* For instance, you could return this.data.title
|
|
136
133
|
*/
|
|
137
|
-
editLabel():
|
|
134
|
+
editLabel(): undefined;
|
|
138
135
|
/**
|
|
139
136
|
* Components may override this function to give their edit bars a custom
|
|
140
137
|
* CSS class
|
|
@@ -147,7 +144,7 @@ export declare abstract class Component<DataType extends ComponentData = any, Fe
|
|
|
147
144
|
* For instance, an area that only accepts 'layout' components could
|
|
148
145
|
* return "Add Layout"
|
|
149
146
|
*/
|
|
150
|
-
newLabel(areaName: string):
|
|
147
|
+
newLabel(areaName: string): undefined;
|
|
151
148
|
/**
|
|
152
149
|
* Components may override this function to give their new bars a custom
|
|
153
150
|
* CSS class
|
|
@@ -165,6 +162,31 @@ export declare abstract class Component<DataType extends ComponentData = any, Fe
|
|
|
165
162
|
* Generally should not be overridden - override newLabel and newClass instead
|
|
166
163
|
*/
|
|
167
164
|
newBar(areaName: string, opts?: EditBarOpts): string;
|
|
165
|
+
/**
|
|
166
|
+
* These functions will be provided by the rendering server to assist in the
|
|
167
|
+
* rendering process.
|
|
168
|
+
*/
|
|
169
|
+
static editBar: (path: string, opts: EditBarOpts) => string;
|
|
170
|
+
static newBar: (path: string, opts: EditBarOpts) => string;
|
|
171
|
+
static repairHTML: (html: string) => string;
|
|
172
|
+
constructor(data: DataType, path: string, parent: Component | undefined, editMode: boolean);
|
|
173
|
+
areas: Map<string, Component<any, any, any>[]>;
|
|
174
|
+
data: Omit<DataType, 'areas'>;
|
|
175
|
+
fetched: FetchedType;
|
|
176
|
+
renderCtx: RenderContextType;
|
|
177
|
+
path: string;
|
|
178
|
+
parent?: Component;
|
|
179
|
+
page?: Page;
|
|
180
|
+
hadError: boolean;
|
|
181
|
+
autoLabel: string;
|
|
182
|
+
autoNewLabel: string;
|
|
183
|
+
/**
|
|
184
|
+
* For logging errors during rendering without crashing the render. If your fetch, setContext,
|
|
185
|
+
* render, or renderVariation functions throw, the error will be logged but the page render will
|
|
186
|
+
* continue. You generally do not need to use this function, just throw when appropriate.
|
|
187
|
+
*/
|
|
188
|
+
logError(e: Error): void;
|
|
189
|
+
protected passError(e: Error, path: string): void;
|
|
168
190
|
}
|
|
169
191
|
export interface PageRecord<DataType extends PageData = PageData> {
|
|
170
192
|
id: string;
|
|
@@ -195,12 +217,31 @@ export interface ContextBase {
|
|
|
195
217
|
*/
|
|
196
218
|
headerLevel: number;
|
|
197
219
|
}
|
|
220
|
+
export interface EditBarOpts {
|
|
221
|
+
extraClass?: string;
|
|
222
|
+
label?: string;
|
|
223
|
+
editMode?: boolean;
|
|
224
|
+
inheritedFrom?: string;
|
|
225
|
+
}
|
|
226
|
+
export interface RenderedComponent<C extends Component = Component> {
|
|
227
|
+
component: C;
|
|
228
|
+
html: string;
|
|
229
|
+
}
|
|
198
230
|
export declare abstract class Page<DataType extends PageData = any, FetchedType = any, RenderContextType extends ContextBase = any> extends Component<DataType, FetchedType, RenderContextType> {
|
|
199
231
|
pagePath: string;
|
|
200
232
|
/**
|
|
201
|
-
*
|
|
202
|
-
* the
|
|
203
|
-
*
|
|
233
|
+
* This will be filled by the rendering server. The template properties are described
|
|
234
|
+
* over in apitemplate.ts in the comment for APIPageTemplate.templateProperties.
|
|
235
|
+
*
|
|
236
|
+
* The properties will appear in the GraphQL API and the rendering server will automatically
|
|
237
|
+
* download them and provide them here so all you need to do as a template developer is
|
|
238
|
+
* reference the values in your fetch/setContext/render functions.
|
|
239
|
+
*/
|
|
240
|
+
templateProperties: any;
|
|
241
|
+
/**
|
|
242
|
+
* This is a bunch of javascript and CSS and meta tags managed by the DosGato engine. It will
|
|
243
|
+
* be filled by the rendering server and your render function for your page template
|
|
244
|
+
* should place include it in the <head> element
|
|
204
245
|
*/
|
|
205
246
|
headContent: string;
|
|
206
247
|
protected passError(e: Error, path: string): void;
|
package/dist/component.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { isNotBlank } from 'txstate-utils';
|
|
2
|
-
import { editBar, newBar } from './editbar.js';
|
|
3
2
|
import { ResourceProvider } from './provider.js';
|
|
4
3
|
/**
|
|
5
4
|
* This is the primary templating class to build your templates. Subclass it and provide
|
|
@@ -13,9 +12,9 @@ export class Component extends ResourceProvider {
|
|
|
13
12
|
// a Component will also construct/hydrate all its child components
|
|
14
13
|
constructor(data, path, parent, editMode) {
|
|
15
14
|
super();
|
|
16
|
-
//
|
|
15
|
+
// Properties provided during the rendering process. You do not have to provide these when
|
|
17
16
|
// building a template, but you can use them in the functions you do provide
|
|
18
|
-
this.areas = new Map();
|
|
17
|
+
this.areas = new Map(); // a Map of area names and the array of hydrated components in each
|
|
19
18
|
this.editMode = editMode;
|
|
20
19
|
this.parent = parent;
|
|
21
20
|
const { areas, ...ownData } = data;
|
|
@@ -38,10 +37,14 @@ export class Component extends ResourceProvider {
|
|
|
38
37
|
* Place any needed data into the return object, and it will be available to you as `this.fetched`
|
|
39
38
|
* during the rendering phase.
|
|
40
39
|
*
|
|
41
|
-
* Note that this.page will be available, and
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
40
|
+
* Note that `this.page` will be available, and `this.api` has dataloaded methods for retrieving
|
|
41
|
+
* data from the API if, for instance, you need to inherit information from a parent or root
|
|
42
|
+
* page. If you need to inherit and render entire components from ancestor pages,
|
|
43
|
+
* you must register them. See the comment for `this.registerInherited`
|
|
44
|
+
*
|
|
45
|
+
* Try to minimize the number of round trips you make here, make use of Promise.all and such;
|
|
46
|
+
* remember that the api functions are mostly dataloaded so calling them simultaneously is
|
|
47
|
+
* advantageous where possible.
|
|
45
48
|
*/
|
|
46
49
|
async fetch() {
|
|
47
50
|
return undefined;
|
|
@@ -79,18 +82,10 @@ export class Component extends ResourceProvider {
|
|
|
79
82
|
renderVariation(extension, renderedAreas) {
|
|
80
83
|
return Array.from(renderedAreas.values()).join('');
|
|
81
84
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
*/
|
|
87
|
-
logError(e) {
|
|
88
|
-
this.hadError = true;
|
|
89
|
-
this.passError(e, this.path);
|
|
90
|
-
}
|
|
91
|
-
// helper function for recursively passing the error up until it reaches the page
|
|
92
|
-
passError(e, path) {
|
|
93
|
-
this.parent?.passError(e, path);
|
|
85
|
+
// helper function to help you print an area, but you can also override this if you
|
|
86
|
+
// need to do something advanced like wrap each component in a div
|
|
87
|
+
renderComponents(components = [], opts) {
|
|
88
|
+
return components.flatMap(c => c.component.inheritedFrom && opts?.hideInheritBars ? [c.html] : [c.component.editBar(), c.html]).join('');
|
|
94
89
|
}
|
|
95
90
|
/**
|
|
96
91
|
* During rendering, each component should determine the CSS blocks that it needs. This may
|
|
@@ -100,6 +95,8 @@ export class Component extends ResourceProvider {
|
|
|
100
95
|
*
|
|
101
96
|
* This is evaluated after the fetch and context phases but before the rendering phase. If you
|
|
102
97
|
* need any async data to make this determination, be sure to fetch it during the fetch phase.
|
|
98
|
+
*
|
|
99
|
+
* You should check `this.editMode` if you need to load CSS that alters edit bars.
|
|
103
100
|
*/
|
|
104
101
|
cssBlocks() {
|
|
105
102
|
return Array.from(this.constructor.cssBlocks.keys());
|
|
@@ -112,21 +109,16 @@ export class Component extends ResourceProvider {
|
|
|
112
109
|
}
|
|
113
110
|
/**
|
|
114
111
|
* Components may override this function to give their edit bars a custom
|
|
115
|
-
* label instead of using the
|
|
112
|
+
* label instead of using the template name
|
|
116
113
|
*
|
|
117
114
|
* For instance, you could return this.data.title
|
|
118
115
|
*/
|
|
119
|
-
editLabel() {
|
|
120
|
-
const This = this.constructor;
|
|
121
|
-
return This.templateName;
|
|
122
|
-
}
|
|
116
|
+
editLabel() { return undefined; }
|
|
123
117
|
/**
|
|
124
118
|
* Components may override this function to give their edit bars a custom
|
|
125
119
|
* CSS class
|
|
126
120
|
*/
|
|
127
|
-
editClass() {
|
|
128
|
-
return undefined;
|
|
129
|
-
}
|
|
121
|
+
editClass() { return undefined; }
|
|
130
122
|
/**
|
|
131
123
|
* Components may override this function to give their new bars a custom
|
|
132
124
|
* label
|
|
@@ -134,26 +126,23 @@ export class Component extends ResourceProvider {
|
|
|
134
126
|
* For instance, an area that only accepts 'layout' components could
|
|
135
127
|
* return "Add Layout"
|
|
136
128
|
*/
|
|
137
|
-
newLabel(areaName) {
|
|
138
|
-
return 'Add Content';
|
|
139
|
-
}
|
|
129
|
+
newLabel(areaName) { return undefined; }
|
|
140
130
|
/**
|
|
141
131
|
* Components may override this function to give their new bars a custom
|
|
142
132
|
* CSS class
|
|
143
133
|
*/
|
|
144
|
-
newClass(areaName) {
|
|
145
|
-
return undefined;
|
|
146
|
-
}
|
|
134
|
+
newClass(areaName) { return undefined; }
|
|
147
135
|
/**
|
|
148
136
|
* Components may override this function to provide a custom edit bar
|
|
149
137
|
*
|
|
150
138
|
* Generally should not be overridden - override editLabel and editClass instead
|
|
151
139
|
*/
|
|
152
140
|
editBar(opts = {}) {
|
|
153
|
-
opts.label ?? (opts.label = this.editLabel());
|
|
141
|
+
opts.label ?? (opts.label = this.editLabel() ?? this.autoLabel);
|
|
154
142
|
opts.extraClass ?? (opts.extraClass = this.editClass());
|
|
155
|
-
opts.editMode = this.editMode;
|
|
156
|
-
|
|
143
|
+
opts.editMode ?? (opts.editMode = this.editMode);
|
|
144
|
+
opts.inheritedFrom ?? (opts.inheritedFrom = this.inheritedFrom);
|
|
145
|
+
return Component.editBar(this.path, opts);
|
|
157
146
|
}
|
|
158
147
|
/**
|
|
159
148
|
* Components may override this function to provide a custom new bar
|
|
@@ -161,10 +150,24 @@ export class Component extends ResourceProvider {
|
|
|
161
150
|
* Generally should not be overridden - override newLabel and newClass instead
|
|
162
151
|
*/
|
|
163
152
|
newBar(areaName, opts = {}) {
|
|
164
|
-
opts.label ?? (opts.label = this.newLabel(areaName));
|
|
153
|
+
opts.label ?? (opts.label = this.newLabel(areaName) ?? this.autoNewLabel);
|
|
165
154
|
opts.extraClass ?? (opts.extraClass = this.newClass(areaName));
|
|
166
|
-
opts.editMode = this.editMode;
|
|
167
|
-
|
|
155
|
+
opts.editMode ?? (opts.editMode = this.editMode);
|
|
156
|
+
opts.inheritedFrom ?? (opts.inheritedFrom = this.inheritedFrom);
|
|
157
|
+
return Component.newBar([this.path, 'areas', areaName].filter(isNotBlank).join('.'), opts);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* For logging errors during rendering without crashing the render. If your fetch, setContext,
|
|
161
|
+
* render, or renderVariation functions throw, the error will be logged but the page render will
|
|
162
|
+
* continue. You generally do not need to use this function, just throw when appropriate.
|
|
163
|
+
*/
|
|
164
|
+
logError(e) {
|
|
165
|
+
this.hadError = true;
|
|
166
|
+
this.passError(e, this.path);
|
|
167
|
+
}
|
|
168
|
+
// helper function for recursively passing the error up until it reaches the page
|
|
169
|
+
passError(e, path) {
|
|
170
|
+
this.parent?.passError(e, path);
|
|
168
171
|
}
|
|
169
172
|
}
|
|
170
173
|
export class Page extends Component {
|
package/dist/links.d.ts
CHANGED
|
@@ -63,3 +63,13 @@ export interface DataFolderLink {
|
|
|
63
63
|
path: string;
|
|
64
64
|
}
|
|
65
65
|
export declare type LinkDefinition = AssetLink | AssetFolderLink | PageLink | WebLink | DataLink | DataFolderLink;
|
|
66
|
+
/**
|
|
67
|
+
* This function is used by template definitions to help them identify links inside large blocks
|
|
68
|
+
* of text and return them for indexing, and by render definitions to help replace them with the actual URLs
|
|
69
|
+
*/
|
|
70
|
+
export declare function extractLinksFromText(text: string | undefined): LinkDefinition[];
|
|
71
|
+
/**
|
|
72
|
+
* This function is used by render definitions to replace links in large blocks with the actual
|
|
73
|
+
* URLs they point to at render time.
|
|
74
|
+
*/
|
|
75
|
+
export declare function replaceLinksInText(text: string, resolved: Map<string, string>): string;
|
package/dist/links.js
CHANGED
|
@@ -1 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
const LinkRegex = /{.*"type"\s?:\s+"\w+".*?}/g;
|
|
2
|
+
/**
|
|
3
|
+
* This function is used by template definitions to help them identify links inside large blocks
|
|
4
|
+
* of text and return them for indexing, and by render definitions to help replace them with the actual URLs
|
|
5
|
+
*/
|
|
6
|
+
export function extractLinksFromText(text) {
|
|
7
|
+
if (!text)
|
|
8
|
+
return [];
|
|
9
|
+
const matches = text.matchAll(LinkRegex);
|
|
10
|
+
return Array.from(matches).map(m => JSON.parse(m[0]));
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* This function is used by render definitions to replace links in large blocks with the actual
|
|
14
|
+
* URLs they point to at render time.
|
|
15
|
+
*/
|
|
16
|
+
export function replaceLinksInText(text, resolved) {
|
|
17
|
+
// TODO: figure out a broken link to use instead of '#', so it can be detected later
|
|
18
|
+
return text.replace(LinkRegex, m => resolved.get(m) ?? '#');
|
|
19
|
+
}
|
package/dist/render.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ContextBase, DataData, PageData } from './component.js';
|
|
1
|
+
import { ContextBase, DataData, PageData, PageRecord } from './component.js';
|
|
2
2
|
import { AssetLink, DataFolderLink, DataLink, LinkDefinition } from './links.js';
|
|
3
3
|
export declare function printHeader(ctx: ContextBase, content: string): string;
|
|
4
4
|
export declare function advanceHeader(ctx: ContextBase, content?: string): {
|
|
@@ -42,7 +42,7 @@ export interface APIClient {
|
|
|
42
42
|
*/
|
|
43
43
|
query: <T = any>(query: string, variables?: any) => Promise<T>;
|
|
44
44
|
/**
|
|
45
|
-
* This function will be provided by the rendering server and should be used inside your fetch
|
|
45
|
+
* This function will be provided by the rendering server and should be used inside your fetch
|
|
46
46
|
* method to convert a link, as input by a user, into a URL suitable for an href, or optionally
|
|
47
47
|
* an absolute URL suitable for a backend http request or non-HTML document like an RSS feed.
|
|
48
48
|
*/
|
|
@@ -61,23 +61,40 @@ export interface APIClient {
|
|
|
61
61
|
* The alt text it returns will be the default alternative text from the asset repository. Alt
|
|
62
62
|
* text gathered from a template's dialog should generally take precedence (though the dialog may
|
|
63
63
|
* preload the alt text field with the asset repository default).
|
|
64
|
+
*
|
|
65
|
+
* Will be dataloaded.
|
|
64
66
|
*/
|
|
65
67
|
getImgAttributes: (link: string | AssetLink, absolute?: boolean) => Promise<PictureAttributes>;
|
|
66
|
-
/** Get the data for a specific page.
|
|
68
|
+
/** Get the data for a specific page.
|
|
69
|
+
*
|
|
70
|
+
* Will be dataloaded.
|
|
71
|
+
*/
|
|
67
72
|
getPageData: ({ id, path }: {
|
|
68
73
|
id?: string;
|
|
69
74
|
path?: string;
|
|
70
75
|
}) => Promise<PageData>;
|
|
76
|
+
/** Get all ancestor pages of a specific page. First array element will be the pagetree root page. */
|
|
77
|
+
getAncestors: ({ id, path }: {
|
|
78
|
+
id?: string;
|
|
79
|
+
path?: string;
|
|
80
|
+
}) => Promise<PageRecord[]>;
|
|
81
|
+
/** Get the pagetree root page from which the specified page descends. */
|
|
82
|
+
getRootPageData: ({ id, path }: {
|
|
83
|
+
id?: string;
|
|
84
|
+
path?: string;
|
|
85
|
+
}) => Promise<PageData>;
|
|
71
86
|
/**
|
|
72
|
-
* Get data
|
|
87
|
+
* Get data entries by link or folder link
|
|
73
88
|
*
|
|
74
89
|
* Returns an array in case link is a DataFolderLink. If link is a DataLink, will return an
|
|
75
90
|
* array with length <= 1.
|
|
76
91
|
*/
|
|
77
92
|
getDataByLink: (link: string | DataLink | DataFolderLink) => Promise<DataData[]>;
|
|
78
93
|
/**
|
|
79
|
-
* Get data by full path including site
|
|
80
|
-
*
|
|
94
|
+
* Get data entries by full path including site
|
|
95
|
+
*
|
|
96
|
+
* Use '/global' for global data. If path refers to a specific data item, will return
|
|
97
|
+
* an array with length <= 1.
|
|
81
98
|
*/
|
|
82
99
|
getDataByPath: (templateKey: string, path: string) => Promise<DataData[]>;
|
|
83
100
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dosgato/templating",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.42",
|
|
4
4
|
"description": "A library to support building templates for dosgato CMS.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@iconify/svelte": "^2.2.1",
|
|
17
17
|
"svelte": "^3.48.0",
|
|
18
|
-
"txstate-utils": "^1.7.
|
|
18
|
+
"txstate-utils": "^1.7.4"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
|
-
"eslint-config-standard-with-typescript": "^
|
|
21
|
+
"eslint-config-standard-with-typescript": "^22.0.0",
|
|
22
22
|
"typescript": "^4.4.2"
|
|
23
23
|
},
|
|
24
24
|
"repository": {
|
package/dist/editbar.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export interface EditBarOpts {
|
|
2
|
-
extraClass?: string;
|
|
3
|
-
label?: string;
|
|
4
|
-
editMode?: boolean;
|
|
5
|
-
}
|
|
6
|
-
export declare function editBar(path: string, opts: EditBarOpts & {
|
|
7
|
-
label: string;
|
|
8
|
-
}): string;
|
|
9
|
-
export declare function newBar(path: string, opts: EditBarOpts & {
|
|
10
|
-
label: string;
|
|
11
|
-
}): string;
|
package/dist/editbar.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { htmlEncode, randomid } from 'txstate-utils';
|
|
2
|
-
export function editBar(path, opts) {
|
|
3
|
-
if (!opts.editMode)
|
|
4
|
-
return '';
|
|
5
|
-
const id = randomid();
|
|
6
|
-
return `
|
|
7
|
-
<div class="dg-edit-bar ${opts.extraClass ?? ''}" data-path="${htmlEncode(path)}" draggable="true" ondragstart="window.dgEditing.drag(event)" ondragover="window.dgEditing.over(event)" ondragend="window.dgEditing.drop(event)">
|
|
8
|
-
<span id="${id}" class="dg-edit-bar-label">${htmlEncode(opts.label)}</span>
|
|
9
|
-
<button onclick="window.dgEditing.edit(event)" aria-describedby="${id}">Edit</button>
|
|
10
|
-
<button onclick="window.dgEditing.move(event)" aria-describedby="${id}">Move</button>
|
|
11
|
-
<button onclick="window.dgEditing.del(event)" aria-describedby="${id}">Trash</button>
|
|
12
|
-
</div>
|
|
13
|
-
`.trim();
|
|
14
|
-
}
|
|
15
|
-
export function newBar(path, opts) {
|
|
16
|
-
if (!opts.editMode)
|
|
17
|
-
return '';
|
|
18
|
-
return `
|
|
19
|
-
<div role="button" onclick="window.dgEditing.create(event)" class="dg-new-bar ${opts.extraClass ?? ''}" data-path="${htmlEncode(path)}">
|
|
20
|
-
${htmlEncode(opts.label)}
|
|
21
|
-
</div>
|
|
22
|
-
`.trim();
|
|
23
|
-
}
|