update docs

This commit is contained in:
Denys Vuika
2018-09-06 12:22:33 +01:00
parent f03196d424
commit 85d19251d4

View File

@@ -91,6 +91,219 @@ Always keep in mind that all extension files are merged together at runtime.
That allows plugins overwriting the code from the main application or altering other plugins. That allows plugins overwriting the code from the main application or altering other plugins.
</p> </p>
### Startup behaviour
First, the root `app.extensions.json` is loaded by means of the special `Loader` service.
The file can contain all the necessary declarations for an application to function,
and having extra plugin files is fully optional.
Next, the `Loader` traverses the `$references` metadata and loads additional files if provided.
For the sake of speed the files are loaded in parallel,
however, once everything is loaded, they are applied in the order of declaration.
After all the external files are fetched, the `Loader` sorts them, removes the metadata properties
and stacks the resulting JSON objects on top of each other.
<p class="tip">
Any top-level property name that starts with the `$` symbol is considered a metadata and does not participate in merge process.
That allows a plugin to carry extra information for maintenance and visualisation purposes,
for example: `$name`, `$version`, `$description`, `$license`, etc.
</p>
#### Merging properties
There are no limits in the JSON structure and level of nesting.
All objects are merged into a single set based on property keys and object IDs (for arrays).
Before: Plugin 1
```json
{
"$name": "plugin1",
"plugin1.key": "value",
"plugin1.text": "string"
}
```
Before: Plugin 2
```json
{
"$name": "plugin2",
"plugin2.key": "value",
"plugin1.text": "custom string"
}
```
Final result:
```json
{
"plugin1.key": "value",
"plugin1.text": "custom string",
"plugin2.key": "value"
}
```
Note that as a result we have two unique properties `plugin1.key` and `plugin2.key`,
and also a `plugin1.text` that was first defined in the `Plugin 1`, but then overwritten by the `Plugin 2`.
<p class="tip">
JSON merging is very powerful concept as it gives you abilities to alter any base application settings,
or toggle features in other plugins without rebuilding the application or corresponding plugin libraries.
</p>
#### Merging objects
The complex objects are merged by properties. This process is recursive and has no limits for nesting levels.
Before: Plugin 1
```json
{
"$name": "plugin1",
"features": {
"title": "some title",
"page1": {
"title": "page 1"
}
}
}
```
Before: Plugin 2
```json
{
"$name": "plugin2",
"features": {
"page1": {
"title": "custom title"
},
"page2": {
"title": "page 2"
}
}
}
```
Final result:
```json
{
"features": {
"title": "some title",
"page1": {
"title": "custom title"
},
"page2": {
"title": "page 2"
}
}
}
```
As you can see, the unique properties get merged together in a single object.
However the last non-unique property always wins and overwrites the previous value.
As per current design it is not possible to delete any application property from the plugin.
The loader engine supports only overwriting values on purpose.
Many components however support the `disabled` property you can change from external definition:
Before: Plugin 1
```json
{
"$name": "plugin1",
"feature1": {
"disabled": false,
"text": "some-feature",
"icon": "some-icon"
}
}
```
Before: Plugin 2
```json
{
"$name": "plugin2",
"feature1": {
"disabled": true
}
}
```
Final result:
```json
{
"feature1": {
"disabled": true,
"text": "some-feature",
"icon": "some-icon"
}
}
```
You can find more details in the [Disabling Content](#disabling-content) section
#### Merging arrays
The extension `Loader` provides a special support for merging Arrays.
By default, two collections will be merged into a single array unless objects have `id` properties.
<p class="tip">
If array contains two objects with the same `id` property, the objects will be merged rather than appended.
</p>
Before: Plugin 1
```json
{
"$name": "plugin1",
"features": [
{ "text": "common 1" },
{
"id": "page1",
"text": "page 1"
}
]
}
```
Before: Plugin 2
```json
{
"$name": "plugin2",
"features": [
{ "text": "common 2" },
{
"id": "page1",
"text": "custom page"
}
]
}
```
Final result:
```json
{
"features": [
{ "text": "common 1" },
{ "text": "common 2" },
{
"id": "page1",
"text": "custom page"
}
]
}
```
Note that objects with the same `page1` identifiers were merged while other unique entries were appended to the resulting array.
### Disabling content ### Disabling content
Most of the schema elements can be switched off by using the `disabled` property: Most of the schema elements can be switched off by using the `disabled` property: