JSON Manager - Documentation
Purpose
Middleware plugin that perform JSON manipulation through patches and are accessed through dataset, a named alias.
Use when
When a reteived JSON file or when a JSON result requested through a RESTful API need a few minor manipulation in order to be displayed with the data-json.
Do not use when
To perform complexe manipulation or metamorphing data in a way that change his original meaning. By complexe manipulation is like filtering, sorting, forking, merging, infering a result based from multiple source inside or outside the data context and any other operation that take time or required considerable amount of ressource where it badly impact the performance of the device and the user experience.
Instead, if your JSON file need a lot of manipulation, consider to create your own RESTful service that will accomodate for performing those task and it will allow to cache the result.
Instead, if your are metamorphing the JSON data source, then that is probably means it should be an middleware service that do that transformation prior to receive the data for being display.
Working example
English:
French:
How to implement
JSON manager is a middleware plugin that allow to manipulate JSON data and return it as a fetch result.
-
From a plugin that request JSON content, refer to a dataset name in the request url. For example with the data json plugin.
<span data-json-replace="#[example1]/product">unknown number of</span>
-
Create a JSON manager plugin by adding the attribute
data-jsonmanager
to an element. At the minimum, you will need to configure the url and the dataset name.Then the following configuration is required if:
-
patches=[]
If you are only applying static patches at the fetched JSON.<div data-wb-jsonmanager='{ "url": "demo/data-en.json", "name": "example1", "patches": [ { "op": "wb-count", "path": "/products", "set": "/nbproduct" }, { "op": "copy", "from": "/products/0", "path": "/product"} ] }'></div>
-
wait=true
If the JSON manager need to wait to receive patches from another plugin, like urlmapping. Note that in this mode you can also specified a series of default patches to apply through setting the configurationpatches
<div id="jmexample1" data-wb-jsonmanager='{ "url": "data/data-1.json", "name": "example1", "wait": true }'></div>
-
- Configure your patches as per the supported operation bellow
Note: The json manager can not be set on the same element that listen to wb.jsonfetch
event, like data json.
Using Dataset
To refer at a dataset, it is quite similar to a JSON pointer. But you start with a bracket "[", followed by the dataset name, then by the closing bracket "]" and the rest is the JSON pointer to navigate in the dataset. You can find read about JSON Pointer in the RFC6901 spec or in the data-json plugin documentation.
#[DatasetName]/JSON/Pointer
JSON patches operation
JSON operation is defined as per RFC6002 - JavaScript Object Notation (JSON) Patch with additional operation to fullfill the needs of the JSON manager. Described in the documentation, the following operation are supported: add
, remove
, replace
, move
, copy
, test
, wb-count
, wb-first
, wb-last
, wb-toDateISO
and wb-toDateTimeISO
. The operation that start with "wb" are custom operation defined inside the JSON manager
In the description bellow when it refering to :
<path>
- That represents a string containing a valid JavaScript Object Notation (JSON) Pointer [RFC6901]. You can find JSON pointer example in the data-json working example under "Selecting data" heading.
<value>
- A valid value, it could be a number, a string, a JSON object or a JSON array.
You will find a few examples in the Appendix A of RFC6002
Operation | Syntax | What it's does |
---|---|---|
Add | { "op": "add", "path": <path>, "value": <value> } |
Performs one of the following functions, depending upon what the target location references:
For adding in an array, you may finish the path by |
Remove | { "op": "remove", "path": <path> } |
Removes the value at the target location. |
Replace | { "op": "replace", "path": <path>", "path": <value> } |
Replaces the value at the target location with a new value. |
Move | { "op": "move", "from": <path>, "path": <path> } |
Removes the value at a specified location and adds it to the target location. |
Copy | { "op": copy, "from": <path>, "path": <path> } |
Copies the value at a specified location to the target location. |
Test | { "op": "test", "path": <path>, "value": <value> } |
Tests that a value at the target location is equal to a specified value. On failing, it would result in no changes being made. Note by using test operation, it makes the pathes atomic. So that means that is one test operation fail, nothing will be executed otherwise all operation get executed. The execution of any test operation are prioritized before any other operation. |
Counting items | { "op": "wb-count", "path": <path>, "set": <path> } |
Count the number of items in an array and copy the value at a specified location. Filter can be used to count a specific subset. |
Counting items with filter | { "op": "wb-count", "path": <path>, "set": <path>, "filter": <evaluation object>, "filternot": <evaluation object> } |
Both attribute |
First item | { "op": "wb-first", "path": <path>, "set": <path> } |
Copy the first item from an array at a specified location. |
Last item | { "op": "wb-last", "path": <path>, "set": <path> } |
Copy the last item from an array at a specified location. |
Formatting a number | { "op": "wb-nbtolocal", "path": <path> } |
Replace the number at the <path> location that represents the number value formatted according to the conventions of the host environment's current locale. Additional setting:
|
Get output from Base64 (UTF-8) | { "op": "wb-decodeUTF8Base64", "path": <path> } or { "op": "wb-decodeUTF8Base64", "path": <path>, "set": <path> } |
Decodes Base64 content to raw format according to the source at the path location and copy the value at a specified location. If set is not defined, it will be the value located at path that will be replaced. |
Escape HTML | { "op": "wb-escapeHTML", "path": <path> } or { "op": "wb-escapeHTML", "path": <path>, "set": <path> } |
Escapes HTML characters from content located in the path and copy the value at a specified location. If set is not defined, it will be the value located at path that will be replaced. |
Formating a date to ISO (YYYY-MM-DD) | { "op": "wb-toDateISO", "path": <path> } or { "op": "wb-toDateISO", "path": <path>, "set": <path> } |
Format a date value to data ISO and copy the value at a specified location. If set is not defined, it will be the value located at path that will be replaced. |
Formating a date and time to ISO (YYYY-MM-DD HH:MM) | { "op": "wb-toDateTimeISO", "path": <path> } or { "op": "wb-toDateTimeISO", "path": <path>, "set": <path> } |
Format a date value to date time ISO and copy the value at a specified location. If set is not defined, it will be the value located at path that will be replaced. |
Swap data with reference | { "op": "wb-swap", "path": <path to current value>, "ref": <path to reference value> } |
Swaps data from "path" with data from "ref", using either the value as a key in the reference or the value set matching the @id property in an array of objects in the reference. The value from "path" can either be a string or an array. |
Patches | { "op": "patches", "path": <path>, "patches": [Array of patches] } |
Executes list of patches defined in the "patches" array using a newly defined "path". This "path" must be located inside the JSON object defined at "url". Use if you need to execute patches to an array of objects but still need to have access to the global JSON object. For example, when using "wb-swap" |
It's is possible to add your own custom operations, like:
window[ "wb-jsonmanager" ] = {
ops: [
{
name: "wb-count",
fn: function( obj, key, tree ) {
var countme = obj[ key ],
len = 0;
if ( $.isArray( countme ) ) {
len = countme.length;
}
jsonpatch.apply( tree, [
{ op: "add", path: this.set, value: len }
] );
}
},
{
name: "wb-first",
fn: function( obj, key, tree ) {
var currObj = obj[ key ];
if ( !$.isArray( currObj ) || currObj.length === 0 ) {
return;
}
jsonpatch.apply( tree, [
{ op: "add", path: this.set, value: currObj[ 0 ] }
] );
}
}
],
opsArray: [ ],
opsRoot: [ ],
}
There is tree type of configuration where you can defined your custom operation depending on what the operation is executed.
ops
- Basic operation on a JSON node.
opsArray
- Operation made upon JSON array.
opsRoot
- Operation that target the root of JSON object.
Debugging
You can set the configuration option "debug": true
to show, added the element that call the JSON manager, the modified JSON object and his applied patches. The JSON are displayed without any formating.
<div data-wb-jsonmanager='{
"url": "data-en.json",
"name": "example2",
"debug": true
}'></div>
Cache busting
Before to use the cache busting mechanism with your data json instance, it's highly recommended to configure your server properly instead.
Various strategy can be set on the server side and those are communicated to the browser through an http header as defined in section 5 of RFC7234.
Configuration options
Option | Description | How to configure | Values |
---|---|---|---|
url |
Required. Define the url or the dataset name to use. When used in a template mode, the URL should point to an array object. | You can follow the url or the dataset name by a JSON Pointer (RFC6901). The value can be either a string or an array of strings. If all references are arrays, the arrays will be concatenated into one array. If all references are objects, the objects will be extended into a single object. If there are references of multiple types, the plugin will throw an error. |
|
name |
Required. The dataset name that other plugin will be able to use as an alias to a JSON file. | data-wb-jsonmanager='{ "url": "", "name": "ADataSetName" }' |
String |
wait |
Indicate if plugins that use the named dataset should wait to display information until all patches is received. | data-wb-jsonmanager='{ "url": "", "name": "ADataSetName", "wait": true }' |
Boolean
|
patches |
Array of patches, operation object, to be applied to the JSON | data-wb-jsonmanager='{ "url": "", "name": "ADataSetName", "patches": [ {operation object} ] }' |
Array of operation object or a unique operation object |
{Operation object} |
Object structured as per RFC6002 specification. | data-wb-jsonmanager='{ "url": "", "name": "ADataSetName", "patches": [ { "op": "Name of the operation", (any additional parameter as per the operation) } ] }' |
See section 4 of RFC6902. All the supported operation is defined above in the section JSON patches operation. |
wraproot |
Name of a property where to move the JSON root into. | data-wb-jsonmanager='{ "url": "", "name": "ADataSetName", "wraproot": "root" }' |
|
fpath |
Base JSON pointer path to an array [] where the specified filter must be applied. |
data-wb-jsonmanager='{ "url": "file.json", "name": "ADataSetName", "fpath": "/myArray", "filter": [ ... ]' |
|
filter |
Available for when selecting array only. Item that is true will be kept and item that is false will be removed. The fpath configuration must be set also. |
data-wb-jsonmanager='{ "url": "", "filter": [ {evaluation object} ] }' |
Evaluation object have the following property
There is more details in the filter section bellow |
filternot |
Available for when selecting array only. Item that is true will be removed and item that is false will be kept. This filter happen after the configuration for the "filter" option has been evaluated. The fpath configuration must be set also. |
data-wb-jsonmanager='{ "url": "", "filternot": [ {evaluation object} ] }' |
Evaluation object have the following property
There is more details in the filter section bellow |
debug |
Show the modified JSON object and his applied patches after there are applied. | data-wb-jsonmanager='{ "url": "", "name": "ADataSetName", "wraproot": "root" }' |
Boolean
|
nocache |
Prevent caching. Prior using the functionality, use the various caching strategies that can be set and communicated through http header from your server, as defined in section 5 of RFC7234. Also, please note that some server may not like to have an query appended to his url and you may get an HTTP error like "400 Bad Request" or "404 Not Found". Like a page served by a domino server will return 404 error if the query string do not start with "?open ", "?openDocument " or "?readForm ". |
data-wb-json='{ "url": "", "nocache": true }' or data-wb-json='{ "url": "", "nocache": "nocache" }' |
|
nocachekey |
Prevent caching. Optional, it defined what query parameter name to use for the cache busting. | data-wb-json='{ "url": "", "nocache": true, "nocachekey": "wbCacheBust" }' |
|
data |
Add parameter in the request body. | data-wb-json='{ "url": "", "data": { "prop": "value" } }' or data-wb-json='{ "url": "", "data": "prop=value" } }' |
|
contenttype |
Set the content type of the request body when data are sent | data-wb-json='{ "url": "", "contenttype": "text/turtle", "data": "" }' |
|
method |
Set the HTTP method to be use when fetching the resource. | data-wb-json='{ "url": "", "data": "", "method": "PUT" }' |
|
extractor |
To be used when the dataset is build from the curent page and no JSON url is provided. Array of objects containing html selectors with their specific paths. |
data-wb-jsonmanager='{ "name": "ex1", "extractor": ' [ { selector object, (any additional parameter as per the extraction type) } ] }' |
The selector object can have the following properties
|
URL advanced configuration (Url fetch object)
An object representing the URL to be fetch with some advanced configuration on how to fetch and merge the file specified by the URL into the JSON manager.
Option | How to configure | Values and clarification |
---|---|---|
url |
{ "url": "location/of/json/file.json#/" …} or { "url": "[datasetName]#/" …} |
Required. Define the url or the dataset name to use. When used in a template mode, the URL should point to an array object. You can follow the url or the dataset name by a JSON Pointer (RFC6901). The value can be either a string or an array of strings. If all references are arrays, the arrays will be concatenated into one array. If all references are objects, the objects will be extended into a single object. If there are references of multiple types, the plugin will throw an error. |
path |
{ "url": "location/of/json/file.json#/", "path": "/JSON Pointer" } |
A valid JSON Pointer (RFC6901) to where the data would be inserted. It's must start with an "/". |
Filtering (evaluation object)
The path selector must point to an valid JSON array object. All the option presented in the table bellow can be combined.
The configuration option fpath
must be set in the JSON manager configuration in order to apply any filtering.
Option | How to configure | Values and clarification |
---|---|---|
path |
{ "filter": [ { "path": "/JSON Pointer" } ] …} or { "filternot": [ { "path": "/JSON Pointer" } ] …} |
A valid JSON Pointer (RFC6901) to the data being evaluated.. It's must start with an "/". |
value |
{ "filter": [ { "value": "A value" } ] …} or { "filternot": [ { "value": "A value" } ] …} |
Any value that could be compared with the information retreived form the path. An exact match is performed. |
optional |
{ "filter": [ { "optional": true } ] …}' or { "filternot": [ { "optional": true } ] …}' |
True or false. If omited it will be false by default. |
Extractor (selector object)
Option | How to configure | Values and clarification |
---|---|---|
selector |
{ "extractor": [ { "selector": "h2" } ] …} or { "extractor": [ { "selector": "dl[data-dl]" } ] …} |
A valid css selector for any html element from the page |
path |
{ "extractor": [ { "path": "firstH2" } ] …} or { "extractor": [ { "path": "myGroup" } ] …} |
The value of this property will be the pointer in the JSON object dataset that will be created |
selectAll |
{ "extractor": [ { "selectAll": true } ] …} |
If true, it will search in the page for all the html elements indicated in the selector property |
attr |
{ "extractor": [ { "attr":"data-td" } ] …} |
If present, it will collect the value from the specified attribute for the mentioned selector instead of the text value of the selector property |
interface |
{ "extractor": [ { "interface":"referer" } ] …} or { "extractor": [ { "interface":"locationHref" } ] …} |
If present, it will collect the value from predefined properties as follows (This list is not exhaustive):
|
extractor |
{ "extractor": [ { "extractor":[ { "selector": "dt", "path": "title", "attr":"data-td" }, { "selector": "dd", "path": "desc" }] } ] …} |
Used for combined selectors e.g. description lists. Same configuration as for outer extractor option, it is an array of objects containing html selectors with their specific paths. |
Events
Event | Trigger | What it does |
---|---|---|
patches.wb-jsonmanager |
Triggered manually via javascript or automatically via other plugin that interact with the JSON manager.
Where supporting the following event property:
|
Apply patches to the dataset and will send a request to update the content of all plugin that are binded to this dataset. |
postpone.wb-jsonmanager |
Triggered automatically by the json fetch plugin to let the JSON manager that other plugin depends on it. | Postpone the json fetch call until the dataset is ready. |
wb-init.wb-jsonmanager |
Triggered manually (e.g., $( ".wb-jsonmanager" ).trigger( "wb-init.wb-jsonmanager" ); ). |
Used to manually initialize the wb-jsonmanager plugin. Note: The wb-jsonmanager plugin will be initialized automatically unless the required markup is added after the page has already loaded. |
wb-ready.wb-jsonmanager |
Triggered automatically after an wb-jsonmanager is initialized. | Used to identify when an wb-jsonmanager has initialized (target of the event)
|
wb-ready.wb |
Triggered automatically when WET has finished loading and executing. | Used to identify when all WET plugins and polyfills have finished loading and executing.
|
Source code
- Date modified: