liveBook · Manning

Template function

As explained in Building User-Friendly DSLs

A function that generates source code from fixed text and information extracted from an abstract syntax tree.

A template function generates source code by combining fixed text with information extracted from an abstract syntax tree. JavaScript ES2015 template literals provide embedded expressions for this work. section 8.5

Template functions can return nested strings: strings and arbitrarily nested arrays of strings. This structure replaces explicit concatenation and newline joining, making composed templates easier to read while preserving generated formatting. section 8.4.2

A practical composition pattern is:

  • Return fixed source fragments and mapped template results in an array. section 8.4.2
  • Pass AST-derived values such as names, attributes, or business-rule state into subordinate templates. section 14.3.3
  • Flatten and join the outer result with an asString utility that ensures newlines. section 8.4.2

Generating a form field

A formField template function receives an attribute and its affected status, delegates to formFieldInputs, and emits a FormField wrapper. The generated UI can therefore switch affected attributes from inputs to display fields. section 14.3.3

const indexJsx = (recordType) => { 
    const name = ccNameOf(recordType)     #1
    const ucName = withFirstUpper(name)        #2
    const { attributes } = recordType.settings     #3

    return [                            #4
        `import React from "react" 
import { createRoot } from "react-dom/client" 
import { makeAutoObservable } from "mobx" 
import { observer } from "mobx-react" 

import { FormField, Input } from "./components" 
import { DateRange } from "./dates" 

require("./styling.css") 

class ${ucName} {`,              #5
        attributes.map((attribute) => 
            `    ${initializationFor(attribute)}`),     #6
        `constructor() {                       #7
        makeAutoObservable(this) 
    } 
} 

// ...rest of the code... 

createRoot(document.getElementById("root")) 
    .render( 
        <RentalForm rental={rental} /> 
    ) 
` 
    ]        #8
}

Inspect the indexJsx template’s array-shaped return value, including generated imports, mapped attributes, and fixed source fragments. section 8.4.2

How Building User-Friendly DSLs covers it

How deep it goes
Explains composition, nested-string representation, flattening, and newline handling, but defers broader formatter design.
Examples
Uses indexJsx generation, mapped attributes, asString conversion, and business-rule-aware form-field templates.
What it assumes
Assumes an abstract syntax tree and JavaScript template literals, then develops nested strings for composition.
What you can do after
Builds readable template functions that compose nested strings and emit properly formatted generated source.
How it connects
Connects template functions with ASTs, code generators, nested strings, JavaScript template literals, and code formatting.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Building User-Friendly DSLs. The section links point to the parts of the book it draws on.