Extension:Jsoner

The Jsoner extension allows to read JSON APIs to filter and transform data as well as display it.

It was developed by Jonas Gröger while working at noris network AG. Therefore this extension is property of noris network AG but licensed under the GPL version 3.

= TL;DR (MW 1.25+) =

Install,  ,   and   for PHP. Put this in your :

{   &quot;require&quot;: { &quot;noris/jsoner&quot;: &quot;~1.0&quot; } } and run. Then, append this to your LocalSettings.php:

wfLoadExtension( 'Jsoner' ); $jsonerBaseUrl = 'https://example.com/api/'; $jsonerUser = '&lt;your_user&gt;'; $jsonerPass = '&lt;your_pass&gt;';

= Jsoner =

This is a MediaWiki extension that allows one to embed external JSON data (i.e. from a REST API) into an article.

Requirements
This extension requires at least  and the following PHP extensions:


 * curl
 * fileinfo
 * intl
 * mbstring

Using Debian / Ubuntu you can install the extensions like this:

sudo apt-get install php5-curl php5-intl sudo service apache2 restart To test if they are enabled (use your php.ini):

$ php5 --php-ini /etc/php5/apache2/php.ini -m | grep -E 'fileinfo|mbstring|intl|curl' curl fileinfo intl mbstring

Download (recommended, with Composer)
Put this to your :

