Skip to content

Commit 300ee29

Browse files
committed
feat: v-html-editor: extractVariables
1 parent b9f0a58 commit 300ee29

File tree

2 files changed

+40
-15
lines changed

2 files changed

+40
-15
lines changed

modules/v-html-editor/runtime/composables/useHtmlRenderer.ts

+7-15
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { defu } from 'defu';
22
import { create as createHbInstance } from 'handlebars';
3+
import { getHandlebarsVariables } from '../utils/handlebars';
34

4-
export type VHtmlRuntimeVariableDefinition = string;
55
export type VHtmlVariableGroup = Record<string | number | symbol, any>;
6+
export type VHtmlTemplate = string;
67
export type VHtmlRendererConfig = {
78
/**
89
* Set of static variables that are available before-hand (while designing).
@@ -11,13 +12,6 @@ export type VHtmlRendererConfig = {
1112
*/
1213
staticVariables: any;
1314

14-
/**
15-
* Set of variable definitions that are available during
16-
* runtime. They will be filled during runtime and will be available in
17-
* the runtime. Fake values can be used during design time.
18-
*/
19-
runtimeVariableDefinitions: VHtmlRuntimeVariableDefinition[];
20-
2115
/**
2216
* Set of known helpers that can be used in the template.
2317
*/
@@ -45,14 +39,8 @@ export function useHtmlRenderer(config: VHtmlRendererConfig) {
4539
});
4640

4741
const staticVariables = config.staticVariables;
48-
const runtimeVariableDefinitions = config.runtimeVariableDefinitions;
4942

5043
const render = (template: string, runtimeVars: VHtmlVariableGroup) => {
51-
const missingVars = runtimeVariableDefinitions.filter((key) => !runtimeVars[key]);
52-
if (missingVars.length > 0) {
53-
throw new Error(`Missing runtime variables: ${missingVars.join(', ')}`);
54-
}
55-
5644
const mergedVars = defu(runtimeVars, staticVariables);
5745
const compiledTemplate = hb.compile(template, {
5846
data: true,
@@ -66,5 +54,9 @@ export function useHtmlRenderer(config: VHtmlRendererConfig) {
6654
return compiledTemplate(mergedVars);
6755
};
6856

69-
return { render };
57+
const extractVariables = (template: string) => {
58+
return getHandlebarsVariables(template);
59+
};
60+
61+
return { render, extractVariables };
7062
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { parseWithoutProcessing } from 'handlebars';
2+
import type { VHtmlTemplate } from '../composables/useHtmlRenderer';
3+
4+
const getVariablesFromStatementsRecursive = (statements: hbs.AST.Statement[]): string[] => {
5+
return statements.reduce<string[]>((acc, statement) => {
6+
const { type } = statement;
7+
8+
if ('BlockStatement' === type) {
9+
const { inverse, program } = statement as hbs.AST.BlockStatement;
10+
11+
if (program.body) {
12+
acc = acc.concat(getVariablesFromStatementsRecursive(program.body));
13+
}
14+
15+
if (inverse.body) {
16+
acc = acc.concat(getVariablesFromStatementsRecursive(inverse.body));
17+
}
18+
} else if ('MustacheStatement' === type) {
19+
const { path } = statement as hbs.AST.MustacheStatement;
20+
21+
if (path.type === 'PathExpression') {
22+
const pathExpression = path as hbs.AST.PathExpression;
23+
acc.push(pathExpression.original);
24+
}
25+
}
26+
return acc;
27+
}, []);
28+
};
29+
30+
export const getHandlebarsVariables = (input: VHtmlTemplate) => {
31+
const ast = parseWithoutProcessing(input);
32+
return getVariablesFromStatementsRecursive(ast.body);
33+
};

0 commit comments

Comments
 (0)