A Go implementation of Shopify's Liquid template engine with full feature parity.
liquidgo/
├── .cursorrules # AI agent instructions
├── .cursor/
│ └── instructions.md # Detailed implementation guide
├── IMPLEMENTATION.md # This file
├── liquid/ # Main Go package (maps to lib/liquid/)
│ ├── tags/ # Tag implementations (maps to lib/liquid/tags/)
│ ├── tag/ # Tag base classes (maps to lib/liquid/tag/)
│ └── profiler/ # Profiler (maps to lib/liquid/profiler/)
├── reference-liquid/ # Cloned Ruby repository for reference
└── README.md # Project README
This project maintains exact file name parity with the Ruby implementation to enable easy application of changelog updates.
-
Base names match exactly (only extension changes)
- Ruby:
template.rb→ Go:template.go - Ruby:
if.rb→ Go:if.go
- Ruby:
-
Directory structure mirrors Ruby
- Ruby:
lib/liquid/tags/if.rb→ Go:liquid/tags/if.go - Ruby:
lib/liquid/tag/disableable.rb→ Go:liquid/tag/disableable.go
- Ruby:
-
Test files follow Go conventions
- Integration tests:
*_integration_test.go - Unit tests:
*_unit_test.go - Regular tests:
*_test.go
- Integration tests:
When Shopify releases a new version:
- Check
reference-liquid/History.mdfor changes - Identify affected Ruby files
- Find corresponding Go files using the same base name
- Apply equivalent changes
- Update version to match
This naming convention makes it trivial to track which files need updates.
Version numbers match the Ruby repository exactly.
- Current version: Tracked in
liquid/version.go - Maps to:
reference-liquid/lib/liquid/version.rb - Format: Semantic versioning (e.g., "5.10.0")
- When Ruby releases a new version, update Go version to match
The Ruby implementation is cloned in reference-liquid/ directory. This serves as:
- Implementation reference: Understand how features work
- Test reference: Mirror test cases
- Changelog source: Track new releases via
History.md - API reference: Maintain API compatibility
Do not modify the reference repository. It should remain a clean clone of the upstream.
Goal: Achieve 100% feature parity with Ruby implementation.
- All tags must be implemented
- All filters must be implemented
- All error modes must be supported
- All edge cases must be handled
While maintaining parity, use Go idioms:
- Structs for classes
- Interfaces for polymorphism
- Methods for behavior
- Error returns instead of exceptions
- Go naming conventions (exported = CapitalCase)
- Write tests for every feature
- Mirror Ruby test cases
- Use Go's
testingpackage - Aim for same coverage as Ruby version
- Document public APIs with Go doc comments
- Reference Ruby implementation in complex logic
- Keep this file updated with architectural decisions
-
Check for Updates
cd reference-liquid git fetch origin git log HEAD..origin/main --oneline -
Review Changelog
- Read
reference-liquid/History.md - Identify new features/fixes
- Read
-
Identify Affected Files
- Check git diff for specific changes
- Map Ruby files to Go files using naming convention
-
Implement Changes
- Read Ruby changes
- Implement equivalent Go changes
- Maintain same behavior
-
Update Version
- Update
liquid/version.goto match Ruby version - Commit with version number
- Update
-
Update Tests
- Add/modify tests as needed
- Ensure all tests pass
Ruby release 5.10.0 adds inline snippets:
- Changelog mentions
snippet.rbchanges - Map to
liquid/tags/snippet.go - Check git diff:
git show v5.10.0 -- lib/liquid/tags/snippet.rb - Implement equivalent changes
- Update version to "5.10.0"
- Add tests
- Identify Ruby file:
reference-liquid/lib/liquid/feature.rb - Create Go file:
liquid/feature.go - Read Ruby implementation thoroughly
- Implement Go equivalent
- Write tests:
liquid/feature_test.go - Verify behavior matches Ruby
- Find Ruby test:
reference-liquid/test/integration/feature_test.rb - Create Go test:
liquid/feature_integration_test.go - Translate test cases to Go
- Use Go testing patterns
- Ensure same coverage
- File name matches Ruby convention
- Implementation matches Ruby behavior
- Tests mirror Ruby tests
- Version updated if needed
- Documentation updated
- All tests pass
liquid/template.go- Main API (maps tolib/liquid/template.rb)liquid/environment.go- Configuration (maps tolib/liquid/environment.rb)liquid/parser.go- Parsing logic (maps tolib/liquid/parser.rb)liquid/lexer.go- Lexical analysis (maps tolib/liquid/lexer.rb)
liquid/tags/- All tag implementations- See
.cursor/instructions.mdfor complete mapping
liquid/*_integration_test.go- Integration testsliquid/*_unit_test.go- Unit tests
- Ruby Implementation: https://github.com/Shopify/liquid
- Liquid Documentation: https://shopify.github.io/liquid/
- Reference Code:
reference-liquid/directory - Detailed Guide:
.cursor/instructions.md
When contributing:
- Follow file naming conventions strictly
- Reference Ruby implementation
- Write comprehensive tests
- Update version if needed
- Document any deviations
This project follows the same license as the Ruby implementation (MIT).