Skip to content

Instantly share code, notes, and snippets.

@iNewLegend
Last active May 1, 2023 11:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iNewLegend/9f4c2403c9857a3ce0369063d24a4ccb to your computer and use it in GitHub Desktop.
Save iNewLegend/9f4c2403c9857a3ce0369063d24a4ccb to your computer and use it in GitHub Desktop.
Parse template
// Copyrights Leonid Vinikov <leonidvinikov@gmail.com>
export const UI_TEMPLATE_WRAPPER_START = "{",
UI_TEMPLATE_WRAPPER_END = "}";
export const uiUtilsWrapAsTemplate = ( template: string ): string => {
return UI_TEMPLATE_WRAPPER_START + template + UI_TEMPLATE_WRAPPER_END;
};
const UI_TEMPLATE_VAR_WRAPPER_REGEX = new RegExp( UI_TEMPLATE_WRAPPER_START + "(.+?)" + UI_TEMPLATE_WRAPPER_END, "g" );
type KeyValue = { [ key: string | number ]: any };
/**
* UITemplateBase is an abstract class that provides methods to replace template variables with corresponding
* data values from objects, as well as extract variables from template options based on template logic.
*/
export abstract class TemplateBase {
/**
* Function composeTemplate() :: Returns a new object with template variables replaced with the corresponding
* data values from the data object and options object.
*/
protected composeTemplate( template: KeyValue, data: KeyValue, options: KeyValue ): KeyValue {
const parsedData = { ... data, ... this.extractVariablesFromTemplateLogic( data, options ) };
return this.compileTemplate( template, parsedData );
}
/**
* Function compileTemplate() :: Returns a new object with template variables replaced with the
* corresponding data values from the variables object.
*/
private compileTemplate( template: KeyValue, variables: KeyValue ): KeyValue {
const result = {} as KeyValue;
for ( const key in template ) {
if ( template.hasOwnProperty( key ) ) {
const value = template[ key ];
result[ key ] = this.replaceTemplateVariables( value, variables );
}
}
return result;
}
/**
* Function extractVariablesFromTemplateLogic() :: Returns an object containing variables extracted from the
* templateOptions object based on the values in the templateLogic object.
*/
private extractVariablesFromTemplateLogic( templateLogic: KeyValue, templateOptions: KeyValue ): KeyValue {
const variables = templateOptions,
appliedVariables = {} as KeyValue;
// Construct the variables according to template inputs.
for ( const variableName in variables ) {
const variableContext = variables[ variableName ];
if ( "object" === typeof variableContext ) {
/**
* variableContext
* {
* "{value}": "{limitValue}",
* "{unlimited}": "Unlimited"
* }
*
* templateLogic
* {
* "name": "test",
* "limit": "{value}",
* "state": "{private}",
* "limitValue": 1
* }
*/
// eg: appliedVariables[ "limit" ] = "{limitValue}";
appliedVariables[ variableName ] = variableContext[ templateLogic[ variableName ] ];
} else if ( "string" === typeof variableContext ) {
appliedVariables[ variableName ] = variables[ variableName ];
} else {
throw new Error( "Invalid variable object" );
}
}
return appliedVariables;
}
/**
* Function replaceTemplateVariables() :: Recursively replaces template variables in a string or object with
* their corresponding values from the variables object.
*/
private replaceTemplateVariables( templateVariable: any, variables: KeyValue ): any {
if ( "string" === typeof templateVariable ) {
return templateVariable.replace( UI_TEMPLATE_VAR_WRAPPER_REGEX, ( match, p1 ) => {
const replaced = variables[ p1 ];
// Skip if the variable is not defined.
if ( "undefined" === typeof replaced ) {
return match;
} else if ( "object" === typeof replaced ) {
return JSON.stringify( replaced );
}
return this.replaceTemplateVariables( variables[ p1 ], variables );
} );
}
return templateVariable;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment