Thank you for your interest in contributing to Templify! We welcome contributions from the community and appreciate your efforts to improve this project.
- Code of Conduct
- How Can I Contribute?
- Development Setup
- Development Guidelines
- Documentation
- Additional Resources
This project and everyone participating in it is governed by our Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to the project maintainers.
Before creating bug reports, please check existing issues to avoid duplicates. When creating a bug report, include as many details as possible:
Bug Report Checklist:
- Clear, descriptive title - Summarize the problem in one sentence
- Steps to reproduce - Detailed steps to reproduce the issue
- Expected behavior - What you expected to happen
- Actual behavior - What actually happened
- Environment details:
- Templify version
- .NET version
- Operating system
- Any relevant configuration
- Sample code/template - Minimal code to reproduce the issue (if applicable)
- Error messages - Full stack traces or error messages
Example:
## Bug: Placeholder not replaced in nested table cells
**Steps to reproduce:**
1. Create a Word template with a table containing nested tables
2. Add placeholder `{{CompanyName}}` in the nested table cell
3. Process template with data containing CompanyName
**Expected:** Placeholder should be replaced with actual value
**Actual:** Placeholder remains unchanged
**Environment:**
- Templify: 1.0.0
- .NET: 9.0
- OS: Windows 11
**Sample code:** [link or inline code]Enhancement suggestions are tracked as GitHub issues. When creating an enhancement suggestion:
- Use a clear, descriptive title
- Provide detailed description of the proposed enhancement
- Explain the use case - Why is this enhancement needed?
- Describe alternatives - Have you considered alternative solutions?
- Provide examples - Show how the feature would be used
We actively welcome pull requests! To increase the likelihood of your PR being accepted:
- Discuss first - For major changes, open an issue first to discuss your proposal
- Follow guidelines - Adhere to our coding standards and conventions
- Write tests - Maintain 100% test coverage
- Update documentation - Keep docs in sync with code changes
- Keep it focused - One feature/fix per PR
Pull Request Process:
- Fork the repository and create your branch from
main - Make your changes following our development guidelines
- Add tests for any new functionality
- Ensure all tests pass (
dotnet test) - Update documentation (README.md, ARCHITECTURE.md, etc.) if needed
- Commit your changes using our commit message format
- Push to your fork and submit a pull request
- Link relevant issues in your PR description
PR Title Format:
Add feature X
Fix bug in Y
Update documentation for Z
PR Description Template:
## Summary
Brief description of what this PR does
## Changes
- Bullet point list of changes
- Another change
## Related Issues
Fixes #123
Relates to #456
## Testing
- [ ] All existing tests pass
- [ ] New tests added for new functionality
- [ ] Manual testing completed
## Documentation
- [ ] README.md updated (if needed)
- [ ] Code comments added/updated
- [ ] ARCHITECTURE.md updated (if needed)We follow the Conventional Commits specification for commit messages. This leads to more readable commit history and enables automated changelog generation.
<type>(<scope>): <description>
[optional body]
[optional footer(s)]
Types that appear in CHANGELOG:
feat:- New feature → Goes in "Added" sectionfix:- Bug fix → Goes in "Fixed" sectionperf:- Performance improvement → Goes in "Performance" or "Changed" section- Breaking changes: Add
BREAKING CHANGE:in commit body → Goes in "Breaking Changes" section
Types for internal changes (NOT in CHANGELOG):
docs:- Documentation changes onlystyle:- Code formatting, whitespace, missing semicolonsrefactor:- Code restructuring without changing behaviortest:- Adding or updating testschore:- Maintenance tasks, dependency updatesci:- CI/CD configuration changesbuild:- Build system or tooling changes
The scope provides additional context:
feat(loops):- Loop-related featurefix(placeholders):- Placeholder bug fixdocs(contributing):- Contributing documentationci(workflow):- Workflow configuration
# Feature with body
feat: add support for custom date format specifiers
Implements #42
# Bug fix
fix: resolve placeholder replacement in nested table cells
Fixes #38
# Documentation
docs(readme): update installation instructions
# Breaking change
feat!: change placeholder syntax to use curly braces
BREAKING CHANGE: Placeholder syntax changed from {{var}} to ${var}.
Update all templates before upgrading.
# Multiple changes
feat(conditionals): add support for 'or' operator in conditions
- Implements logical OR operator
- Updates conditional evaluator
- Adds comprehensive tests- Choose the appropriate type based on your change
- If type is
feat,fix,perf, or breaking change:- Also update
CHANGELOG.mdin the[Unreleased]section - Ensure commit description matches changelog entry
- Also update
- Write clear, descriptive commit messages
- Use present tense: "add feature" not "added feature"
- Be specific: "fix date formatting in German locale" not "fix bug"
- Reference issues in commit body or footer
| Commit Type | CHANGELOG Section | Required |
|---|---|---|
feat: |
### Added |
Yes |
fix: |
### Fixed |
Yes |
perf: |
### Performance or ### Changed |
Yes |
BREAKING CHANGE: |
### Breaking Changes |
Yes |
docs:, style:, refactor:, etc. |
Not included | No |
- .NET 9.0 SDK or later - Download
- Git - Download
- IDE (optional but recommended):
- Visual Studio 2022
- JetBrains Rider
- Visual Studio Code with C# extension
# Clone the repository
git clone https://github.com/TriasDev/templify.git
cd templify
# Restore dependencies
dotnet restore templify.sln
# Build the solution
dotnet build templify.sln
# Run tests
dotnet test TriasDev.Templify.Tests/TriasDev.Templify.Tests.csproj
# Run tests with coverage
dotnet test --collect:"XPlat Code Coverage"templify/
├── TriasDev.Templify/ # Core library
├── TriasDev.Templify.Tests/ # Test suite (690+ tests)
├── TriasDev.Templify.Gui/ # GUI application
├── TriasDev.Templify.Converter/# CLI converter tool
├── TriasDev.Templify.Benchmarks/# Performance benchmarks
└── TriasDev.Templify.Demo/ # Demo console application
# Run demo application
dotnet run --project TriasDev.Templify.Demo/TriasDev.Templify.Demo.csproj
# Run GUI application
dotnet run --project TriasDev.Templify.Gui/TriasDev.Templify.Gui.csproj
# Run benchmarks
dotnet run --project TriasDev.Templify.Benchmarks/TriasDev.Templify.Benchmarks.csproj -c Release
# Run converter tool
dotnet run --project TriasDev.Templify.Converter/TriasDev.Templify.Converter.csproj -- [command] [args]We follow standard C# coding conventions. The repository includes an .editorconfig file that automatically enforces these conventions in most modern IDEs (Visual Studio, VS Code, Rider, etc.). Your editor should automatically apply these settings when you open the project.
Key guidelines:
Naming Conventions:
- Private fields:
_camelCase(with underscore prefix) - Public properties:
PascalCase - Local variables:
camelCase - Constants:
PascalCase - Methods:
PascalCase - Interfaces:
IPascalCase(with I prefix)
Code Organization:
- One class per file (except for closely related nested types)
- Namespace matches folder structure
- Group members by type: fields → constructors → properties → methods
- Order by visibility: public → internal → private
Code Quality:
- Use nullable reference types -
<Nullable>enable</Nullable>is enabled - Check for null before processing nullable values
- Avoid magic numbers - Use named constants
- Keep methods focused - Single Responsibility Principle
- Prefer composition over inheritance
- Use meaningful names - Code should be self-documenting
XML Documentation:
- Add XML documentation to all public APIs
- Document parameters, return values, and exceptions
- Internal classes: document where complexity warrants explanation
- Complex algorithms: add inline comments explaining "why" not "what"
Example:
/// <summary>
/// Processes a Word document template by replacing placeholders with actual values.
/// </summary>
/// <param name="templateStream">The input template stream.</param>
/// <param name="outputStream">The output stream for the processed document.</param>
/// <param name="data">The data dictionary containing replacement values.</param>
/// <returns>A <see cref="ProcessingResult"/> indicating success or failure.</returns>
/// <exception cref="ArgumentNullException">Thrown when any parameter is null.</exception>
public ProcessingResult ProcessTemplate(Stream templateStream, Stream outputStream, Dictionary<string, object> data)
{
// Implementation
}We maintain 100% test coverage. All contributions must include tests.
Testing Guidelines:
-
Unit Tests - Test individual components in isolation
- Location:
TriasDev.Templify.Tests/ - Use xUnit framework
- Mock dependencies where appropriate
- Location:
-
Integration Tests - Test end-to-end scenarios
- Location:
TriasDev.Templify.Tests/Integration/ - Process actual Word documents
- Verify output using
DocumentVerifierhelper
- Location:
-
Test Naming Convention:
[Fact] public void MethodName_Scenario_ExpectedBehavior() { // Arrange // Act // Assert }
-
Test Organization:
- Arrange - Set up test data and dependencies
- Act - Execute the code under test
- Assert - Verify expected outcomes
-
Coverage Requirements:
- 100% line coverage for new code
- 100% branch coverage for new code
- Run:
dotnet test --collect:"XPlat Code Coverage"
Example Test:
[Fact]
public void ProcessTemplate_ValidTemplate_ReplacesPlaceholders()
{
// Arrange
var builder = new DocumentBuilder();
builder.AddParagraph("Hello {{Name}}!");
var templateStream = builder.ToStream();
var data = new Dictionary<string, object>
{
["Name"] = "World"
};
var processor = new DocumentTemplateProcessor();
var outputStream = new MemoryStream();
// Act
var result = processor.ProcessTemplate(templateStream, outputStream, data);
// Assert
Assert.True(result.IsSuccess);
using var verifier = new DocumentVerifier(outputStream);
Assert.Contains("Hello World!", verifier.GetParagraphText(0));
}Use clear, imperative commit messages that explain what and why (not how).
Format:
<type>: <subject>
<body>
<footer>
Type:
Add- New feature or functionalityFix- Bug fixUpdate- Enhancement to existing featureRemove- Code/feature removalRefactor- Code restructuring without behavior changeDocs- Documentation changesTest- Test additions or modificationsChore- Maintenance tasks (dependencies, configs, etc.)
Subject Line:
- Use imperative mood ("Add feature" not "Added feature")
- Don't capitalize first letter (unless proper noun)
- No period at the end
- Limit to 72 characters
Body (optional):
- Explain what and why, not how
- Wrap at 72 characters
- Separate from subject with blank line
Footer (optional):
- Reference issues:
Fixes #123orRelates to #456 - Breaking changes:
BREAKING CHANGE: description
Examples:
Simple:
Add support for array indexing in placeholders
With body:
Fix placeholder replacement in nested tables
Placeholders in nested table cells were not being detected due to
incorrect table traversal logic. Updated DocumentWalker to recursively
process nested tables.
Fixes #42
Multiple changes:
Add markdown formatting support
Changes:
- Implement MarkdownParser to detect markdown syntax
- Update PlaceholderVisitor to apply markdown formatting
- Add FormattingPreserver.ApplyMarkdownFormatting() method
- Support for bold, italic, strikethrough, and combined styles
- Add 15 integration tests for markdown features
Relates to #5
Use descriptive branch names that indicate the purpose of the changes.
Format:
<type>/<short-description>
Types:
feature/- New featuresfix/- Bug fixesdocs/- Documentation changesrefactor/- Code refactoringtest/- Test additions/modificationschore/- Maintenance tasks
Examples:
feature/add-array-indexing
fix/nested-table-placeholders
docs/update-api-reference
refactor/visitor-pattern
test/add-loop-coverage
chore/update-dependencies
Guidelines:
- Use lowercase with hyphens
- Keep it short but descriptive
- Don't use issue numbers alone (e.g., avoid
fix/123) - Branch from
mainfor new work - Delete branch after PR is merged
Update documentation when you:
- Add new features - Document in README.md, Examples.md, and docs/
- Change public APIs - Update API reference and XML comments
- Modify architecture - Update ARCHITECTURE.md
- Add complex logic - Add inline code comments
- Fix bugs - Update troubleshooting sections if applicable
Repository Documentation:
- README.md - Project overview, getting started
- TriasDev.Templify/README.md - API reference, usage guide
- TriasDev.Templify/Examples.md - Comprehensive code examples
- TriasDev.Templify/ARCHITECTURE.md - Design patterns, technical decisions
- CLAUDE.md - Development guide for contributors
User Documentation (docs/ folder):
- docs/quick-start.md - Quick start guide
- docs/tutorials/ - Step-by-step tutorials
- docs/guides/ - Feature guides
- docs/FAQ.md - Frequently asked questions
XML Documentation:
- All public APIs must have XML documentation comments
- XML comments are automatically generated into
.xmlfiles for IntelliSense - Run
dotnet buildto verify XML comment validity
We use DocFX to generate our documentation website.
Preview Documentation Locally:
# Build the library (generates XML docs)
dotnet build TriasDev.Templify/TriasDev.Templify.csproj -c Release
# Install DocFX (one-time setup)
dotnet tool install -g docfx
# Generate API metadata
docfx metadata docfx_project/docfx.json
# Build the documentation site
docfx build docfx_project/docfx.json
# Serve locally (view at http://localhost:8080)
docfx serve _siteDocumentation Workflow:
- Make changes to markdown files in
docs/or XML comments in code - Build and preview locally to verify changes
- Submit PR - documentation is automatically deployed on merge to
main - View live site at https://triasdev.github.io/templify/
Adding New Documentation:
- Place user-facing docs in
docs/folder - Add entries to
docfx_project/articles/toc.ymlfor navigation - Follow existing structure and formatting
- Clear and concise - Avoid jargon where possible
- Use examples - Show, don't just tell
- Keep updated - Docs should match current code
- Use proper markdown - Follow CommonMark specification
- Add code samples - Include runnable examples where applicable
We maintain a changelog following the Keep a Changelog format in CHANGELOG.md.
Update CHANGELOG.md for every PR that changes functionality:
- ✅ New features (even small ones)
- ✅ Bug fixes
- ✅ API changes
- ✅ Performance improvements
- ✅ Breaking changes
- ❌ Documentation-only changes (optional)
- ❌ Internal refactoring with no user impact (optional)
During Development:
- Add your changes to the
[Unreleased]section - Use the appropriate category:
- Added - New features
- Changed - Changes in existing functionality
- Deprecated - Soon-to-be removed features
- Removed - Removed features
- Fixed - Bug fixes
- Security - Vulnerability fixes
Example Entry:
## [Unreleased]
### Added
- Support for custom date formats in placeholders (#42)
### Fixed
- Placeholder replacement in nested table cells (#38)On Release:
Maintainers will:
- Move
[Unreleased]items to a new version section - Add the release date
- Update version links at the bottom
- Create a git tag matching the version
Example:
## [Unreleased]
## [1.1.0] - 2025-11-25
### Added
- Support for custom date formats in placeholders (#42)
[Unreleased]: https://github.com/TriasDev/templify/compare/v1.1.0...HEAD
[1.1.0]: https://github.com/TriasDev/templify/releases/tag/v1.1.0- Write for users, not developers - Focus on impact, not implementation
- Use present tense - "Add support for..." not "Added support for..."
- Be specific - "Fix date formatting in German locale" not "Fix bug"
- Group related changes - Combine similar items into one bullet
- Link to issues - Use issue numbers for context (#123)
- CLAUDE.md - Comprehensive development guide
- ARCHITECTURE.md - Architecture and design patterns
- PERFORMANCE.md - Performance considerations
- Examples.md - 1,900+ lines of examples
- GitHub Issues - Ask questions, report bugs
- GitHub Discussions - Community discussions
- Email - Contact maintainers for sensitive issues
Templify prioritizes:
- Simplicity - Focus on common use cases
- Maintainability - Small, composable classes with single responsibilities
- Testability - Pure functions, dependency injection, 100% test coverage
- Explicit behavior - No magic, predictable results
- Fail-fast - Clear error messages, no silent failures
Contributors will be recognized in:
- GitHub contributors list
- Release notes - Major contributions highlighted
- CHANGELOG.md - Credit for significant features/fixes
If you have questions about contributing, feel free to:
- Open a discussion on GitHub Discussions
- Ask in an issue - We're happy to help!
- Check CLAUDE.md - Detailed development guide
Thank you for contributing to Templify! Your efforts help make document templating easier for the entire .NET community. 🎉