Skip to content

Commit b7b0136

Browse files
Add documentation for FormatterModifier
Co-authored-by: henriquemoody <154023+henriquemoody@users.noreply.github.com>
1 parent 10a27ab commit b7b0136

3 files changed

Lines changed: 225 additions & 4 deletions

File tree

docs/PlaceholderFormatter.md

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,43 @@ echo $formatter->formatUsing(
3535

3636
### With Modifiers
3737

38-
Placeholders can include modifiers that transform values. See the [Modifiers](modifiers/Modifiers.md) documentation for details.
38+
Placeholders can include modifiers that transform values. Formatters can be used as modifiers using the pipe syntax.
3939

4040
```php
41-
$formatter = new PlaceholderFormatter(['name' => 'John']);
41+
$formatter = new PlaceholderFormatter([
42+
'date' => '2024-01-15',
43+
'amount' => '1234.567',
44+
'phone' => '1234567890',
45+
]);
46+
47+
// Date formatting
48+
echo $formatter->format('Date: {{date|date:Y/m/d}}');
49+
// Output: Date: 2024/01/15
50+
51+
// Number formatting
52+
echo $formatter->format('Amount: ${{amount|number:2}}');
53+
// Output: Amount: $1,234.57
54+
55+
// Pattern formatting
56+
echo $formatter->format('Phone: {{phone|pattern:(###) ###-####}}');
57+
// Output: Phone: (123) 456-7890
58+
```
59+
60+
See the [FormatterModifier](modifiers/FormatterModifier.md) documentation for all available formatters and options.
61+
62+
You can also use other modifiers like `list` and `trans`:
4263

43-
echo $formatter->format('Hello {{name|upper}}!');
44-
// Outputs: Hello JOHN!
64+
```php
65+
$formatter = new PlaceholderFormatter([
66+
'items' => ['apple', 'banana', 'cherry'],
67+
]);
68+
69+
echo $formatter->format('Items: {{items|list:and}}');
70+
// Output: Items: apple, banana, and cherry
4571
```
4672

73+
See the [Modifiers](modifiers/Modifiers.md) documentation for details.
74+
4775
## API
4876

4977
### `__construct(array $parameters, Modifier|null $modifier = null)`
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
<!--
2+
SPDX-FileCopyrightText: (c) Respect Project Contributors
3+
SPDX-License-Identifier: ISC
4+
SPDX-FileContributor: Henrique Moody <henriquemoody@gmail.com>
5+
-->
6+
7+
# FormatterModifier
8+
9+
The `FormatterModifier` enables using any formatter as a placeholder modifier. It parses the pipe syntax, dynamically instantiates the requested formatter, and applies it to the value.
10+
11+
## Overview
12+
13+
Instead of creating separate modifier classes for each formatter, `FormatterModifier` provides a unified way to use formatters as modifiers directly in placeholder templates.
14+
15+
## Syntax
16+
17+
```
18+
{{placeholder|formatterName}}
19+
{{placeholder|formatterName:arg1}}
20+
{{placeholder|formatterName:arg1:arg2:arg3}}
21+
```
22+
23+
The formatter name is converted to a formatter class name by:
24+
1. Capitalizing the first letter
25+
2. Appending "Formatter"
26+
3. Looking in the `Respect\StringFormatter` namespace
27+
28+
Arguments after the formatter name (separated by `:`) are passed to the formatter's constructor.
29+
30+
## Examples
31+
32+
### Date Formatting
33+
34+
```php
35+
use Respect\StringFormatter\PlaceholderFormatter;
36+
37+
$formatter = new PlaceholderFormatter(['date' => '2024-01-15']);
38+
39+
// Default date format
40+
echo $formatter->format('Date: {{date|date}}');
41+
// Output: Date: 2024-01-15 00:00:00
42+
43+
// Custom date format
44+
echo $formatter->format('Date: {{date|date:Y/m/d}}');
45+
// Output: Date: 2024/01/15
46+
47+
echo $formatter->format('Date: {{date|date:F j, Y}}');
48+
// Output: Date: January 15, 2024
49+
```
50+
51+
### Number Formatting
52+
53+
```php
54+
$formatter = new PlaceholderFormatter(['amount' => '1234.567']);
55+
56+
// Default (0 decimals)
57+
echo $formatter->format('Amount: {{amount|number}}');
58+
// Output: Amount: 1,235
59+
60+
// With decimals
61+
echo $formatter->format('Amount: {{amount|number:2}}');
62+
// Output: Amount: 1,234.57
63+
64+
// Custom separators (decimals, decimal separator, thousands separator)
65+
echo $formatter->format('Amount: {{amount|number:2:,: }}');
66+
// Output: Amount: 1 234,57
67+
```
68+
69+
### Mask Formatting
70+
71+
```php
72+
$formatter = new PlaceholderFormatter([
73+
'card' => '1234567890123456',
74+
'ssn' => '123456789',
75+
]);
76+
77+
// Mask with range
78+
echo $formatter->format('Card: {{card|mask:5-12}}');
79+
// Output: Card: 1234********3456
80+
81+
// Mask with custom replacement
82+
echo $formatter->format('SSN: {{ssn|mask:1-5:X}}');
83+
// Output: SSN: XXXXX6789
84+
```
85+
86+
### Pattern Formatting
87+
88+
```php
89+
$formatter = new PlaceholderFormatter(['phone' => '1234567890']);
90+
91+
echo $formatter->format('Phone: {{phone|pattern:(###) ###-####}}');
92+
// Output: Phone: (123) 456-7890
93+
```
94+
95+
### Metric Formatting
96+
97+
```php
98+
$formatter = new PlaceholderFormatter(['distance' => '1500']);
99+
100+
echo $formatter->format('Distance: {{distance|metric:mm}}');
101+
// Output: Distance: 1.5 m
102+
```
103+
104+
### Multiple Formatters
105+
106+
```php
107+
$formatter = new PlaceholderFormatter([
108+
'date' => '2024-01-15',
109+
'amount' => '1234.56',
110+
'phone' => '1234567890',
111+
]);
112+
113+
$template = <<<'TEMPLATE'
114+
Date: {{date|date:d/m/Y}}
115+
Amount: ${{amount|number:2}}
116+
Phone: {{phone|pattern:(###) ###-####}}
117+
TEMPLATE;
118+
119+
echo $formatter->format($template);
120+
// Output:
121+
// Date: 15/01/2024
122+
// Amount: $1,234.56
123+
// Phone: (123) 456-7890
124+
```
125+
126+
## Behavior
127+
128+
### Formatter Resolution
129+
130+
1. The modifier attempts to instantiate a formatter based on the pipe name
131+
2. If the formatter class doesn't exist, it delegates to the next modifier in the chain
132+
3. If the formatter exists but construction fails (invalid arguments), it delegates to the next modifier
133+
134+
### Value Conversion
135+
136+
- If the value is already a string, it's passed directly to the formatter
137+
- If the value is not a string, it's first converted to a string by delegating to the next modifier
138+
- This ensures formatters always receive valid string input
139+
140+
### Error Handling
141+
142+
- If a formatter throws an exception during formatting, the modifier delegates to the next modifier
143+
- This provides graceful fallback behavior
144+
145+
### Fallback Chain
146+
147+
`FormatterModifier` is designed to work in a chain with other modifiers:
148+
149+
```
150+
FormatterModifier → TransModifier → ListModifier → StringPassthroughModifier → StringifyModifier
151+
```
152+
153+
If a pipe name doesn't match a formatter, it falls through to the next modifier (e.g., `trans`, `list:and`, `quote`).
154+
155+
## Integration
156+
157+
`FormatterModifier` is automatically included in the default modifier chain for `PlaceholderFormatter`. You don't need to configure it explicitly.
158+
159+
If you want to customize the modifier chain, you can include it manually:
160+
161+
```php
162+
use Respect\StringFormatter\PlaceholderFormatter;
163+
use Respect\StringFormatter\Modifiers\FormatterModifier;
164+
use Respect\StringFormatter\Modifiers\StringifyModifier;
165+
166+
$formatter = new PlaceholderFormatter(
167+
['value' => '123'],
168+
new FormatterModifier(new StringifyModifier())
169+
);
170+
```
171+
172+
## Supported Formatters
173+
174+
All formatters in the `Respect\StringFormatter` namespace can be used:
175+
176+
- `date` - [DateFormatter](../DateFormatter.md)
177+
- `number` - [NumberFormatter](../NumberFormatter.md)
178+
- `mask` - [MaskFormatter](../MaskFormatter.md)
179+
- `pattern` - [PatternFormatter](../PatternFormatter.md)
180+
- `metric` - [MetricFormatter](../MetricFormatter.md)
181+
- `mass` - [MassFormatter](../MassFormatter.md)
182+
- `area` - [AreaFormatter](../AreaFormatter.md)
183+
- `time` - [TimeFormatter](../TimeFormatter.md)
184+
- `imperialLength` - [ImperialLengthFormatter](../ImperialLengthFormatter.md)
185+
- `imperialMass` - [ImperialMassFormatter](../ImperialMassFormatter.md)
186+
- `imperialArea` - [ImperialAreaFormatter](../ImperialAreaFormatter.md)
187+
188+
## Limitations
189+
190+
- Formatter arguments must be strings (they're split by `:` from the pipe)
191+
- Complex objects or arrays cannot be passed as formatter arguments
192+
- Formatter names must match the class name pattern (capitalized name + "Formatter")

docs/modifiers/Modifiers.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ If no modifier is provided, the formatter uses `StringifyModifier` by default.
5757

5858
## Available Modifiers
5959

60+
- **[FormatterModifier](FormatterModifier.md)** - Enables using any formatter as a modifier (e.g., `date:Y-m-d`, `number:2`)
6061
- **[ListModifier](ListModifier.md)** - Formats arrays as human-readable lists with conjunctions
6162
- **[QuoteModifier](QuoteModifier.md)** - Quotes string values using a stringifier quoter
6263
- **[RawModifier](RawModifier.md)** - Returns scalar values as raw strings with `|raw` pipe

0 commit comments

Comments
 (0)