Merge pull request #21856 from civicrm/5.43
[civicrm-core.git] / ext / afform / docs / alter.md
CommitLineData
b9e5de69
TO
1# Form Hooks: Updating forms via declarative selector
2
2d76e916
TO
3> __WIP__ This describes functionality that is intended but not actual.
4> The hooks/change-sets currently work with core's `*.html` files; but we need
5> a little patching to make them work with afform's `*.html` files.
b9e5de69 6
2d76e916
TO
7Form hooks offer a different style of customization than [Form CRUD](docs/crud.md). In the CRUD style, you use an API
8to save an updated form -- which stores the exact form (as designed by the user). In the hook style, you wait until a
9form is being displayed; and, as part of the rendering process, you filter the output.
b9e5de69
TO
10
11## Example
12
13In this example, we use `hook_civicrm_alterAngular` to apply a filter to the file `~/crmMailing/BlockSummary.html` --
14the filter selects an element by CSS class (`crm-group`) and then appends a new field to the bottom of that element:
15
16```php
17function mailwords_civicrm_alterAngular(\Civi\Angular\Manager $angular) {
18 $changeSet = \Civi\Angular\ChangeSet::create('inject_mailwords')
19 // ->requires('crmMailing', 'mailwords')
20 ->alterHtml('~/crmMailing/BlockSummary.html',
21 function (phpQueryObject $doc) {
22 $doc->find('.crm-group')->append('
2d76e916
TO
23 <div crm-ui-field="{name: \'subform.mailwords\', title: ts(\'Keywords\')}">
24 <input crm-ui-id="subform.mailwords" class="crm-form-text" name="mailwords" ng-model="mailing.template_options.keywords">
25 </div>
26 ');
b9e5de69
TO
27 });
28 $angular->add($changeSet);
29}
30```
31
32## Comparison: CRUD vs Hook
33
34Similarities:
35
36* Both styles have safe and unsafe use-cases.
37* The safety generally depends on the specific components being used.
38 * Ex: If you add a new `crm-ui-field` (via either style), that could be safe/maintainable (if `crm-ui-field` is supported, stable, widely used) or it could be risky/hard-to-maintain
39 (if `crm-ui-field` is undocumented and rarely used).
2d76e916
TO
40* In either style, there are legitimate scenarios for someone to reference a safe or risky component.
41* In either style, it is difficult for a person to keep track of whether the referenced components are safe or risky. The list of experimental/supported/deprecated components will be long and will change over time. We'd rather have tooling to keep track of this.
b9e5de69
TO
42* Provided you abide by the code-style of the example, it is possible for the framework to build a list of all CRUD'd forms and all change-sets. In turn, it's possibile to loop through them, audit them, and warn about anything which appears unsafe.
43
44Differences:
45
2d76e916
TO
46* CRUD is concrete. It saves what you tell it to save, and it doesn't do anything else. This makes it more suitable as the conceptual model for the users' GUI editor.
47* Change-sets are abstract. They can change many components (e.g. converting every `<h1>` to a `<div class="my-header-1">`).
48* The good and bad consequences of CRUD are limited to the specific things you manipulated.
49* The good and bad consequences of change-sets can apply across a wider range of things.
50* CRUD locks-in your changes and preferences. If there's an upgrade, your form should remain safely as it was before (provided the form relied on supported components).
51* Change-sets are adaptable. If there's an upgrade or edit to the underlying form, the change-set will be used on top of the latest revision. If the change-set is revised, then the latest change-set will be used without needing to edit the forms individually.
b9e5de69 52
2d76e916 53I expect future people will develop better insight on the trade-offs (and may design other, more nuanced options). For an initial first-read on when to use each, my expectations are that:
b9e5de69 54
2d76e916 55* CRUD is more appropriate when an *administrator* is expressing a *policy opinion* about the importance of information on a page.
b9e5de69
TO
56* Change-sets are more appropriate when a *developer* is changing an *implementation detail* (such as the CSS classes used to style all calendar widgets).
57
58## See also
59
60https://docs.civicrm.org/dev/en/latest/framework/angular/changeset/