-
-
Notifications
You must be signed in to change notification settings - Fork 24
5. Custom Templates
ApexDocs provides a powerful custom template system that allows you to completely customize the output format of your generated documentation. With custom templates, you can:
- Define your own Markdown structure and styling
- Control exactly what information appears in the documentation
- Add custom sections, formatting, or metadata
- Create documentation that matches your team's style guide
Custom templates give you full control over how your Apex classes, interfaces, enums, triggers, LWC components, custom objects, and reference guides are rendered as markdown documentation.
To use custom templates in ApexDocs, you need to define them in your config file (e.g. apexdocs.config.ts,
apexdocs.config.js). The templates property allows you to specify custom templates for different renderable types,
such as classes, interfaces, enums, triggers, LWCs, custom objects, and the reference guide.
Example Configuration:
import { defineMarkdownConfig } from '@cparra/apexdocs';
export default defineMarkdownConfig({
templates: {
class: 'example template for classes',
interface: 'example template for interfaces',
// ...
}
});Custom templates are currently only available for the Markdown documentation endpoint. The OpenAPI and changelog generators do not support custom templates at this time.
ApexDocs supports two types of custom templates:
String templates use Handlebars syntax and are defined as template literals. They're great for simple templates where you want declarative control over the output.
Example:
import { defineMarkdownConfig } from '@cparra/apexdocs';
export default defineMarkdownConfig({
templates: {
class: `# {{name}}
{{renderContent description}}
{{#if methods.length}}
## Methods
{{#each methods}}
### {{name}}
{{renderContent description}}
{{/each}}
{{/if}}`
}
});Function templates are TypeScript/JavaScript functions that receive the renderable data and template helpers. They offer full programmatic control and type safety.
Example:
import { defineMarkdownConfig } from '@cparra/apexdocs';
import type { RenderableClass, TemplateHelpers } from '@cparra/apexdocs';
export default defineMarkdownConfig({
templates: {
class: (renderable: RenderableClass, helpers: TemplateHelpers) => {
const { heading, renderContent } = helpers;
let output = `${heading(1, renderable.name)}\n\n`;
// Add custom logic here
return output;
}
}
});The templates configuration object accepts templates for different renderable types:
type TemplateConfig = {
class?: string | ((renderable: RenderableClass, helpers: TemplateHelpers) => string);
interface?: string | ((renderable: RenderableInterface, helpers: TemplateHelpers) => string);
enum?: string | ((renderable: RenderableEnum, helpers: TemplateHelpers) => string);
trigger?: string | ((renderable: RenderableTrigger, helpers: TemplateHelpers) => string);
lwc?: string | ((renderable: RenderableLwc, helpers: TemplateHelpers) => string);
customObject?: string | ((renderable: RenderableCustomObject, helpers: TemplateHelpers) => string);
referenceGuide?: string | ((data: ReferenceGuideData, helpers: TemplateHelpers) => string);
};You can define templates for some or all of these types. When a template isn't provided for a specific type, ApexDocs will use its default template for that type.
ApexDocs provides a set of helper functions that you can use in both string and function templates:
| Helper | Description | String Template Usage | Function Template Usage |
|---|---|---|---|
link |
Creates markdown links | {{link source}} |
helpers.link(source) |
code |
Renders code blocks | {{code codeBlock}} |
helpers.code(codeBlock) |
renderContent |
Renders renderable content to markdown | {{renderContent content}} |
helpers.renderContent(content) |
heading |
Creates markdown headings | {{heading level text}} |
helpers.heading(level, text) |
inlineCode |
Wraps text in inline code formatting | {{inlineCode text}} |
helpers.inlineCode(text) |
eq |
Equality comparison | {{eq a b}} |
helpers.eq(a, b) |
add |
Addition | {{add a b}} |
helpers.add(a, b) |
lookup |
Array element access | {{lookup array index}} |
helpers.lookup(array, index) |
parseJSON |
JSON parsing | {{parseJSON jsonString}} |
helpers.parseJSON(jsonString) |
startsWith |
String prefix check | {{startsWith str prefix}} |
helpers.startsWith(str, prefix) |
substring |
String extraction | {{substring str start length}} |
helpers.substring(str, start, length) |
splitAndCapitalize |
Splits camelCase and capitalizes | {{splitAndCapitalize text}} |
helpers.splitAndCapitalize(text) |
Converts structured content (text, code blocks, links, etc.) into Markdown. This is essential for rendering descriptions that may contain formatting.
// In a function template
const description = helpers.renderContent(renderable.doc.description);
// In a string template
{{renderContent doc.description}}Creates Markdown headings at the specified level (1-6).
// Creates "## Section Title"
helpers.heading(2, 'Section Title');Wraps text in backticks for inline code formatting.
// Creates "`String`"
helpers.inlineCode('String');Converts camelCase or PascalCase strings to readable text.
// Converts "renderableClass" to "Renderable Class"
helpers.splitAndCapitalize('renderableClass');ApexDocs exports all template helpers as a utility object that you can import and use in your own code. This is particularly useful when you want to reuse the same formatting logic outside of templates, or when you need to create custom helper functions that build upon the built-in helpers.
import { templateHelpers } from '@cparra/apexdocs';
// Use individual helpers
const heading = templateHelpers.heading(2, 'Section Title');
const inlineCode = templateHelpers.inlineCode('myVariable');
const formattedText = templateHelpers.splitAndCapitalize('apexClassName');You can combine the built-in helpers with your own logic to create more complex formatting functions:
import { templateHelpers } from '@cparra/apexdocs';
function formatMethodSignature(methodName: string, parameters: any[], returnType: string) {
const { inlineCode } = templateHelpers;
let signature = `${inlineCode(methodName)}(`;
if (parameters.length > 0) {
signature += parameters.map(p => `${inlineCode(p.name)}: ${p.type}`).join(', ');
}
signature += `): ${returnType}`;
return signature;
}
// Usage in a template
export default defineMarkdownConfig({
templates: {
class: (renderable, helpers) => {
let output = '';
renderable.methods.forEach(method => {
output += formatMethodSignature(method.name, method.parameters, method.returnType);
});
return output;
}
}
});A comprehensive example of custom templates is available in the ApexDocs repository:
Location: examples/markdown-custom-templates/
To run the example:
cd examples/markdown-custom-templates
npm install
npm run docs:gen