X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=ext%2Fafform%2FREADME.md;h=97e890ad787b4905f9ba2de67767bab0c1e0b7e7;hb=1ba1749e62e67560d4b4d769246dc67d55cc3d38;hp=a895ff2eb275fd438553757f42eebbbd6d19b815;hpb=fdee1ed953c47ee2eb99e1c7925f5fee1443a705;p=civicrm-core.git diff --git a/ext/afform/README.md b/ext/afform/README.md index a895ff2eb2..97e890ad78 100644 --- a/ext/afform/README.md +++ b/ext/afform/README.md @@ -1,22 +1,30 @@ # org.civicrm.afform (Early Proof of Concept) -![Screenshot](/images/screenshot.png) +> You are looking at the `master` branch of a proof-of-concept module. It +> may change radically (without full curation of docs, etc). For previous +> iterations with more stable/cogent materials, check other branches (e.g. +> `0.1`). + +![Screenshot](docs/sandbox/3-Free-Blocks-Parent.png) The Affable Administrative Angular Form Framework (`afform`) is a system for administering AngularJS-based forms in CiviCRM which: -1. Allows developers to declaratively define a canonical, baseline form. -2. Allows administrators (or administrative tools) to use the CRUD API to customize the forms. -3. Allows developers to embed these forms in other CiviCRM-AngularJS apps. -4. (WIP; pending upstream support) Allow developers to apply [change sets](https://docs.civicrm.org/dev/en/latest/framework/angular/changeset/). +1. Allows developers to declaratively define a canonical, baseline form using AngularJS. +2. Allows administrators (or administrative GUI tools) to use the CRUD API to customize the forms. +3. Allows developers (or administrators/tools) to embed these forms in other CiviCRM-AngularJS apps. +4. Allows developers to apply change-sets via hook. (*WIP; pending upstream support*) -The extension is licensed under [AGPL-3.0](LICENSE.txt). +This extension is a proof-of-concept. It aims to demonstrate the core model/concept -- however, there are +[known issues and additional components](docs/roadmap.md) to address, and some documentation will be easier to approach +if you already have a basic understanding of CiviCRM API and AngularJS. It is licensed under [AGPL-3.0](LICENSE.txt). ## Requirements -* PHP v5.4+ -* CiviCRM v5.3+ +* PHP v7.0+ +* CiviCRM v5.22+ + ## Installation (CLI, Git) @@ -37,193 +46,17 @@ Sysadmins and developers may clone the [Git](https://en.wikipedia.org/wiki/Git) install it with the command-line tool [cv](https://github.com/civicrm/cv). ```bash -git clone https://github.com/FIXME/org.civicrm.afform.git +git clone https://lab.civicrm.org/extensions/afform.git cv en afform ``` -## Development: Quick Start - -As an extension author, you can define a form along with its default, -canonical content. Simply create a folder named `afform/`. In -this example, we create a form named `foobar`: - -``` -$ cd /path/to/my/own/extension -$ mkdir -p afform/foobar -$ echo '{"server_route": "civicrm/pretty-page"}' > afform/foobar/meta.json -$ echo '
Hello {{routeParams.name}}
' > afform/foobar/layout.html -$ cv flush -``` - -A few things to note: - -* We defined a route `civicrm/pretty-page`. This is defined in the same routing system used by CiviCRM forms. -* The file `layout.html` is an AngularJS HTML document. It has access to all the general features of Angular HTML (discussed more later). -* After creating a new form or file, we should flush the cache. -* If you're going to actively edit/revise the content of the file, then you should navigate - to **Administer > System Settings > Debugging** and disable asset caching. - -Now that we've created a form, we'll want to determine its URL. As with most -CiviCRM forms, the URL depends on the CMS configuration. Here is an example -from a local Drupal 7 site: - -``` -$ cv url "civicrm/pretty-page" -"http://dmaster.localhost/civicrm/pretty-page" -$ cv url "civicrm/pretty-page/#/?name=world" -"http://dmaster.localhost/civicrm/pretty-page/#/?name=world" -``` - -Open the URLs and see what you get. - -## Development: Scopes, variables, and directives - oh my! - -In AngularJS, the primary language for orchestrating a screen is HTML. You can embed code in here. - -One key concept *scope* -- the *scope* defines the list of variables which you can access. By default, `afform` -provides a few variables within the scope of every form: - -* `routeParams`: This is a reference to the [$routeParams](https://docs.angularjs.org/api/ngRoute/service/$routeParams) - service. In the example, we used `routeParams` to get a reference to a `name` from the URL. -* `meta`: The stored meta data (`meta.json`) for this form. -* `ts`: This is a utility function which translates strings, as in `{{ts('Hello world')}}`. - -Additionally, AngularJS allows *directives* -- these are extra HTML attributes and HTML tags. For example: - -* `ng-if` will conditionally create or destroy elements in the page. -* `ng-repeat` will loop through data. -* `ng-style` and `ng-class` will conditionally apply styling. - -A full explanation of these features is out-of-scope for this document, but the key point is that you can use standard -AngularJS features. - -## Development: Display a contact record - -Let's say we want `foobar` to become a basic "View Contact" page. A user -would request a URL like: - -``` -http://dmaster.localhost/civicrm/pretty-page/#/?cid=123 -``` - -How do we use the `cid` to get information about the contact? Update `layout.html` to include data from APIv3: - -```html -
- -
-

