Thank you for your interest in contributing to TinyTemplateEngine! We welcome contributions from the community.
Before contributing, please understand our core principles:
- Keep it Tiny - The core library stays minimal with zero unnecessary dependencies
- Data-First - Templates are projections of data, not views or applications
- Explicit over Implicit - Clear, predictable behavior without magic
- Extensibility through Services - Complex features via opt-in Template Services
- .NET SDK 8.0, 9.0, or 10.0
- Git
- Your favorite IDE (Visual Studio, VS Code, Rider)
# Clone the repository
git clone https://github.com/lowlandtech/tinytools.git
cd tinytools
# Restore dependencies
dotnet restore
# Build the project
dotnet build
# Run tests
dotnet test- Check existing issues - Someone may have already reported it
- Use the issue template - Provide as much detail as possible
- Include reproduction steps - Help us reproduce the issue
- Add code samples - Minimal, complete examples are best
- Open a discussion first - Discuss your idea before coding
- Align with philosophy - Ensure it fits the "tiny" principle
- Consider Template Services - Can it be a service instead of core feature?
- Provide use cases - Real-world examples help
- Fork the repository
- Create a feature branch -
git checkout -b feature/amazing-feature - Make your changes
- Follow existing code style
- Add/update tests
- Update documentation
- Commit your changes - Use clear, descriptive commit messages
- Push to your fork -
git push origin feature/amazing-feature - Open a Pull Request - Fill in the PR template
- C# 12 features - Use modern C# idioms
- Nullable reference types - Always enabled
- XML documentation - Public APIs must be documented
- Keep methods focused - Single responsibility principle
- Avoid complexity - Prefer clarity over cleverness
- Test coverage - All new features must have tests
- Use descriptive names -
ItShouldPluralizeUsingHumanizerService - Follow AAA pattern - Arrange, Act, Assert
- One assertion per test - Keep tests focused
- Test edge cases - Null, empty, invalid inputs
Example test:
[Fact]
public void ItShouldHandleNullInput()
{
// Arrange
var context = new ToolContext();
context.RegisterService("test", input => input?.ToString() ?? "default");
// Act
var result = engine.Render("${Context.Services('test')(null)}", context);
// Assert
result.Should().Contain("default");
}tinytools/
├── src/
│ └── lowlandtech.tinytools/ # Core library
│ ├── TinyTemplateEngine.cs # Main engine
│ ├── ToolContext.cs # Template context
│ ├── VariableResolver.cs # Expression resolver
│ ├── TemplateHelpers.cs # Built-in helpers
│ └── ITemplateService.cs # Service interface
├── test/
│ └── lowlandtech.tinytools.unittests/ # Unit tests
├── samples/
│ └── README.md # Service examples
├── .github/
│ └── workflows/ # CI/CD pipelines
└── readme.md # Main documentation
- Sync with main -
git pull origin main - Create feature branch - Descriptive name
- Write failing test - TDD approach preferred
- Implement feature - Make test pass
- Refactor - Clean up code
- Update docs - README, samples, XML docs
- Push and PR - Submit for review
- New features - Always document
- Breaking changes - Migration guide required
- Bug fixes - If behavior changes
- Examples - Real-world use cases welcome
- readme.md - User-facing documentation
- XML comments - API documentation
- samples/ - Usage examples
- changelog.md - Version history
When adding Template Services examples:
- Keep them simple - Clear, focused functions
- Show both registrations - Code and usage
- Add to samples/README.md - Comprehensive guide
- Include tests - Working examples
By contributing, you agree that your contributions will be licensed under the MIT License.
- Be respectful and inclusive
- Welcome newcomers
- Focus on constructive feedback
- Assume positive intent
- GitHub Discussions - Ask questions
- Issues - Report bugs
- Twitter - @wendellmva
Contributors will be acknowledged in:
- Release notes
- README contributors section
- Package metadata (where applicable)
Thank you for helping make TinyTemplateEngine better! 🎉