Release Notes - v2.3.0
Release Date: February 2026
Summary
v2.3.0 introduces the Template / Mail Merge engine — a new pkg/template/ package for document template processing. This release adds placeholder detection, data merging, batch document generation, custom delimiter support, and full MERGEFIELD compatibility with real Microsoft Word templates.
New Features
Template / Mail Merge Engine (pkg/template/)
A complete template processing package with zero external dependencies:
MergeTemplate()— Replace{{placeholder}}tokens with data values while preserving all formattingFindPlaceholders()/PlaceholderNames()— Detect all placeholders across body, tables, headers, and footersValidateTemplate()— Check for missing or unused data keys before mergingConsolidateRuns()— Merge adjacent runs with identical formatting to heal split placeholders- Custom Delimiters — Support for
${key},«key», or any custom open/close delimiter pair - Strict Mode — Optional error reporting for missing keys during merge
- Batch Merge — Generate multiple documents from a single template with different data sets
MERGEFIELD Support
Full compatibility with Microsoft Word's native mail merge fields:
- Reads Word MERGEFIELD instructions from
.docxtemplates - Correctly handles Word's two-run MERGEFIELD pattern (field instruction + display text)
- Supports
«guillemet»delimiters used by Word's mail merge UI - Tested with real production Word templates
Paragraph Mutation APIs
Paragraph.ClearRuns()— Remove all runs from a paragraphParagraph.RemoveRun(index)— Remove a specific run by indexParagraph.InsertRunAt(index)— Insert a new run at a specific position
Run Content Inspection
Run.Fields()— Access field instructions in a runRun.Breaks()— Access break elements in a runRun.Image()— Access embedded image in a runRun.ClearFields()— Clear field instructions from a run
New Examples
- Example 14: Mail merge invoice template with batch generation (programmatic)
- Example 15: External Word template with real MERGEFIELDs and
«»delimiters
Bug Fixes
- Phantom Header/Footer References — Fixed
walkParagraphs()callingsection.Header()which auto-creates headers/footers on sections that don't have them, causing "Word found unreadable content" errors. Now uses read-onlyHeadersAll()/FootersAll()methods. - MERGEFIELD Text Duplication — Fixed issue where MERGEFIELD display text was duplicated after merge because the field instruction in the preceding run continued to emit the original placeholder. Now clears fields from the preceding run when replacing MERGEFIELD text.
Installation
go get github.com/mmonterroca/docxgo/v2@v2.3.0Usage Examples
Basic Template Merge
import (
docx "github.com/mmonterroca/docxgo/v2"
"github.com/mmonterroca/docxgo/v2/pkg/template"
)
doc := docx.NewDocument()
para, _ := doc.AddParagraph()
run, _ := para.AddRun()
run.SetText("Hello {{name}}, welcome to {{company}}!")
data := template.MergeData{
"name": "John",
"company": "Acme Corp",
}
err := template.MergeTemplate(doc, data)
// MergeTemplate modifies the document in place
doc.SaveAs("output.docx")External Word Template with MERGEFIELDs
doc, _ := docx.OpenDocument("template.docx")
opts := template.MergeOptions{
OpenDelimiter: "«",
CloseDelimiter: "»",
}
data := template.MergeData{
"Contact_FullName": "Jane Doe",
"Account_Name": "Acme Corp",
}
err := template.MergeTemplate(doc, data, opts)
// MergeTemplate modifies the document in place
doc.SaveAs("merged_output.docx")Batch Merge
records := []template.MergeData{
{"name": "John Smith", "amount": "$1,500.00"},
{"name": "Alice Johnson", "amount": "$2,300.00"},
}
for i, data := range records {
doc, _ := docx.OpenDocument("invoice_template.docx")
template.MergeTemplate(doc, data)
doc.SaveAs(fmt.Sprintf("invoice_%d.docx", i+1))
}Files Added
pkg/template/doc.go— Package documentationpkg/template/merge.go— Core merge logicpkg/template/merge_test.go— Merge testspkg/template/placeholder.go— Placeholder detectionpkg/template/placeholder_test.go— Placeholder testspkg/template/consolidate.go— Run consolidationpkg/template/consolidate_test.go— Consolidation testspkg/template/format.go— Run formatting comparison helperpkg/template/options.go— MergeData, MergeOptions, ValidationError typespkg/template/walk.go— Document traversalpkg/template/integration_test.go— Integration testsexamples/14_mail_merge/main.go— Programmatic template exampleexamples/15_external_template/main.go— External Word template example
Files Modified
domain/paragraph.go— AddedClearRuns(),RemoveRun(),InsertRunAt()domain/run.go— AddedFields(),Breaks(),Image(),ClearFields()internal/core/paragraph.go— Implemented paragraph mutation methodsinternal/core/run.go— Implemented run content inspection andClearFields()
Test Coverage
- 41 new tests across the
pkg/template/package - All existing tests continue to pass
- Tested with real Microsoft Word templates containing MERGEFIELDs
Acknowledgements
This release represents the biggest feature addition since the v2.0.0 rewrite, adding a complete template engine while maintaining the library's zero-dependency philosophy.