{   &quot;require&quot;: { &quot;noris/jsoner&quot;: &quot;~1.0&quot; } } and run  (or   if you don't have a composer.lock yet).

Download (not recommended, manually)
Download the extension and put it in your  folder.

Add to MediaWiki
To enable this extension, add this to your :

wfLoadExtension( 'Jsoner' ); This will enable the Jsoner extension and add the following functions to the MediaWiki parser:


 * with parameters  and filters, see below.

Configuration
The extension has multiple settings. Please put them after the.

$jsonerBaseUrl (default = null)
$jsonerBaseUrl = 'https://example.com/api/'; This can be used to prefix all  calls (the   argument specifically) with this url so that you don't have to repeat yourself, if you only consume data from one domain. If omitted, you have to provide complete domains in.

$jsonerUser / $jsonerPass (default = null)
$jsonerUser = '&lt;your_user&gt;'; $jsonerPass = '&lt;your_pass&gt;'; If both are set, this is passed to cURL to authenticate. If omitted, cURL tries unauthenticated.

Usage
Jsoner has a pipes and filters architecture. First, data is fetched, then filters are applied and finally, the data is transformed in a representation.

Fetch → [Filter ...] → Transformer This looks like this in MediaWiki syntax:

// Fetch        → Filter              → Filter                  → Transformer Lets run something interesting:

↓

[   {        &quot;base_stat&quot;: 45, &quot;effort&quot;: 0, &quot;stat&quot;: { &quot;name&quot;: &quot;speed&quot;, &quot;url&quot;: &quot;http://pokeapi.co/api/v2/stat/6/&quot; }   },    {        &quot;base_stat&quot;: 65, &quot;effort&quot;: 0, &quot;stat&quot;: { &quot;name&quot;: &quot;special-defense&quot;, &quot;url&quot;: &quot;http://pokeapi.co/api/v2/stat/5/&quot; }   },    {        &quot;base_stat&quot;: 65, &quot;effort&quot;: 1, &quot;stat&quot;: { &quot;name&quot;: &quot;special-attack&quot;, &quot;url&quot;: &quot;http://pokeapi.co/api/v2/stat/4/&quot; }   },    {        &quot;base_stat&quot;: 49, &quot;effort&quot;: 0, &quot;stat&quot;: { &quot;name&quot;: &quot;defense&quot;, &quot;url&quot;: &quot;http://pokeapi.co/api/v2/stat/3/&quot; }   },    {        &quot;base_stat&quot;: 49, &quot;effort&quot;: 0, &quot;stat&quot;: { &quot;name&quot;: &quot;attack&quot;, &quot;url&quot;: &quot;http://pokeapi.co/api/v2/stat/2/&quot; }   },    {        &quot;base_stat&quot;: 45, &quot;effort&quot;: 0, &quot;stat&quot;: { &quot;name&quot;: &quot;hp&quot;, &quot;url&quot;: &quot;http://pokeapi.co/api/v2/stat/1/&quot; }   } ] As you can see, Filters are prefixed with   and Transformers are prefixed with.

Available Filters
A typical call looks like this

CensorKeysFilter
Runs on a list and returns a list. Usage:

Example:

[ {    &quot;name&quot;: &quot;Bob&quot;, &quot;email&quot;: &quot;bob@example.com&quot; }, {    &quot;name&quot;: &quot;Tom&quot;, &quot;email&quot;: &quot;tom@example.com&quot; } ]  ↓ [  {    &quot;name&quot;: &quot;Bob&quot;, &quot;email&quot;: &quot;--protected--&quot; }, {    &quot;name&quot;: &quot;Tom&quot;, &quot;email&quot;: &quot;--protected--&quot; } ]

ReduceKeysFilter
Runs on a list and returns a list. Usage:

Example:

[ {    &quot;id&quot;: &quot;1&quot;, &quot;data&quot;: { &quot;email&quot;: &quot;bob@example.com&quot;, &quot;city&quot;: &quot;Berlin&quot; } },  {    &quot;id&quot;: 2, &quot;data&quot;: { &quot;email&quot;: &quot;tom@example.com&quot;, &quot;city&quot;: &quot;Hamburg&quot; } } ]

↓

[ {    &quot;id&quot;: &quot;1&quot;, &quot;data&quot;: { &quot;email&quot;: &quot;bob@example.com&quot;, &quot;city&quot;: &quot;Berlin&quot; },   &quot;mail&quot;: &quot;bob@example.com&quot; }, {    &quot;id&quot;: 2, &quot;data&quot;: { &quot;email&quot;: &quot;tom@example.com&quot;, &quot;city&quot;: &quot;Hamburg&quot; },   &quot;mail&quot;: &quot;tom@example.com&quot; } ]

RemoveKeysFilter
Runs on a list and returns a list. Usage:

Example:

[ {    &quot;name&quot;: &quot;Bob&quot;, &quot;email&quot;: &quot;bob@example.com&quot; }, {    &quot;name&quot;: &quot;Tom&quot;, &quot;email&quot;: &quot;tom@example.com&quot; } ] ↓ [ {    &quot;name&quot;: &quot;Bob&quot; }, {    &quot;name&quot;: &quot;Tom&quot; } ]

SelectKeysFilter
Runs on a list and returns a list. Usage:

Example:

[ {    &quot;name&quot;: &quot;Bob&quot;, &quot;email&quot;: &quot;bob@example.com&quot; }, {    &quot;name&quot;: &quot;Tom&quot;, &quot;email&quot;: &quot;tom@example.com&quot; } ]

↓

[ {    &quot;email&quot;: &quot;bob@example.com&quot; }, {    &quot;email&quot;: &quot;tom@example.com&quot; } ]

SelectSubtreeFilter
Runs on an object and returns a list. Usage:

Example:

{ &quot;recordCount&quot;: 2, &quot;records&quot;: [ {     &quot;name&quot;: &quot;Bob&quot;, &quot;email&quot;: &quot;bob@example.com&quot; },   {      &quot;name&quot;: &quot;Tom&quot;, &quot;email&quot;: &quot;tom@example.com&quot; } ] }

↓

[ {    &quot;name&quot;: &quot;Bob&quot;, &quot;email&quot;: &quot;bob@example.com&quot; }, {    &quot;name&quot;: &quot;Tom&quot;, &quot;email&quot;: &quot;tom@example.com&quot; } ]

Available Transformers
There must be always a transformer at the end of the pipeline.

InlineListTransformer
Creates a comma-separated list of values from a list.

Usage:

With a list as input, calling

[ {    &quot;name&quot;: &quot;Bob&quot;, &quot;email&quot;: &quot;bob@example.com&quot; }, {    &quot;name&quot;: &quot;Tom&quot;, &quot;email&quot;: &quot;tom@example.com&quot; } ]

↓

bob@example.com, tom@example.com Good for, you guessed it: lists!

JsonDumpTransformer
Dumps the JSON data into a  tag. Nice for debugging.

SingleElementTransformer
Returns a single JSON value out of an object or a list. If the input is a list, the SingleElementTransformer will use the first element in the list to display something.

Usage:

With a list as input, calling

[ {    &quot;name&quot;: &quot;Bob&quot;, &quot;email&quot;: &quot;bob@example.com&quot; }, {    &quot;name&quot;: &quot;Tom&quot;, &quot;email&quot;: &quot;tom@example.com&quot; } ]

↓

Bob With an object as input, calling

{   &quot;name&quot;: &quot;Bob&quot;, &quot;email&quot;: &quot;bob@example.com&quot; }

↓

Bob Nice for single values like IDs.

StackedElementTransformer
Creates a  separated (on top of each other) stack out of an object or a list. If the input is a list, the StackedElementTransformer uses the first element in the list and displays that.

With a list as input:

[ {    &quot;name&quot;: &quot;Bob&quot;, &quot;email&quot;: &quot;bob@example.com&quot; }, {    &quot;name&quot;: &quot;Tom&quot;, &quot;email&quot;: &quot;tom@example.com&quot; } ]

↓

Bob bob@example.com With an object as input:

{   &quot;name&quot;: &quot;Tom&quot;, &quot;email&quot;: &quot;tom@example.com&quot; }

↓

Tom tom@example.com Useful for address data.

WikitextTableTransformer
Creates a nice and sortable Wikitext table out of a list of objects.

[ {    &quot;name&quot;: &quot;Bob&quot;, &quot;email&quot;: &quot;bob@example.com&quot; }, {    &quot;name&quot;: &quot;Tom&quot;, &quot;email&quot;: &quot;tom@example.com&quot; } ]

↓

╔════════╦═════════════════╗ ║ name ▼ ║ email        ▼ ║ ╠════════╬═════════════════╣ ║ Bob   ║ bob@example.com ║ ║ Tom   ║ tom@example.com ║ ╚════════╩═════════════════╝

Limitations

 * If you set  and , the authentification is used for every request. There is currently no per-domain or per-request level setting for username and password (and maybe rightfully so). One possibility would be to put a separate call, like   or something like that.

Development
This extension is under development. Anything may change.

You can clone is using

git clone git@github.com:noris-network/Jsoner.git &amp;&amp; cd Jsoner make devenv To install it into your development MediaWiki, just symlink it to your  folder

cd /path/to/your/extensions/folder ln -s /path/to/the/Jsoner/extension Jsoner Then, install it like described above.
 * 1) Assuming you are in Jsoner folder

To see what you can do run one of

make make help To test, you can run

make test To fix warnings etc. from, you can run:

make fix To clean, you can run

make clean

License
GPL version 3