Commit | Line | Data |
---|---|---|
b9e5de69 TO |
1 | # Philosophy, Beliefs, Assumptions |
2 | ||
3e04b1d0 | 3 | Afform is generally grounded in a few beliefs. |
b9e5de69 TO |
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 | |
3e04b1d0 | 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. |
b9e5de69 TO |
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 | |
3e04b1d0 | 13 | be easy: draw a mockup, write code, ship, and retire. But we can't -- because Civi users / integrators / developers engage with |
b9e5de69 TO |
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 | ||
3e04b1d0 TO |
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 | ||
b9e5de69 TO |
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. |