Skip to content
Snippets Groups Projects
Commit 52eabe30 authored by totten's avatar totten
Browse files

"AngularJS: Loader" - Various updates

parent 98443340
Branches
No related tags found
No related merge requests found
# AngularJS: Loader
What happens when a user visits a CiviCR-Angular page, such as
`https://example.org/civicrm/a/#/mailing/new`? Broadly speaking, two steps:
What happens when a user visits a CiviCR-Angular page? For example, let's
consider this URL:
* `https://example.org/civicrm/a/#/mailing/new`
Broadly speaking, two things happen:
1. (Server-side) CiviCRM processes the request for `civicrm/a`. It
displays a web-page with all your Angular modules.
......@@ -13,19 +17,64 @@ The client-side behavior is well-defined by Angular
server-side in greater depth because that is unique to the CiviCRM-Angular
integration.
## The default base page (`civicrm/a`)
## The library of AngularJS modules
CiviCRM includes a default base-page -- any module can add new routes on
this page. For example, the `crmMailing` module defines a route
`mailing/new`. You can view this at:
CiviCRM needs a list of available AngularJS modules. Technically, these
modules are defined via
[hook_civicrm_angularModules](/hooks/hook_civicrm_angularModules.md), e.g.
* `https://example.org/civicrm/a/#/mailing/new`
```php
/**
* Implements hook_civicrm_angularModules.
*/
function foobar_civicrm_angularModules(&$angularModules) {
$angularModules['myBigAngularModule'] = array(
'ext' => 'org.example.foobar',
'basePages' => array('civicrm/a'),
'requires' => array('crmUi', 'crmUtils', 'ngRoute'),
'js' => array('ang/myBigangularModule/*.js'),
'css' => array('ang/myBigangularModule/*.css'),
'partials' => array('ang/myBigangularModule'),
);
}
```
!!! tip "Tip: Generating skeletal code with `civix`"
In practice, this skeletal code can be autogenerated usin `civix`.
For details, see [AngularJS: Quick Start](/framework/angular/quickstart.md).
The list of available modules varies depending on your system configuration:
if you install more CiviCRM extensions, then you might have more Angular
modules. Use `cv` to inspect the list of available Angular modules:
```
$ cv ang:module:list
For a full list, try passing --user=[username].
+-------------------+-------------+------------------------------------------------------------------------------------+
| name | basePages | requires |
+-------------------+-------------+------------------------------------------------------------------------------------+
| angularFileUpload | civicrm/a | |
| bw.paging | (as-needed) | |
| civicase | (as-needed) | crmUi, crmUtil, ngRoute, angularFileUpload, bw.paging, crmRouteBinder, crmResource |
| crmApp | civicrm/a | |
| crmAttachment | civicrm/a | angularFileUpload, crmResource |
| crmAutosave | civicrm/a | crmUtil |
| crmCaseType | civicrm/a | ngRoute, ui.utils, crmUi, unsavedChanges, crmUtil, crmResource |
...
```
!!! tip "Tip: More options for `cv ang:module:list`"
* Use `--columns` to specify which columns to display. Ex: `cv ang:module:list --columns=name,ext,extDir`
* Use `--out` to specify an output format. Ex: `cv ang:module:list --out=json-pretty`
* Use `--user` to specify a login user using with. This may reveal permission-dependent modules. Ex: `cv ang:module:list --user=admin`
The default base-page is special because *all registered Angular modules
will be included by default*. You can expect the markup to look roughly
like this:
## The default base page (`civicrm/a`)
CiviCRM includes a default base-page named `civicrm/a`. Any module can add new routes on
this page. The page might look like this:
```html
<!-- URL: https://example.org/civirm/a -->
<html>
<head>
<script type="text/javascript" src="https://example.org/.../angular.js"></script>
......@@ -44,51 +93,26 @@ like this:
</html>
```
The PHP application instantiates `AngularLoader`
!!! note "In practice, the JS files may be aggregated and/or minimized."
The markup is generated by a PHP class, `AngularLoader`, using logic like this:
```php
$loader = new \Civi\Angular\AngularLoader();
$loader->setPageName('civicrm/a');
$loader->setModules(array('crmApp'));
$loader->setPageName('civicrm/a');
$loader->load();
```
The `load()` function determines the necessary JS/CSS/HTML/JSON resources
and loads them on the page. Roughly speaking, it outputs:
More specifically, the `load()` function gets a list of all available
Angular modules (including their JS/CSS/HTTML files). Then it loads the
files for `crmApp` as well as any dependencies (like `crmUi`).
The most important thing to understand is how it *gets the list of Angular
modules*. A few Angular modules are bundled with core (eg `crmUi` or
`crmUtil`), but most new Angular modules should be loaded via
[hook_civicrm_angularModules](/hooks/hook_civicrm_angularModules.md)
For example, if you created an extension `org.example.foobar` with an
Angular module named `myBigAngularModule`, then the hook might look like:
```php
/**
* Implements hook_civicrm_angularModules.
*/
function foobar_civicrm_angularModules(&$angularModules) {
$angularModules['myBigAngularModule'] = array(
'ext' => 'org.example.foobar',
'basePages' => array('civicrm/a'),
'requires' => array('crmUi', 'crmUtils', 'ngRoute'),
'js' => array('ang/myBigangularModule/*.js'),
'css' => array('ang/myBigangularModule/*.css'),
'partials' => array('ang/myBigangularModule'),
);
}
```
!!! tip "`civix` code-generator"
In practice, you usually don't need to implement. The `civix`
code-generator creates a file named `ang/{mymodule}.ang.php` and
automatically loads as part of `hook_civicrm_angularModules`.
and loads them on the page. This will include:
* Any AngularJS modules explicitly listed in `setModules(...)`. (Ex: `crmApp`)
* Any AngularJS modules with matching `basePages`. (Ex: The value `civicrm/a`
is specified by both `setPageName(...)` and `myBigAngularModule` [above].)
* Any AngularJS modules transitively required by the above.
!!! note "What makes `civicrm/a` special?"
When declaring a module, the property `basePages` will default to
`array('civicrm/a')`. In other words, if you don't specify otherwise,
all modules are loaded on `civicrm/a`.
......@@ -16,12 +16,23 @@ available in CiviCRM 4.6+.
## Parameters
- &$angularModules - an array containing a list of all Angular
modules.
* `&$angularModules` - an array containing a list of all Angular modules. Each item is keyed by the Angular module name.
Each item `angularModules` may include these properties:
* `ext` (`string`): The name of the CiviCRM extension which has the source-code.
* `js` (`array`): List of Javascript files. May use the wildcard (`*`). Relative to the extension.
* `css` (`array`): List of CSS files. May use the wildcard (`*`). Relative to the extension.
* `partials` (`array`): List of HTML folders. Relative to the extension.
* `requires` (`array`): List of AngularJS modules required by this module. Default: `array()`. (`v4.7.21+`)
* `basePages` (`array`): Uncondtionally load this module onto the given Angular pages. (`v4.7.21+`)
* If omitted, the default is `array('civicrm/a')`. This provides backward compatibility with behavior since `v4.6+`.
* For a utility that should only be loaded on-demand, use `array()`.
* For a utility that should be loaded in all pages use, `array('*')`.
## Returns
- null
* `null`
## Example
......@@ -32,6 +43,8 @@ available in CiviCRM 4.6+.
);
$angularModules['myBigAngularModule'] = array(
'ext' => 'org.example.mymod',
'requires' => array('ngRoute', 'crmUi'),
'basePages' => array('civicrm/a'),
'js' => array('js/part1.js', 'js/part2.js'),
'css' => array('css/myAngularModule.css'),
'partials' => array('partials/myBigAngularModule'),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment