This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Latte Tools is a library for converting PHP templates and Twig templates to Latte (Nette's templating engine). The project provides two main converters:
- PhpConverter: Transforms PHP templates with echo statements into Latte syntax
- TwigConverter: Transforms Twig templates into Latte templates
The project includes "Twiggy" - a complete custom implementation of the Twig parser/compiler (~4,650 lines of code) that allows parsing Twig templates without depending on the actual Twig library.
# Run all tests
composer run tester
# Run a specific test file directly
php tests/PhpTest.php
php tests/TwigTest.php
# Run static analysis
composer run phpstan
# Convert a PHP file to Latte
php php-to-latte.php input.php [output.latte]
# Convert a Twig file to Latte
php twig-to-latte.php input.twig [output.latte]The PHP converter uses nikic/php-parser to parse and transform PHP code through multiple AST transformation passes:
- Parse: PHP code → AST using nikic/php-parser
- Transform (multiple passes):
expandEcho(): Splitecho a, b;→echo a; echo b;removeHtmlSpecialChars(): Remove redundanthtmlspecialchars()calls (runs twice)expandConcat(): Expand string concatenations for better Latte outputstringToHtml(): Convert literal strings to inline HTML
- Print: Use custom
LattePrinter(extends nikic's PrettyPrinter) to output Latte syntax
Key class: src/PhpConverter.php - orchestrates the transformation pipeline
The Twig converter uses the custom Twiggy parser implementation:
- Initialize: Set up Twiggy environment with extensions (Cache, Html, Debug, Sandbox)
- Parse: Twig template → AST using Twiggy lexer/parser
- Transform:
LatteNodeVisitorwalks the AST converting Twig constructs to Latte - Compile: Generate Latte output
- Post-process: Pattern replacements (e.g.,
class="{html_classes(...)}"→n:class="...")
Key classes:
src/TwigConverter.php: Main converter orchestrationsrc/Twiggy/: Complete Twig parser implementationEnvironment.php: Twig environment setupLexer.php: TokenizationParser.php: AST generationCompiler.php: Compilation logicNodeVisitor/LatteNodeVisitor.php: Twig→Latte AST transformation
Twiggy is organized into several subsystems:
- Core parsing:
Lexer.php,Parser.php,Compiler.php - Node types:
Node/directory contains all AST node types (expressions, statements, operators) - Extensions:
Extension/provides Core, Debug, Escaper, Optimizer, Sandbox functionality - Token parsers:
TokenParser/handles parsing of specific Twig tags (if, for, block, etc.) - Node visitors:
NodeVisitor/for AST transformation and optimization - Loaders:
Loader/for template loading (ArrayLoader used for conversion) - Extra features:
Extra/for Cache and HTML support
src/LattePrinter.php extends nikic/php-parser's PrettyPrinterAbstract to customize PHP AST printing for Latte output. This is where PHP syntax gets transformed into Latte template syntax during the printing phase.
Tests use fixture-based comparison:
- Each test has paired input/output files (
.php/.latteor.twig/.latte) - Test runners iterate through fixtures, convert, and compare output using
Assert::match() - Fixtures are organized by category in
tests/fixtures-php/andtests/fixtures-twig/
Fixture categories for Twig:
expressions/: Expression syntax testsfilters/: Filter conversion testsfunctions/: Function conversion testsmacros/: Macro conversion teststags/: Tag conversion tests (if, for, block, extends, etc.)tests/: Test expression tests
Adding new test cases:
- Create input file (
.phpor.twig) in appropriate fixtures directory - Create expected output file (
.latte) with same name - Run tests - the test runner automatically picks up new fixtures
- PHP 8.0+ with
declare(strict_types=1)in every file - Follows Nette Coding Standard (PSR-12 based)
- Use TABS for indentation
- Type declarations required for all properties, parameters, and return values
- PHPStan static analysis enforced
Core:
nikic/php-parser(^4.10): AST parsing for PhpConverter
Development:
nette/tester(^2.3): Test frameworkphpstan/phpstan(^0.12): Static analysisnette/finder(^2.5): File iteration utilitiestracy/tracy(^2.8): Debugging/error handling
Note: The project does NOT depend on the actual Twig library - it implements its own Twig parser (Twiggy) for conversion purposes.