A modern, high-performance PHP template resolver with entity-based processing, hierarchical fallback, and multi-language support. Perfect for e-commerce marketplaces, multi-tenant applications, and any system requiring flexible template management.
- Entity-Based Processing: Extract data from objects using reflection
- Hierarchical Template Fallback:
{context}_template.txtβtemplate.txt - Multi-Language Support: Automatic language detection from entity properties
- Advanced Template Syntax: Variables, conditionals, loops, and nested data access
- Performance Optimized: In-memory caching for templates and entity structures
- Modern PHP 8.4+: Full type safety with strict typing
- Factory Pattern: Multiple pre-configured resolver instances
- Marketplace Ready: Optimized for e-commerce integrations
composer require four-bytes/four-template-resolveruse Four\TemplateResolver\TemplateResolverFactory;
// Create resolver with template directory
$resolver = TemplateResolverFactory::createWithDirectory('/path/to/templates');
// Simple template resolution
$result = $resolver->resolve('greeting', ['name' => 'World']);
// Output: Content from greeting.txt with {{name}} replaced
// Entity-based resolution
$product = new Product('Cool Item', 19.99);
$description = $resolver->resolveFromEntity('item_description', $product);// Optimized for e-commerce marketplaces
$resolver = TemplateResolverFactory::createForMarketplaces('/templates');
// Hierarchical fallback: amazon_item_description.txt β item_description.txt
$amazonListing = $resolver->resolveFromEntity('item_description', $product, 'amazon');
// Automatic language detection
$customer = new Customer('Hans', 'MΓΌller', 'DEU');
$comment = $resolver->resolveFromEntity('order_comment', $customer);
// Uses order_comment_german.txt automaticallyThe resolver extracts data from objects using reflection, analyzing getter methods to create template variables:
class Product
{
public function getName(): string { return 'Cool Product'; }
public function getPrice(): float { return 29.99; }
public function getReleaseDate(): DateTime { return new DateTime(); }
}
// Automatically extracts: name, price, releaseDate
$resolver->resolveFromEntity('template', $product);Templates follow a hierarchical resolution pattern:
Templates Directory:
βββ amazon_item_description.txt β Used for context 'amazon'
βββ ebay_item_description.txt β Used for context 'ebay'
βββ item_description.txt β Default fallback
$resolver->resolve('item_description', $data, 'amazon');
// 1. Tries amazon_item_description.txt
// 2. Falls back to item_description.txtAutomatic language detection from entity properties:
class Customer
{
public function getCountry(): string { return 'DEU'; }
}
// Automatically detects German and uses template_german.txt
$resolver->resolveFromEntity('template', $customer);Default Mappings:
DEU,AUT,CHEβ German- All others β English
Hello {{name}}! Your order {{orderId}} is ready.
{{#if premium}}Welcome Premium Member!{{/if}}
{{#if description}}Description: {{description}}{{/if}}
Tags: {{#each tags}}{{value}}, {{/each}}
Tracks:
{{#each tracks}}
{{index}}. {{title}} ({{duration}})
{{/each}}
Customer: {{customer.name}} ({{customer.address.country}})
// Basic resolver
$resolver = TemplateResolverFactory::createWithDirectory('/templates');
// Strict mode (throws exceptions on missing templates)
$resolver = TemplateResolverFactory::createStrict('/templates');
// European marketplace optimized
$resolver = TemplateResolverFactory::createEuropean('/templates');
// Includes: German, French, Italian, Spanish, Dutch, Polish mappings
// Development (no caching, strict errors)
$resolver = TemplateResolverFactory::createForDevelopment('/templates');
// Production (caching enabled, graceful errors)
$resolver = TemplateResolverFactory::createForProduction('/templates');use Four\TemplateResolver\Configuration\LanguageMapping;
use Four\TemplateResolver\Configuration\TemplateConfiguration;
$languageMapping = new LanguageMapping([
'FRA' => 'french',
'DEU' => 'german',
'ESP' => 'spanish'
], 'english');
$config = new TemplateConfiguration(
templateDirectory: '/templates',
enableCaching: true,
templateExtension: '.txt',
strictMode: false,
languageMapping: $languageMapping
);
$resolver = new TemplateResolver($config);Basic variable replacement using {{variable}} syntax:
Product: {{name}}
Price: {{formattedPrice}}
Released: {{releaseDate}}
Show content based on variable truthiness:
{{#if onSale}}
π₯ SPECIAL OFFER: Save {{discount}}%!
{{/if}}
{{#if description}}
Description: {{description}}
{{/if}}
Truthy values: Non-empty strings, numbers β 0, true, non-empty arrays
Falsy values: null, '', '0', 0, false, empty arrays
Iterate over arrays:
Features:
{{#each features}}
- {{value}}
{{/each}}
Track Listing:
{{#each tracks}}
{{index}}. {{title}} - {{duration}}
{{/each}}
Loop variables:
{{value}}- Item value (for simple arrays){{index}}- Current index- All item properties (for object arrays)
Access nested properties with dot notation:
Customer: {{customer.fullName}}
Address: {{customer.address.street}}, {{customer.address.city}}
Order Total: {{order.total.formatted}}
Template: amazon_item_description.txt
π΅ {{name}} π΅
Artist: {{artist}}
Format: {{format}}
Release Date: {{releaseDate}}
Price: {{formattedPrice}}
{{#if description}}
{{description}}
{{/if}}
{{#if tags}}
Tags: {{#each tags}}#{{value}} {{/each}}
{{/if}}
Perfect for music lovers and collectors!
Template: ebay_item_description.txt
π₯ AUCTION: {{name}} π₯
π΅ Artist: {{artist}}
π
Release: {{releaseDate}}
πΏ Format: {{format}}
π° Price: {{formattedPrice}}
π DESCRIPTION:
{{description}}
β‘ Fast shipping worldwide!
π‘οΈ 100% authentic merchandise
Don't miss this opportunity!
Template: order_comment_german.txt
Danke fΓΌr Ihre {{marketplace}}-Bestellung!
{{#if customerName}}
Liebe/r {{customerName}},
{{/if}}
Ihre Bestellung wurde erfolgreich bearbeitet.
Mit freundlichen GrΓΌΓen
Template: order_comment_english.txt
Thank you for your {{marketplace}} order!
{{#if customerName}}
Dear {{customerName}},
{{/if}}
Your order has been successfully processed.
Best regards
$stats = $resolver->getCacheStats();
echo "Template Cache Entries: {$stats['template_cache']['entries']}\n";
echo "Template Cache Hits: {$stats['template_cache']['total_hits']}\n";
echo "Entity Types Cached: {$stats['entity_cache']['entities']}\n";// Clear all caches
$resolver->clearCache();
// Disable caching (for development)
$resolver = TemplateResolverFactory::createWithoutCaching('/templates');
// Check cache status
$isEnabled = $resolver->getConfiguration()->enableCaching;- Use caching in production - Significant performance boost
- Cache entity structures - Reflection analysis is expensive
- Minimize template complexity - Simple templates are faster
- Batch operations - Process multiple items with same templates
- Pre-register dynamic templates - Avoid repeated registrations
Run the test suite:
# Install dependencies
composer install
# Run tests
composer test
# Run tests with coverage
composer test-coverage
# Run quality checks
composer quality- Unit tests for all core components
- Integration tests for marketplace scenarios
- Performance tests for caching efficiency
- Mock servers for realistic testing
$config = new TemplateConfiguration(
templateDirectory: '/path/to/templates', // Required
enableCaching: true, // Enable template caching
templateExtension: '.txt', // Template file extension
strictMode: false, // Throw on missing templates
languageMapping: $languageMapping // Country->language mapping
);// Default German/English mapping
$mapping = LanguageMapping::germanEnglish();
// European marketplace mapping
$mapping = LanguageMapping::european();
// Custom mapping
$mapping = new LanguageMapping([
'FRA' => 'french',
'ITA' => 'italian',
'ESP' => 'spanish'
], 'english');use Four\TemplateResolver\Exception\TemplateNotFoundException;
use Four\TemplateResolver\Exception\InvalidTemplateException;
use Four\TemplateResolver\Exception\EntityExtractionException;
try {
$result = $resolver->resolveFromEntity('template', $entity);
} catch (TemplateNotFoundException $e) {
// Template file not found
} catch (InvalidTemplateException $e) {
// Template syntax error
} catch (EntityExtractionException $e) {
// Entity data extraction failed
}Strict Mode (Development):
- Throws exceptions on missing templates
- Better error reporting
- Fails fast on issues
Non-Strict Mode (Production):
- Returns empty strings for missing templates
- Graceful degradation
- Continues operation despite errors
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
git clone https://github.com/four-bytes/four-template-resolver
cd four-template-resolver
composer install
composer testThis project is licensed under the MIT License - see the LICENSE file for details.
Four Template Resolver is developed by 4 Bytes, specialists in modern PHP solutions and e-commerce integrations.
Contact: info@4bytes.de
Added:
- Entity-based template processing with reflection
- Hierarchical template fallback system
- Multi-language support with automatic detection
- Advanced template syntax (variables, conditionals, loops)
- Performance-optimized caching system
- Factory pattern with pre-configured resolvers
- Comprehensive test suite with 95%+ coverage
- Professional documentation and examples
Features:
- PHP 8.4+ compatibility with strict typing
- PSR-12 compliant code
- PHPStan level 8 analysis
- Marketplace-optimized configurations
- European language mappings
- Development/production modes
Made with β€οΈ by the team at 4 Bytes