Skip to content

5. Custom Templates

Cesar Parra edited this page Dec 16, 2025 · 1 revision

Custom Templates Guide

Introduction

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.

Setting up Custom Templates

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',
    // ...
  }
});

Limitations

Custom templates are currently only available for the Markdown documentation endpoint. The OpenAPI and changelog generators do not support custom templates at this time.

Template Types

ApexDocs supports two types of custom templates:

1. String Templates (Handlebars Syntax)

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}}`
  }
});

2. Function Templates (JavaScript/TypeScript)

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;
    }
  }
});

Template Configuration Structure

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.

Template Helpers

ApexDocs provides a set of helper functions that you can use in both string and function templates:

Available Helpers

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)

Helper Details

renderContent(content: RenderableContent[])

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}}

heading(level: number, text: string)

Creates Markdown headings at the specified level (1-6).

// Creates "## Section Title"
helpers.heading(2, 'Section Title');

inlineCode(text: string)

Wraps text in backticks for inline code formatting.

// Creates "`String`"
helpers.inlineCode('String');

splitAndCapitalize(text: string)

Converts camelCase or PascalCase strings to readable text.

// Converts "renderableClass" to "Renderable Class"
helpers.splitAndCapitalize('renderableClass');

Importing TemplateHelpers

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.

Accessing the Helpers Object

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');

Using Helpers in Custom Functions

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;
    }
  }
});

Example Reference

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