> For the complete documentation index, see [llms.txt](https://triton.pharos.ai/pharos-triton/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://triton.pharos.ai/pharos-triton/triton-best-practices/templates-and-builder-pattern.md).

# Templates & the Builder Pattern

## Why Templates Matter

* **Always prefer** `TritonBuilder` + **template cloning** over convenience helpers.
* **Why:** Templates standardize category, type, area, base details, and reduce copy/paste drift.

## Apex – Set & Reuse a Template

```apex
// Early in the transaction (e.g., controller entry, batch start)
Triton.instance.setTemplate(
    Triton.makeBuilder()
        .category(TritonTypes.Category.Apex)
        .level(TritonTypes.Level.DEBUG)
        .type(TritonTypes.Type.Backend)
        .area(TritonTypes.Area.OpportunityManagement) // agreed taxonomy
);

// Later: clone and specialize
Triton.instance.log(
    Triton.instance.fromTemplate()
        .level(TritonTypes.Level.INFO)
        .summary('Opportunity sync started')
        .details('seed=nightly, source=ERP')
);
```

## LWC – Component-Scoped Template

```js
import Triton, { LEVEL, TYPE, AREA } from 'c/triton';

const triton = new Triton().bindToComponent('c-opp-sync'); // scopes component details

triton.setTemplate(
  triton.makeBuilder()
    .type(TYPE.FRONTEND)
    .area(AREA.OPPORTUNITY_MANAGEMENT)
);

// Usage later:
triton.log(
  triton.fromTemplate()
    .summary('Button clicked')
    .details('action=sync-all')
);
```

## Real-World Example: Customer Service Portal

```js
// Customer service LWC component with comprehensive template
export default class CustomerServicePortal extends LightningElement {
    triton;
    
    connectedCallback() {
        this.triton = new Triton().bindToComponent('c-customer-service-portal');
        
        // Set comprehensive template for all customer service operations
        this.triton.setTemplate(
            this.triton.makeBuilder()
                .type(TYPE.FRONTEND)
                .area(AREA.COMMUNITY)
                .level(LEVEL.INFO)
                .relatedObjects([this.recordId])
        );
    }
    
    async handleCaseCreation() {
        try {
            const result = await createCase({ caseData: this.caseForm });
            
            // Uses template, adds specific details
            this.triton.log(
                this.triton.fromTemplate()
                    .summary('Case created successfully')
                    .details(JSON.stringify({ 
                        caseId: result.Id, 
                        priority: this.caseForm.priority,
                        category: this.caseForm.category 
                    }))
                    .relatedObjects([result.Id])
            );
            
        } catch (error) {
            // Template properties preserved in error logs
            this.triton.logNow(
                this.triton.fromTemplate()
                    .exception(error)
                    .summary('Case creation failed')
            );
        }
    }
}
```

## Template Benefits

### Consistency

* All logs in a method/component share the same base properties
* Reduces the risk of inconsistent categorization
* Ensures proper context across all log entries

### Maintainability

* Changes to common properties only need to be made in one place
* Reduces code duplication and drift
* Makes updates and refactoring easier

### Reduced Errors

* No risk of forgetting to set important properties
* Template ensures all required fields are populated
* Consistent structure across all logging calls

### Performance

* Template cloning is efficient
* Reduces object creation overhead
* Maintains singleton pattern benefits

## Template Override Pattern

Show how to override template properties when needed:

```apex
// Template sets common properties
Triton.instance.setTemplate(
    Triton.makeBuilder()
        .category(TritonTypes.Category.Apex)
        .type(TritonTypes.Type.Backend)
        .area(TritonTypes.Area.Accounts)
        .relatedObject(accountId)
);

// Override specific properties as needed
Triton.instance.log(
    Triton.instance.fromTemplate()
        .level(TritonTypes.Level.INFO)        // Override level
        .summary('Account processed')         // Add specific summary
        .details('status=completed')          // Add specific details
        .duration(processingTime)             // Add duration
        .relatedObjects(new Set<Id>{contactId}) // Override related objects
);
```

## Best Practices

### Do's

* ✅ Clone from `fromTemplate()` to get a pre-filled builder and add specifics
* ✅ Set templates early in methods/components
* ✅ Use templates for all logging calls within a scope
* ✅ Override only what's specific to each log entry

### Don'ts

* ❌ Call `addEvent/addDebug` directly in new code
* ❌ Use `makeBuilder()` for every log entry
* ❌ Forget to set templates in new methods
* ❌ Override template properties unnecessarily

## Template Scoping

### Method-Level Templates

```apex
public void processAccount(Id accountId) {
    // Set template for this method
    Triton.instance.setTemplate(
        Triton.makeBuilder()
            .category(TritonTypes.Category.Apex)
            .type(TritonTypes.Type.Backend)
            .area(TritonTypes.Area.Accounts)
            .relatedObject(accountId)
    );
    
    // All logs in this method use the template
    Triton.instance.log(Triton.instance.fromTemplate().summary('Processing started'));
    // ... processing logic ...
    Triton.instance.log(Triton.instance.fromTemplate().summary('Processing completed'));
}
```

### Component-Level Templates

```js
export default class AccountManager extends LightningElement {
    triton;
    
    connectedCallback() {
        this.triton = new Triton().bindToComponent('c-account-manager');
        
        // Set template for entire component
        this.triton.setTemplate(
            this.triton.makeBuilder()
                .type(TYPE.FRONTEND)
                .area(AREA.ACCOUNTS)
                .relatedObjects([this.recordId])
        );
    }
    
    // All methods in this component can use the template
    async handleSave() {
        this.triton.log(this.triton.fromTemplate().summary('Save initiated'));
        // ... save logic ...
    }
    
    async handleDelete() {
        this.triton.log(this.triton.fromTemplate().summary('Delete initiated'));
        // ... delete logic ...
    }
}
```

## Advanced Template Patterns

### Conditional Template Properties

```apex
// Set base template
Triton.instance.setTemplate(
    Triton.makeBuilder()
        .category(TritonTypes.Category.Apex)
        .type(TritonTypes.Type.Backend)
        .area(TritonTypes.Area.Accounts)
);

// Add conditional properties
if (isHighPriority) {
    Triton.instance.log(
        Triton.instance.fromTemplate()
            .level(TritonTypes.Level.WARNING)
            .summary('High priority account processed')
    );
} else {
    Triton.instance.log(
        Triton.instance.fromTemplate()
            .level(TritonTypes.Level.INFO)
            .summary('Standard account processed')
    );
}
```

### Template Inheritance

```apex
// Base template for all account operations
Triton.instance.setTemplate(
    Triton.makeBuilder()
        .category(TritonTypes.Category.Apex)
        .type(TritonTypes.Type.Backend)
        .area(TritonTypes.Area.Accounts)
);

// Specialize for specific operations
public void processHighValueAccount(Id accountId) {
    // Override template for this specific operation
    Triton.instance.setTemplate(
        Triton.instance.fromTemplate()
            .level(TritonTypes.Level.WARNING)
            .relatedObject(accountId)
    );
    
    // All logs in this method inherit the specialized template
    Triton.instance.log(Triton.instance.fromTemplate().summary('High value processing started'));
}
```

By mastering the template pattern, you'll create logging code that is consistent, maintainable, and efficient while providing rich context for all your log entries.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://triton.pharos.ai/pharos-triton/triton-best-practices/templates-and-builder-pattern.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
