@@ -21,6 +21,8 @@ class App {
2121 /** @var (Component|string|callable)[] */
2222 private $ components = [];
2323
24+ private $ componentSetups = [];
25+
2426 /**
2527 * @param callable[] $methods The available methods.
2628 * The key is the method name, the value is the corresponding callable.
@@ -36,10 +38,17 @@ public function __construct( array $methods ) {
3638 * @param string $name The component name.
3739 * @param string|callable $template Either the template HTML as a string,
3840 * or a callable that will return the template HTML as a string when called with no arguments.
41+ * @param callable|null $setup An optional setup function.
42+ * If set, the callable is called with the array of data used to render the component,
43+ * and whichever array it returns is then used to actually render the template.
44+ * This can be used, for example, to add additional data (the equivalent of `computed` in JS).
3945 * @return void
4046 */
41- public function registerComponentTemplate ( string $ name , $ template ): void {
47+ public function registerComponentTemplate ( string $ name , $ template, ? callable $ setup = null ): void {
4248 $ this ->components [$ name ] = $ template ;
49+ if ( $ setup !== null ) {
50+ $ this ->componentSetups [$ name ] = $ setup ;
51+ }
4352 }
4453
4554 public function evaluateExpression ( string $ expression , array $ data ) {
@@ -53,6 +62,10 @@ public function renderComponent( string $componentName, array $data ): string {
5362 }
5463
5564 public function renderComponentToDOM ( string $ componentName , array $ data ): DOMElement {
65+ $ setup = $ this ->componentSetups [$ componentName ] ?? null ;
66+ if ( $ setup !== null ) {
67+ $ data = $ setup ( $ data );
68+ }
5669 return $ this ->getComponent ( $ componentName )
5770 ->render ( $ data );
5871 }
0 commit comments