PHPackages                             noris/jsoner - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. noris/jsoner

ActiveMediawiki-extension[Utility &amp; Helpers](/categories/utility)

noris/jsoner
============

1.1.10(4y ago)01792[3 issues](https://github.com/noris-network/jsoner/issues)GPL-3.0PHPPHP &gt;=5.6CI failing

Since Apr 15Pushed 4y ago15 watchersCompare

[ Source](https://github.com/noris-network/jsoner)[ Packagist](https://packagist.org/packages/noris/jsoner)[ RSS](/packages/noris-jsoner/feed)WikiDiscussions master Synced 2mo ago

READMEChangelog (1)Dependencies (6)Versions (10)Used By (0)

TL;DR (MW 1.25+)
================

[](#tldr-mw-125)

Install `curl`, `fileinfo`, `intl` and `mbstring` for PHP. Put this in your `composer.local.json`:

```
{
    "require": {
        "noris/jsoner": "~1.0"
    }
}

```

and run `composer update`. Then, append this to your LocalSettings.php:

```
wfLoadExtension( 'Jsoner' );
$jsonerBaseUrl = 'https://example.com/api/';
$jsonerUser = '';
$jsonerPass = '';

```

Jsoner
======

[](#jsoner)

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

Requirements
------------

[](#requirements)

This extension requires at least `PHP >= 5.6` 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

```

Installation
------------

[](#installation)

### Download (recommended, with Composer)

[](#download-recommended-with-composer)

Put this to your `composer.local.json`:

```
{
    "require": {
        "noris/jsoner": "~1.0"
    }
}

```

and run `composer update` (or `composer install` if you don't have a composer.lock yet).

### Download (not recommended, manually)

[](#download-not-recommended-manually)

Download the extension and put it in your `extension/` folder.

### Add to MediaWiki

[](#add-to-mediawiki)

To enable this extension, add this to your `LocalSettings.php`:

```
wfLoadExtension( 'Jsoner' );

```

This will enable the Jsoner extension and add the following functions to the MediaWiki parser:

- `#jsoner` with parameters `url` and filters, [see below](#available-filters).

Configuration
-------------

[](#configuration)

The extension has multiple settings. Please put them after the `wfLoadExtension( 'Jsoner' );`.

### $jsonerBaseUrl (default = null)

[](#jsonerbaseurl-default--null)

```
$jsonerBaseUrl = 'https://example.com/api/';

```

This can be used to prefix all `#jsoner` calls (the `url` 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 `url`.

### $jsonerUser / $jsonerPass (default = null)

[](#jsoneruser--jsonerpass-default--null)

```
$jsonerUser = '';
$jsonerPass = '';

```

If both are set, this is passed to cURL to authenticate. If omitted, cURL tries unauthenticated.

Usage
-----

[](#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
{{ #jsoner:url=… | f-SelectSubtree=foo | f-SelectKeys=name,email | t-JsonDump }}

```

Lets run something interesting:

```
{{ #jsoner:url=http://pokeapi.co/api/v2/pokemon/1/ | f-SelectSubtree=stats | t-JsonDump }}

↓

[
    {
        "base_stat": 45,
        "effort": 0,
        "stat": {
            "name": "speed",
            "url": "http://pokeapi.co/api/v2/stat/6/"
        }
    },
    {
        "base_stat": 65,
        "effort": 0,
        "stat": {
            "name": "special-defense",
            "url": "http://pokeapi.co/api/v2/stat/5/"
        }
    },
    {
        "base_stat": 65,
        "effort": 1,
        "stat": {
            "name": "special-attack",
            "url": "http://pokeapi.co/api/v2/stat/4/"
        }
    },
    {
        "base_stat": 49,
        "effort": 0,
        "stat": {
            "name": "defense",
            "url": "http://pokeapi.co/api/v2/stat/3/"
        }
    },
    {
        "base_stat": 49,
        "effort": 0,
        "stat": {
            "name": "attack",
            "url": "http://pokeapi.co/api/v2/stat/2/"
        }
    },
    {
        "base_stat": 45,
        "effort": 0,
        "stat": {
            "name": "hp",
            "url": "http://pokeapi.co/api/v2/stat/1/"
        }
    }
]

```

As you can see, Filters are prefixed with `f-` and Transformers are prefixed with `t-`.

Available Filters
-----------------

[](#available-filters)

A typical call looks like this

```
{{ #jsoner:url=… | f-SelectSubtree=foo | }}

```

### CensorKeysFilter (`f-CensorKeys`)

[](#censorkeysfilter-f-censorkeys)

Runs on a list and returns a list. Usage: [`f-CensorKeys=key(,key)*,replacement`](http://regexr.com/3d0vn)

Example: `f-CensorKeys=email,--protected--`

```
[
  {
    "name": "Bob",
    "email": "bob@example.com"
  },
  {
    "name": "Tom",
    "email": "tom@example.com"
  }
]

↓

[
  {
    "name": "Bob",
    "email": "--protected--"
  },
  {
    "name": "Tom",
    "email": "--protected--"
  }
]

```

### ReduceKeysFilter (`f-Reduce`)

[](#reducekeysfilter-f-reduce)

Runs on a list and returns a list. Usage: [`f-Reduce=(\w+),(\w+)(\.\w+)*`](http://regexr.com/3d5kp)

Example: `f-Reduce=mail,data.email`

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

↓

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

```

### RemoveKeysFilter (`f-RemoveKeys`)

[](#removekeysfilter-f-removekeys)

Runs on a list and returns a list. Usage: [`f-RemoveKeys=key(,key)*`](http://regexr.com/3d0vt)

Example: `f-RemoveKeys=email`

```
[
  {
    "name": "Bob",
    "email": "bob@example.com"
  },
  {
    "name": "Tom",
    "email": "tom@example.com"
  }
]

↓

[
  {
    "name": "Bob"
  },
  {
    "name": "Tom"
  }
]

```

### SelectKeysFilter (`f-SelectKeys`)

[](#selectkeysfilter-f-selectkeys)

Runs on a list and returns a list. Usage: [`f-SelectKeys=key(,key)*`](http://regexr.com/3d100)

Example: `f-SelectKeys=email`

```
[
  {
    "name": "Bob",
    "email": "bob@example.com"
  },
  {
    "name": "Tom",
    "email": "tom@example.com"
  }
]

↓

[
  {
    "email": "bob@example.com"
  },
  {
    "email": "tom@example.com"
  }
]

```

### SelectSubtreeFilter (`f-SelectSubtree`)

[](#selectsubtreefilter-f-selectsubtree)

Runs on an object and returns a list. Usage: [`f-SelectSubtree=key`](http://regexr.com/3d106)

Example: `f-SelectSubtree=records`

```
{
  "recordCount": 2,
  "records": [
    {
      "name": "Bob",
      "email": "bob@example.com"
    },
    {
      "name": "Tom",
      "email": "tom@example.com"
    }
  ]
}

↓

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

```

### SelectRecordFilter (`f-SelectRecord`)

[](#selectrecordfilter-f-selectrecord)

Runs on a list and returns a list. Usage: \[`f-SelectRecord=key:value`\]

Example: `f-SelectRecord=email:test2@example.com`

```
[
  {
    "name": "Bob",
    "email": "test1@example.com"
  },
  {
    "name": "Tom",
    "email": "test2@example.com"
  }
]

↓

[
  {
	"name": "Tom",
	"email": "test2@example.com"
  }
]

```

Available Transformers
----------------------

[](#available-transformers)

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

### InlineListTransformer (`t-InlineList`)

[](#inlinelisttransformer-t-inlinelist)

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

Usage: `t-InlineList=key`

With a list as input, calling `t-InlineList=email`

```
[
  {
    "name": "Bob",
    "email": "bob@example.com"
  },
  {
    "name": "Tom",
    "email": "tom@example.com"
  }
]

↓

bob@example.com, tom@example.com

```

Good for, you guessed it: lists!

### JsonDumpTransformer (`t-JsonDump`)

[](#jsondumptransformer-t-jsondump)

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

### SingleElementTransformer (`t-SingleElement`)

[](#singleelementtransformer-t-singleelement)

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: `t-SingleElement=key`

With a list as input, calling `t-SingleElement=name`

```
[
  {
    "name": "Bob",
    "email": "bob@example.com"
  },
  {
    "name": "Tom",
    "email": "tom@example.com"
  }
]

↓

Bob

```

With an object as input, calling `t-SingleElement=name`

```
{
    "name": "Bob",
    "email": "bob@example.com"
}

↓

Bob

```

Nice for single values like IDs.

### StackedElementTransformer (`t-StackedElement`)

[](#stackedelementtransformer-t-stackedelement)

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:

```
[
  {
    "name": "Bob",
    "email": "bob@example.com"
  },
  {
    "name": "Tom",
    "email": "tom@example.com"
  }
]

↓

Bob
bob@example.com

```

With an object as input:

```
{
    "name": "Tom",
    "email": "tom@example.com"
}

↓

Tom
tom@example.com

```

Useful for address data.

### WikitextTableTransformer (`t-WikitextTable`)

[](#wikitexttabletransformer-t-wikitexttable)

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

```
[
  {
    "name": "Bob",
    "email": "bob@example.com"
  },
  {
    "name": "Tom",
    "email": "tom@example.com"
  }
]

↓

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

```

### MediaWikiTemplateTransformer (`t-mwTemplate`)

[](#mediawikitemplatetransformer-t-mwtemplate)

Creates Wikitext depending on the given template. You probably have to create a suiting template for the query. Uses key=value pairs.

Wiki-String: {{ template |key=value }}

Usage: `t-mwTemplate=template`

With `t-mwTemplate=jsoner-template`

```
[
  {
    "name": "Bob",
    "email": "bob@example.com"
    "username": "bobexample"
  },
  {
    "name": "Tom",
    "email": "tom@example.com"
    "username": "tomexample"
  }
]

↓

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

```

The output is depending on the template you use.

### MediaWikiTemplateTransformerAnonymous (`t-mwTemplateAnonymous`)

[](#mediawikitemplatetransformeranonymous-t-mwtemplateanonymous)

Creates Wikitext depending on the given template. You probably have to create a suiting template for the query. Doesn't use key=value pairs, uses the Anonymous templating in the Mediawiki. Template in this use case : template= {{{1}}} {{{2}}}

Usage: `t-mwTemplateAnonymous=template`

```
[
  {
    "name": "Bob",
    "email": "bob@example.com"
    "username": "bobexample"
  },
  {
    "name": "Tom",
    "email": "tom@example.com"
    "username": "tomexample"
  }
]

↓

Bob bob@example.com Tom tom@example.com

```

The output is depending on the template you use.

Limitations
-----------

[](#limitations)

- If you set `$jsonerUser` and `$jsonerPass`, 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 `{{ #jsoner-unauth:url=… }}`or something like that.

Development
-----------

[](#development)

This extension is under development. Anything may change.

You can clone is using

```
git clone git@github.com:noris-network/Jsoner.git && cd Jsoner
make devenv

```

To install it into your development MediaWiki, just symlink it to your `extensions` folder

```
# Assuming you are in Jsoner folder
cd /path/to/your/extensions/folder
ln -s /path/to/the/Jsoner/extension Jsoner

```

Then, install it [like described above](#installation).

To see what you can do run one of

```
make
make help

```

To test, you can run

```
make test

```

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

```
make fix

```

To clean, you can run

```
make clean

```

License
-------

[](#license)

GPL v3

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity12

Limited adoption so far

Community17

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 55.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~240 days

Recently: every ~395 days

Total

9

Last Release

1761d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/6b350e63d2cb2dbaba1991b4d0b1b6ad4276d533c0894907cca8f2b2eca81330?d=identicon)[noris](/maintainers/noris)

---

Top Contributors

[![mxrieger](https://avatars.githubusercontent.com/u/66461227?v=4)](https://github.com/mxrieger "mxrieger (5 commits)")[![nxcc](https://avatars.githubusercontent.com/u/73293562?v=4)](https://github.com/nxcc "nxcc (2 commits)")[![JonasGroeger](https://avatars.githubusercontent.com/u/1790638?v=4)](https://github.com/JonasGroeger "JonasGroeger (1 commits)")[![Marco-Kaulea](https://avatars.githubusercontent.com/u/78022140?v=4)](https://github.com/Marco-Kaulea "Marco-Kaulea (1 commits)")

---

Tags

httpjsonmediawikimediawiki-extension

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/noris-jsoner/health.svg)

```
[![Health](https://phpackages.com/badges/noris-jsoner/health.svg)](https://phpackages.com/packages/noris-jsoner)
```

###  Alternatives

[league/uri-components

URI components manipulation library

31932.3M67](/packages/league-uri-components)[php-soap/wsdl

Deals with WSDLs

173.5M12](/packages/php-soap-wsdl)[rainlab/blog-plugin

Blog plugin for October CMS

17257.7k](/packages/rainlab-blog-plugin)[rainlab/builder-plugin

Builder plugin for October CMS

17147.2k1](/packages/rainlab-builder-plugin)[pfefferle/wordpress-activitypub

The ActivityPub protocol is a decentralized social networking protocol based upon the ActivityStreams 2.0 data format.

5671.4k1](/packages/pfefferle-wordpress-activitypub)[civicrm/civicrm-drupal-8

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

18238.1k2](/packages/civicrm-civicrm-drupal-8)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
