Skip to content

Commit 93efbeb

Browse files
committed
Document custom renderers
1 parent 83945fd commit 93efbeb

3 files changed

Lines changed: 80 additions & 1 deletion

File tree

docs/_data/nav_docs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
items:
99
- id: hack-builder-blocks
1010
- id: hack-builder-keys-and-values
11+
- id: hack-builder-custom-renderers
1112

1213
# n title:, 1 items: per title:, n id: per items:
1314
# - title: A
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
docid: hack-builder-custom-renderers
3+
title: Custom Renderers
4+
layout: docs
5+
permalink: /docs/hack-builder/custom-renderers/
6+
---
7+
8+
There are 3 main ways to implement custom rendering:
9+
10+
- Pre-process your values to code, then use `HackBuilderValues::literal()` or
11+
`HackBuilderKeys::literal()`
12+
- use `HackBuilderValues::lambda()` or `HackBuilderKeys::lambda()`
13+
- create classes that implement `IHackBuilderValueRenderer` or
14+
`IHackBuilderKeyRenderer`
15+
16+
Pre-processing
17+
--------------
18+
19+
Pre-process the values so that the keys/values are the literal code you want
20+
instead:
21+
22+
``` php
23+
<?hh
24+
25+
$map = Map { /* ... */ };
26+
$processed = Map { };
27+
foreach ($map as $k => $v) {
28+
$processed[my_render_function($k)] = $v;
29+
}
30+
$builder
31+
->addValue(
32+
$map,
33+
HackBuilderValues::map(
34+
HackBuilderKeys::literal(),
35+
HackBuilderValues::export(),
36+
),
37+
);
38+
```
39+
40+
This is usually the right approach for a single value, but not the most readable
41+
for multiple values, eg for collections.
42+
43+
Lambdas
44+
-------
45+
46+
The lambda takes an `IHackCodegenConfig` and the value; the value can be used
47+
to create a `HackCodegenFactory` if neccessary, though as there's usually one
48+
in scope, it's usually unneeded.
49+
50+
``` php
51+
<?hh
52+
53+
$map = Map { /* ... */ };
54+
$builder
55+
->addValue(
56+
$map,
57+
HackBuilderValues::map(
58+
HackBuilderKeys::lambda(
59+
($_config, $v) ==> my_render_function($v),
60+
),
61+
HackBuilderValues::export(),
62+
),
63+
);
64+
```
65+
66+
This can be the right choice when the same renderer is needed for many values but
67+
in few places.
68+
69+
Custom Renderer Classes
70+
-----------------------
71+
72+
If you are using the same renderer in multiple places, you can implement the
73+
`IHackBuilderKeysRenderer<T>` or `IHackBuilderValuesRenderer<T>` interfaces;
74+
this is the same way the built-ins are implemented.
75+
76+
While it's possible to implement both in the same class, it's usually better
77+
not to so that the hack typechecker has more visibility into argument order
78+
mistakes for collections.

docs/_docs/hack-builder/keys-and-values.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ This is based on the `IHackBuilderValueRenderer<T>` interface, which provides
1616
`public function render(IHackCodegenConfig $config, T $input): string` which
1717
returns PHP code.
1818

19-
Basic Built-ins
19+
Basic Built-Ins
2020
---------------
2121

2222
Hack Codegen provides several implementation of this interface, accessed via

0 commit comments

Comments
 (0)