Gestionnaire JSON - Documentation

Questions ou commentaires?

Needs translation

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.

  1. 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>
  2. 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 configuration patches
      <div id="jmexample1" data-wb-jsonmanager='{
      			"url": "data/data-1.json",
      			"name": "example1",
      			"wait": true
      		}'></div>
  3. 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:

  • If the target location specifies an array index, a new value is inserted into the array at the specified index.
  • If the target location specifies an object member that does not already exist, a new member is added to the object.
  • If the target location specifies an object member that does exist, that member's value is replaced.

For adding in an array, you may finish the path by "/0" to prepend and "/-" to append the value.

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 filter and filternot are optional. They will contain an array of "evaluation object" or one evaluation object defined in the filtering sub section of "Configuration options" bellow.

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:

locale
Default is the current page language. You can set any valid locale. { "op": "wb-nbtolocal", "path": <path> "locale": "fr-CA" }
prefix
Default: empty string. This prepend a string before the formatted number. { "op": "wb-nbtolocal", "path": <path> "suffix": "$CAN " }
suffix
Default: empty string. This append a string after the formatted number. { "op": "wb-nbtolocal", "path": <path> "suffix": "$ CAN" }
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.
data-wb-jsonmanager='{ "url": "location/of/json/file.json#/" }'
The url is a json file.
data-wb-jsonmanager='{ "url": "[datasetName]#/" }'
The url is a reference to a dataset managed by a json-manager defined in the same page.
data-wb-jsonmanager='{ "url": [ "location/of/json/file.json#/", "[datasetName]#/" ] }'
The url is a json file and a reference to a dataset managed by a json-manager defined in the same page. The dataset will be a combination of both references.
data-wb-jsonmanager='{ "url": {Url fetch object} }'

An object defining advanced configuration on how to fetch and merge the file specified by the URL into the JSON manager.

There is more details in the section below.

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
false (default)
Will execute the patches when the plugin is initialized
true
Will wait to notify plugins that use the named dataset, until patches is received throught the event patches.wb-jsonmanager.
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" }'
false (default)
Keep the JSON as it
String
Will create a new property, as named by the string value, then move the root into that property.
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": [ ... ]'
false (default)
No filtering will be applied
String
JSON pointer to the array where the data filtering must be applied
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

path
Required. JSON pointer to the data being evaluated
value
Required. Value of witch the data would be evaluated
optional
Indicated if the evaluation is optional.

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

path
Required. JSON pointer to the data being evaluated
value
Required. Value of witch the data would be evaluated
optional
Indicated if the evaluation is optional.

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
false (default)
There is no debug info that is displayed
true
Will display a unformated result.
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" }'
Default
The browser will manage the cache based on how the server has sent the file.
true
Boolean, Use the same cache buster id for the user session. Clossing and opening the tab should generate a new cache busting id.
nocache
String, A new id is generated everytime the file is fetched
nocachekey Prevent caching. Optional, it defined what query parameter name to use for the cache busting. data-wb-json='{ "url": "", "nocache": true, "nocachekey": "wbCacheBust" }'
Default
Will use "wbCacheBust" for the parameter name.
String
URL pre-encoded string
data Add parameter in the request body. data-wb-json='{ "url": "", "data": { "prop": "value" } }' or data-wb-json='{ "url": "", "data": "prop=value" } }'
Default
No data are sent in the request body
String
The value is sent as is in the request body
Javascript Object
The value is stringify before to be added to the request body
contenttype Set the content type of the request body when data are sent data-wb-json='{ "url": "", "contenttype": "text/turtle", "data": "" }'
Default
When data is added, application/json
String
A valid content type as defined in the IANA media type registry.
method Set the HTTP method to be use when fetching the resource. data-wb-json='{ "url": "", "data": "", "method": "PUT" }'
Default (no data)
The method is "GET".
Default (with data)
The method is "POST".
String
A valid method allowed by the browser.
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

selector
Indicate what html element to be selected from the page
path
Required. JSON pointer to the data being evaluated
selectAll
Indicate if should extract all html elements specified in the selector. If not used, it will extract only the first founded.
attr
Indicate if the value should be extracted from the specified tag attribute instead of the specified tag text
interface
Predefined properties that will store the values from: the document.referrer for referer", location.href for locationHref
extractor
Used for combined selectors e.g. description lists. Same principle as for extractor configuration option, it is an array of objects containing html selectors with their specific paths.

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):
  • referer is assigned for the document.referrer value
  • locationHref is assigned for location.href value
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.

$( "#MyJsonManager" ).trigger(  {
	type: "patches.wb-jsonmanager",
	patches: [ { JSON patached operation object } ]
} );

Where supporting the following event property:

patches
(Required) Array of or a single JSON patches operation.
cumulative
Boolean. Default (false) If true the patches applied for this one event will be cumulative and impact subsequent applied patches.
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-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)
$( document ).on( "wb-ready.wb-jsonmanager", ".wb-jsonmanager", function( event ) {
});
$( ".wb-jsonmanager" ).on( "wb-ready.wb-jsonmanager", function( 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.
$( document ).on( "wb-ready.wb", function( event ) {
});

Source code

JSON manager plugin source code on GitHub

Date de modification :