Merge pull request #18411 from MegaphoneJon/pcp-wysiwyg
[civicrm-core.git] / ext / afform / docs / philosophy.md
1 # Philosophy, Beliefs, Assumptions
2
3 Afform is generally grounded in a few beliefs.
4
5 ## Leap by extension
6
7 Afform represents a major conceptual change in how core forms are developed. It is incubated as an extension that can
8 be enabled or disabled to taste. The aim is to write further extensions which (a) build on afform APIs in order to (b) incrementally override/replace particular forms in core.
9
10 ## Features and user-experiences evolve in funny workflows
11
12 If we could sit down and define one true, correct version of a "Donation" form, then our lives as Civi devlopers would
13 be easy: draw a mockup, write code, ship, and retire. But we can't -- because Civi users / integrators / developers engage with
14 the system creatively. They aim to optimize conversion-rates, to integrate with donor journerys, to question how each
15 detail makes sense in their situation, etc. That means switching between open-ended donation amounts, sliders, radios,
16 etc; revising the language and layout; maybe adding an informational question or newsletter opt-in.
17
18 I believe that features and user-experiences evolve in funny workflows -- because the actual stories behind major
19 improvements have not fit into a single mold. A main ambition of `afform` is to allow multiple workflows in developing
20 a common type of deliverable (*the forms*). Thus, the architecture anticipates scenarios for developers defining forms
21 concretely; for users defining forms concretely; for using GUIs or text-editors or IDEs or SCMs; for using
22 cross-cutting hooks and selectors. Compatibility with multiple workflows is a primary feature of the design.
23
24 This is *not* an argument for maximal customization or maximal decentralization. As participants in an ecosystem, we
25 must still communicate and exercise judgment about the best way to approach each problem. But there are legitimate
26 instances for each workflow; given that each will be sought, we want them to be safe and somewhat consistent.
27
28 The aims are *not* achieved by developing every feature in-house. Rather, this is conceived as an effort to use
29 existing tools/frameworks while relaxing workflows.
30
31 What distinguishes `afform` from the original form architecture (Civi's combination of HTML_Quickform, Smarty and
32 Profiles)? Each of those workflows has been given some consideration upfront with the aim of providing a *consistent,
33 unified model* -- so that the same data-structure can be pushed through any of those common workflows.
34
35 ## Incremental and measurable strictness
36
37 JavaScript, PHP, and HTML are forgiving, loosely-typed systems. This can be viewed as a strength (wrt to learnability
38 and prototyping), and it can be viewed as a weakness (allowing a number of common mistakes to go unidentified until a
39 user runs into them).
40
41 Personally, I think that strongly-typed languages are better for large, multi-person projects -- providing a fallback
42 to protect against some common mistakes that arise people don't fully communicate or understand a change. However,
43 adopting a strongly-typed system is a major change, and it's not perfect, and I can respect the arguments in favor of
44 loosely-typed systems.
45
46 A compromise is to phase-in some static analysis incrementally. For `afform`, this means that the main deliverables
47 (HTML documents+changesets) should be encoded in an inspectable form -- it must be possible for the system to enumerate
48 all documents+changesets and audit them (i.e. identifying which form elements -- CSS classes and Angular directives --
49 are officially supported or unsupported). This, in turn, means that we can provide warnings and scores to identify
50 which customizations are more maintainable or more experimental/suspect.
51
52 ## Don't reinvent the wheel; do use a wheel that fits
53
54 The general philosophy and architecture in `afform` could be used with almost any form system that has a clear
55 component hierarchy (such as AngularJS's HTML notation, Symfony Form's object graph, or Drupal Form API's array-trees).
56
57 It specifically uses AngularJS. Why? In order of descending importance:
58
59 * It can work across a wide range of existing deployment environments (D7, D8, WordPress, Backdrop, Joomla, Standalone).
60 * It already exists.
61 * I have experience with it.
62 * The main Angular tutorials aimed at generalist web developers are reasonably slick.
63 * The connection between the code you write and what's displayed in the browser is fairly concrete.
64
65 It's by no means a perfect wheel. Other wheels have strengths, too. I checked the top-line requirement and grabbed
66 the closest wheel that fit.
67
68 ## Fidelity to upstream
69
70 The upstream AngularJS project canonically represents a form as an HTML file on disk; thus, `afform` does the same.
71 The upstream project uses `ng-if` for a conditional element; thus, an `afform` instance should do the same. The
72 upstream project uses "directives" for composable building blocks; and `afform`, the same.
73
74 This convention (a) helps to reduce bike-shedding, (b) helps us get some benefit out of re-using an existing wheel, and
75 (c) practices what we preach with regard to "consistency" across the various workflows.
76
77 ## Generally comparable platform requirements
78
79 If you can install CiviCRM on a server today, then you should be able to install `afform` and a personalized mix of
80 extensions which build on it. This means that the main workflows facilitated by `afform` can require PHP (and even
81 MySQL), but they can't require (say) Redis or Ruby or NodeJS.