Wiki source code of Front-end macros API
Last modified by superadmin on 2026/07/29 16:53
Show last authors
| author | version | line-number | content |
|---|---|---|---|
| 1 | == Defining a macro == | ||
| 2 | |||
| 3 | A macro is described by the ##Macro## type, which is the union of ##BlockMacro## and ##InlineMacro##. | ||
| 4 | Every macro provides: | ||
| 5 | |||
| 6 | * ##infos## - the macro metadata (see ##MacroInfos##). | ||
| 7 | * ##renderAs## - ##"block"## or ##"inline"##.MacroLinkTarget | ||
| 8 | * ##render(params, rawBody)## - a function returning the rendering AST. | ||
| 9 | |||
| 10 | {{code language="typescript"}} | ||
| 11 | import type { | ||
| 12 | BlockMacro, | ||
| 13 | MacroBlock, | ||
| 14 | MacroParameterType, | ||
| 15 | } from "@xwiki/platform-macros-api"; | ||
| 16 | |||
| 17 | // Parameter definitions. | ||
| 18 | const params = { | ||
| 19 | message: { type: "string" }, | ||
| 20 | } satisfies Record<string, MacroParameterType>; | ||
| 21 | |||
| 22 | // A block macro rendering its "message" parameter as a paragraph. | ||
| 23 | class InfoMacro implements BlockMacro<typeof params> { | ||
| 24 | readonly infos = { | ||
| 25 | id: "info", | ||
| 26 | name: "Information", | ||
| 27 | description: "Displays a message.", | ||
| 28 | params, | ||
| 29 | paramsDescription: { message: "The message to display." }, | ||
| 30 | defaultParameters: { message: "" }, | ||
| 31 | bodyType: "none", | ||
| 32 | } as const; | ||
| 33 | |||
| 34 | readonly renderAs = "block" as const; | ||
| 35 | |||
| 36 | render(params: { message: string }): MacroBlock[] { | ||
| 37 | return [ | ||
| 38 | { | ||
| 39 | type: "paragraph", | ||
| 40 | styles: {}, | ||
| 41 | content: [{ type: "text", content: params.message, styles: {} }], | ||
| 42 | }, | ||
| 43 | ]; | ||
| 44 | } | ||
| 45 | } | ||
| 46 | {{/code}} | ||
| 47 | |||
| 48 | Macros are made available to the front-end by registering them with the Macros Service. See [[Service API>>documentation.xs.dev.front-end.macros.service-api.WebHome]]. | ||
| 49 | |||
| 50 | === MacroInfos === | ||
| 51 | |||
| 52 | Metadata describing a macro. | ||
| 53 | |||
| 54 | |=Field|=Type|=Description | ||
| 55 | |##id##|##string##|The macro identifier. Only lowercase letters, uppercase letters, digits, and underscores are allowed. | ||
| 56 | |##name##|##string##|Human-readable name, shown in menus. | ||
| 57 | |##description##|##string##|Description of the macro. | ||
| 58 | |##params##|##Record<string, MacroParameterType>##|The macro's parameter definitions. | ||
| 59 | |##paramsDescription##|record of ##string##|A human-readable description for each parameter. | ||
| 60 | |##defaultParameters##|concrete parameters or ##false##|Default parameter values used when inserting the macro. ##false## hides the macro. When ##bodyType## is ##"raw"##, a dialog box is shown to insert the macro. | ||
| 61 | |##bodyType##|##"none"##, ##"wysiwyg"## or ##"raw"##|Whether the macro has a body and how it is edited: ##"none"## (no body), ##"wysiwyg"## (WYSIWYG-editable body), ##"raw"## (editable but not WYSIWYG). | ||
| 62 | |||
| 63 | === BlockMacro === | ||
| 64 | |||
| 65 | A macro that renders as a block. | ||
| 66 | |||
| 67 | |=Member|=Type|=Description | ||
| 68 | |##infos##|##MacroInfos##|The macro metadata. | ||
| 69 | |##renderAs##|##"block"##|Indicates that the macro renders as a block. | ||
| 70 | |##render(params, rawBody)##|##MacroBlock[]##|Renders the macro. ##params## are the (concrete) parameter values; optional fields may be absent or ##undefined##. ##rawBody## is the raw body string when ##bodyType## is ##"raw"##, otherwise ##null##. | ||
| 71 | |||
| 72 | === InlineMacro === | ||
| 73 | |||
| 74 | A macro that renders as inline content. | ||
| 75 | |||
| 76 | |=Member|=Type|=Description | ||
| 77 | |##infos##|##MacroInfos##|The macro metadata. | ||
| 78 | |##renderAs##|##"inline"##|Indicates that the macro renders as inline content. | ||
| 79 | |##render(params, rawBody)##|##MacroInlineContent[]##|Renders the macro (see ##render## in ##BlockMacro## for the parameters). | ||
| 80 | |||
| 81 | === Macro types === | ||
| 82 | |||
| 83 | |=Type|=Description | ||
| 84 | |##Macro<Parameters>##|A macro: either a ##BlockMacro## or an ##InlineMacro##. | ||
| 85 | |##MacroWithUnknownParamsType##|A ##Macro## whose parameter shape is unknown. Used by generic code such as the Macros Service. | ||
| 86 | |##MacroClassWithUnknownParamsType##|Constructor type for an instantiable macro with an unknown parameter shape. | ||
| 87 | |||
| 88 | == Macro parameters == | ||
| 89 | |||
| 90 | === MacroParameterType === | ||
| 91 | |||
| 92 | The definition of a single macro parameter. | ||
| 93 | |||
| 94 | {{code language="typescript"}} | ||
| 95 | type MacroParameterType = ( | ||
| 96 | | { type: "boolean" } | ||
| 97 | | { type: "float" } | ||
| 98 | | { type: "string" } | ||
| 99 | ) & { optional?: true }; | ||
| 100 | {{/code}} | ||
| 101 | |||
| 102 | The concrete TypeScript type of a parameter is derived from this definition: ##"boolean"## maps to ##boolean##, ##"float"## to ##number## (##"float"## is used instead of ##"number"## to be more explicit for developers) and ##"string"## to ##string##. Setting ##optional## to ##true## makes the parameter optional. | ||
| 103 | |||
| 104 | === Parameter type helpers === | ||
| 105 | |||
| 106 | Advanced type-level helpers, mostly used internally to derive concrete parameter types. | ||
| 107 | |||
| 108 | |=Type|=Description | ||
| 109 | |##UnknownMacroParamsType##|Generic record of a macro's runtime parameter values (##Record<string, boolean ~| number ~| string>##). | ||
| 110 | |##GetConcreteMacroParameterType<T>##|Derives the concrete TypeScript type of a single parameter from its ##MacroParameterType## definition. | ||
| 111 | |##GetConcreteMacroParametersType<T>##|Derives the concrete parameters record type from a parameters definition; optional parameters become optional properties. | ||
| 112 | |##FilterUndefined<T>##|Removes the properties that may be assigned ##undefined## from a record. | ||
| 113 | |##UndefinableToOptional<T>##|Makes the properties that may be assigned ##undefined## optional in a record. | ||
| 114 | |||
| 115 | == Rendering AST == | ||
| 116 | |||
| 117 | The ##render## function returns an array of AST nodes: block macros return ##MacroBlock[]## and inline macros return ##MacroInlineContent[]##. | ||
| 118 | |||
| 119 | === MacroBlock === | ||
| 120 | |||
| 121 | A block-level AST node, discriminated by its ##type##. | ||
| 122 | |||
| 123 | |=##type##|=Description|=Key fields | ||
| 124 | |##"paragraph"##|A paragraph of inline content|##content##, ##styles## | ||
| 125 | |##"heading"##|A heading|##level## (1 to 6), ##content##, ##styles## | ||
| 126 | |##"list"##|A bullet or numbered list|##items##, optional ##numbered##, ##styles## | ||
| 127 | |##"quote"##|A block quote|##content## (nested blocks), ##styles## | ||
| 128 | |##"code"##|A code block|##content## (string), optional ##language## | ||
| 129 | |##"table"##|A table|##columns##, ##rows##, ##styles## | ||
| 130 | |##"image"##|An image (see ##MacroImage##)|##target##, optional ##alt##, ##widthPx##, ##heightPx## | ||
| 131 | |##"macroBlock"##|A nested block macro reference|##name##, ##params## | ||
| 132 | |##"rawHtml"##|A raw HTML block|##html## | ||
| 133 | |##"macroBlockEditableArea"##|Editable-area placeholder for a block macro body|##styles## | ||
| 134 | |||
| 135 | === MacroInlineContent === | ||
| 136 | |||
| 137 | An inline AST node, discriminated by its ##type##. | ||
| 138 | |||
| 139 | |=##type##|=Description|=Key fields | ||
| 140 | |##"text"##|Styled text (see ##MacroText##)|##content##, ##styles## | ||
| 141 | |##"link"##|A link (see ##MacroLink##)|##target##, ##content## | ||
| 142 | |##"rawHtml"##|Raw inline HTML|##html## | ||
| 143 | |##"inlineMacro"##|A nested inline macro reference|##name##, ##params## | ||
| 144 | |##"inlineMacroEditableArea"##|Editable-area placeholder for an inline macro body|(none) | ||
| 145 | |||
| 146 | === Supporting AST types === | ||
| 147 | |||
| 148 | |=Type|=Description | ||
| 149 | |##MacroText##|A text node: ##content## (string) and ##styles## (##MacroTextStyles##). | ||
| 150 | |##MacroTextStyles##|Optional text styling: ##bold##, ##italic##, ##strikethrough##, ##underline##, ##code##, ##textColor##, ##backgroundColor##. | ||
| 151 | |##MacroBlockStyles##|Optional block styling: ##cssClasses##, ##textColor##, ##backgroundColor##, ##textAlignment## (##MacroAlignment##). | ||
| 152 | |##MacroAlignment##|One of ##"left"##, ##"center"##, ##"right"##, ##"justify"##. | ||
| 153 | |##MacroListItem##|A list item: ##content##, ##styles##, optional ##checked##. | ||
| 154 | |##MacroImage##|An ~[~[image~:~]~] ##target## (##MacroLinkTarget##), optional ##alt##, ##widthPx##, ##heightPx##. | ||
| 155 | |##MacroLink##|A link: ##target## (##MacroLinkTarget##) and ##content## (inline content, excluding nested links). | ||
| 156 | |##MacroLinkTarget##|Either ##{ type: "internal", rawReference }## or ##{ type: "external", url }##. | ||
| 157 | |##MacroTableColumn##|A table column: optional ##headerCell## (##content## + ##styles##) and ##widthPx##. | ||
| 158 | |##MacroTableCell##|A table cell: ##content##, ##styles##, optional ##rowSpan##, ##colSpan##. | ||
| 159 | |||
| 160 | == Functions == | ||
| 161 | |||
| 162 | === eraseParamsTypeForMacroClass(macro) === | ||
| 163 | |||
| 164 | Casts a typed macro class to a ##MacroClassWithUnknownParamsType##, dropping its parameter shape. This is useful when macros with different parameter shapes need to be handled together, for example | ||
| 165 | when registering them. | ||
| 166 | |||
| 167 | {{code language="typescript"}} | ||
| 168 | function eraseParamsTypeForMacroClass< | ||
| 169 | Params extends Record<string, MacroParameterType>, | ||
| 170 | >( | ||
| 171 | macro: new (...args: any[]) => Macro<Params>, | ||
| 172 | ): MacroClassWithUnknownParamsType; | ||
| 173 | {{/code}} | ||
| 174 | |||
| 175 | |=Parameter|=Type|=Description | ||
| 176 | |##macro##|macro class|The macro class to cast. | ||
| 177 | |||
| 178 | Returns the same macro class, retyped without its parameter shape. |