{{contact.display_name}}

- -

Key Contact Fields

- -
Contact ID: {{contact.contact_id}}
-
Contact Type: {{contact.contact_type}}
-
Display Name: {{contact.display_name}}
-
First Name: {{contact.first_name}}
-
Last Name: {{contact.last_name}}
- -

Full Contact record

- -
{{contact|json}}
-
-
-``` - -This example is useful pedagogically and may be useful in a crunch -- but in the longer term, -we should have a richer library of directives so that typical user-managed forms don't drill-down -at this level of detail. - -## Development: Form CRUD API - -Now that we've defined a baseline form, it's possible for administrators and -GUI applications to inspect the form using the API: - -``` -$ cv api afform.getsingle name=foobar -{ - "name": "foobar", - "requires": [ - "afformCore" - ], - "title": "", - "description": "", - "layout": { - "#tag": "div", - "#children": [ - "Hello {{routeParams.name}}" - ] - }, - "id": "foobar" -} -``` - -Additionally, you can also update the forms: - -``` -$ cv api afform.create name=foobar title="The Foo Bar Screen" -{ - "is_error": 0, - "version": 3, - "count": 2, - "values": { - "name": "foobar", - "title": "The Foo Bar Screen" - } -} -``` - -A few important things to note about this: - -* The changes are only applied on this site. -* Once you make a change with the CRUD API, there will be two copies of the form: - * `[myextension]/afform/foobar/` is the default, canonical version. - * `[civicrm.files]/afform/foobar/` is the locally customized version. -* The `layout` field is stored as an Angular-style HTML document (`layout.html`), so you can edit it on disk like - normal Angular code. However, when CRUD'ing the `layout` through the API, it is presented in JSON-style. - - -## Development: Every form is an AngularJS directive - -In the quick-start example, we registered a new route (`"server_route": "civicrm/pretty-page"`) -- this created a -simple, standalone page with the sole purpose of displaying the `foobar` form. But that had very limited information. -What if we want control the environment a bit more? - -There's no obligation to use the simple, standalone version of `foobar`. Think of `foobar` as a *re-usable sub-form* -or as a *directive*. If you've created an AngluarJS application, then you can embed `foobar` with two small steps: - -1. In your application, declare a dependency on module `afformFoobar`. This is usually done in `ang/MYMODULE.ang.php` - and/or `ang/MYMODULE.js`. -2. In your HTML template, use the directive `
`. - -This technique is particularly useful if you want to provide extra data for the form author to use. For example, your -application might pass in the current phase of the moon: - -```html -
-``` - -Now, in `afform/foobar/layout.html`, you can use the `phaseOfMoon`: - -```html -Hello, {{routeParams.name}}. The moon is currently {{options.phaseOfMoon}}. -``` - -Or if you're not sure data will actually be provided: - -```html -Hello, {{routeParams.name ? routeParams.name : 'anonymous'}}. The moon is currently {{options.phaseOfMoon ? options.phaseOfMoon : 'on hiatus'}}. -``` +## Developer Documentation -## Known Issues - -* The code is currently written as a proof-of-concept. There are several `FIXME`/`TODO` declarations in the code - for checking pre-conditions, reporting errors, handling edge-cases, etc. -* Although afforms are can be used in AngularJS, they don't fully support tooling like `cv ang:html:list` - and `hook_civicrm_alterAngular` changesets. We'll need a core patch to allow that. -* We generally need to provide more services for managing/accessing data (e.g. `crm-api3`). -* Need to implement the `Afform.revert` API to undo local customizations. -* Haven't decided if we should support a `client_route` property (i.e. defining a skeletal controller and route for any form). - On the plus side, make it easier to add items to the `civicrm/a` base-page. On the flipside, we don't currently have - a strong use-case, and developers can get the same effect with `civix generate:angular-page` and embedding `
`. +* [Quick Start: Creating the canonical definition of a basic form](docs/quickstart.md) +* [Writing Forms: Afform as basic AngularJS templates](docs/writing.md) (With example: *Contact Record*) +* [Embedding Forms: Afform as reusable building-block](docs/embed.md) (With example: *Contact Record*) +* [Form CRUD: Updating forms via programmatic API](docs/crud.md) +* [Form Hooks: Updating forms via declarative selector](docs/alter.md) (*WIP; pending upstream support*) +* [Full AngularJS: Integrating between Afform and vanilla AngularJS](docs/angular.md) +* [Roadmap and Known Issues](docs/roadmap.md) +* [Philosophy, Beliefs, Assumptions](docs/philosophy.md)