Skip to content

Commit 676d264

Browse files
committed
Add modifier support to PlaceholderFormatter
Although basic interpolation is useful, we often want to handle parameters differently, not using the standard modification we apply to them. This commit introduces modifiers, a concept already present in Respect\Validation. We use a familiar `{{value|modifier}}` syntax found in many popular template engines. To handle different types of modifiers, I implemented a Chain of Responsibility, where each modifier delegates to the next one when it cannot handle them. The `StringifyModifier` remains the default fallback, ensuring that we don't lose the robust type-handling we previously built, but I've also made some changes to it. I realise that for Respect\Validation, we have a strong need to add "quotes" around strings because they represent values that were just validated, but in the context of placeholder replacement, this behaviour is undesirable. I've created the `AutoQuoteModifier`, which quotes scalar values by default and provides a `|raw` pipe to bypass quoting when clean output is needed. This allows Validation to retain its quoting behaviour while keeping the default `PlaceholderFormatter` chain simple. Assisted-by: OpenCode (GLM-4.6) Assisted-by: Gemini 3 (Thinking)
1 parent fb2db2d commit 676d264

17 files changed

Lines changed: 688 additions & 351 deletions

AGENTS.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,27 @@ When creating new formatters:
3333

3434
All formatters must implement the `Respect\StringFormatter\Formatter` interface.
3535

36+
## Modifier Development
37+
38+
When creating new modifiers:
39+
40+
1. **Follow Chain of Responsibility pattern**: Check pipe value and delegate to next modifier
41+
2. **Use template structure**: Similar to `src/Modifier/QuoteModifier.php`
42+
3. **Test with TestingModifier**: Located in `tests/Helper/TestingModifier.php`
43+
4. **Handle type checking**: Always check input types before processing
44+
5. **Return string values**: Modifiers must return strings
45+
6. **Use Stringifier Quoter**: For string operations, inject `\Respect\Stringifier\Quoter` with CodeQuoter as default
46+
47+
All modifiers must implement the `Respect\StringFormatter\Modifier` interface.
48+
49+
## Testing Guidelines
50+
51+
1. **Avoid PHPUnit mocks**: Create custom test implementations instead of using createMock()
52+
2. **Use custom test quoter**: Follow pattern in `tests/Helper/TestingQuoter.php`
53+
3. **Test contracts not implementations**: Verify interactions without depending on specific behavior
54+
4. **Make test properties public**: When using anonymous classes to access test state
55+
5. **Verify method calls**: Track whether methods were called and with what parameters
56+
3657
## Commit Guidelines
3758

3859
Follow the detailed rules in `docs/contributing/commit-guidelines.md`:

0 commit comments

Comments
 (0)