{"id":18797472,"url":"https://github.com/noris-network/jsoner","last_synced_at":"2026-01-05T03:31:32.979Z","repository":{"id":48593762,"uuid":"56321378","full_name":"noris-network/Jsoner","owner":"noris-network","description":"MediaWiki extension to embed external JSON data (i.e. from a REST API) into an article.","archived":false,"fork":false,"pushed_at":"2021-07-22T13:46:57.000Z","size":156,"stargazers_count":0,"open_issues_count":2,"forks_count":2,"subscribers_count":17,"default_branch":"master","last_synced_at":"2025-01-26T03:26:24.321Z","etag":null,"topics":["http","json","mediawiki","mediawiki-extension"],"latest_commit_sha":null,"homepage":"https://www.mediawiki.org/wiki/Extension:Jsoner","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/noris-network.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-04-15T13:15:11.000Z","updated_at":"2021-07-22T13:47:00.000Z","dependencies_parsed_at":"2022-08-27T11:33:23.627Z","dependency_job_id":null,"html_url":"https://github.com/noris-network/Jsoner","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noris-network%2FJsoner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noris-network%2FJsoner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noris-network%2FJsoner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noris-network%2FJsoner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/noris-network","download_url":"https://codeload.github.com/noris-network/Jsoner/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244752333,"owners_count":20504254,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["http","json","mediawiki","mediawiki-extension"],"created_at":"2024-11-07T22:08:22.384Z","updated_at":"2026-01-05T03:31:32.935Z","avatar_url":"https://github.com/noris-network.png","language":"PHP","readme":"# TL;DR (MW 1.25+)\n\nInstall `curl`, `fileinfo`, `intl` and `mbstring` for PHP. Put this in your `composer.local.json`:\n\n    {\n        \"require\": {\n            \"noris/jsoner\": \"~1.0\"\n        }\n    }\n    \nand run `composer update`. Then, append this to your LocalSettings.php:\n\n    wfLoadExtension( 'Jsoner' );\n    $jsonerBaseUrl = 'https://example.com/api/';\n    $jsonerUser = '\u003cyour_user\u003e';\n    $jsonerPass = '\u003cyour_pass\u003e';\n\n# Jsoner\n\nThis is a MediaWiki extension that allows one to embed external JSON data (i.e. from\na REST API) into an article.\n\n## Requirements\n\nThis extension requires at least `PHP \u003e= 5.6` and the following PHP extensions:\n\n* curl\n* fileinfo\n* intl\n* mbstring\n\nUsing Debian / Ubuntu you can install the extensions like this:\n\n    sudo apt-get install php5-curl php5-intl\n    sudo service apache2 restart\n\nTo test if they are enabled (use your php.ini):\n\n    $ php5 --php-ini /etc/php5/apache2/php.ini -m | grep -E 'fileinfo|mbstring|intl|curl'\n    curl\n    fileinfo\n    intl\n    mbstring\n\n## Installation\n\n### Download (recommended, with Composer)\n\nPut this to your `composer.local.json`:\n\n    {\n        \"require\": {\n            \"noris/jsoner\": \"~1.0\"\n        }\n    }\n    \nand run `composer update` (or `composer install` if you don't have a composer.lock yet). \n\n### Download (not recommended, manually)\n\nDownload the extension and put it in your `extension/` folder.\n\n### Add to MediaWiki\n\nTo enable this extension, add this to your `LocalSettings.php`:\n\n    wfLoadExtension( 'Jsoner' );\n\nThis will enable the Jsoner extension and add the following functions to the MediaWiki parser:\n\n* `#jsoner` with parameters `url` and filters, [see below](#available-filters).\n\n## Configuration\n\nThe extension has multiple settings. Please put them after the `wfLoadExtension( 'Jsoner' );`. \n\n### $jsonerBaseUrl (default = null)\n\n    $jsonerBaseUrl = 'https://example.com/api/';\n\nThis can be used to prefix all `#jsoner` calls (the `url` argument specifically) with this url\nso that you don't have to repeat yourself, if you only consume data from one domain. If omitted,\nyou have to provide complete domains in `url`.\n\n### $jsonerUser / $jsonerPass (default = null)\n\n    $jsonerUser = '\u003cyour_user\u003e';\n    $jsonerPass = '\u003cyour_pass\u003e';\n\nIf both are set, this is passed to cURL to authenticate. If omitted, cURL tries unauthenticated.\n\n## Usage\n\nJsoner has a pipes and filters architecture. First, data is fetched, then filters are applied and\nfinally, the data is transformed in a representation.\n\n    Fetch → [Filter ...] → Transformer\n    \nThis looks like this in MediaWiki syntax:\n\n    // Fetch         → Filter              → Filter                  → Transformer\n    {{ #jsoner:url=… | f-SelectSubtree=foo | f-SelectKeys=name,email | t-JsonDump }}\n\nLets run something interesting:\n\n    {{ #jsoner:url=http://pokeapi.co/api/v2/pokemon/1/ | f-SelectSubtree=stats | t-JsonDump }}\n    \n    ↓\n    \n    [\n        {\n            \"base_stat\": 45,\n            \"effort\": 0,\n            \"stat\": {\n                \"name\": \"speed\",\n                \"url\": \"http://pokeapi.co/api/v2/stat/6/\"\n            }\n        },\n        {\n            \"base_stat\": 65,\n            \"effort\": 0,\n            \"stat\": {\n                \"name\": \"special-defense\",\n                \"url\": \"http://pokeapi.co/api/v2/stat/5/\"\n            }\n        },\n        {\n            \"base_stat\": 65,\n            \"effort\": 1,\n            \"stat\": {\n                \"name\": \"special-attack\",\n                \"url\": \"http://pokeapi.co/api/v2/stat/4/\"\n            }\n        },\n        {\n            \"base_stat\": 49,\n            \"effort\": 0,\n            \"stat\": {\n                \"name\": \"defense\",\n                \"url\": \"http://pokeapi.co/api/v2/stat/3/\"\n            }\n        },\n        {\n            \"base_stat\": 49,\n            \"effort\": 0,\n            \"stat\": {\n                \"name\": \"attack\",\n                \"url\": \"http://pokeapi.co/api/v2/stat/2/\"\n            }\n        },\n        {\n            \"base_stat\": 45,\n            \"effort\": 0,\n            \"stat\": {\n                \"name\": \"hp\",\n                \"url\": \"http://pokeapi.co/api/v2/stat/1/\"\n            }\n        }\n    ]\n\nAs you can see, Filters are prefixed with `f-` and Transformers are prefixed with `t-`.\n\n## Available Filters\n\nA typical call looks like this\n\n    {{ #jsoner:url=… | f-SelectSubtree=foo | }}\n\n### CensorKeysFilter (`f-CensorKeys`)\n\nRuns on a list and returns a list. Usage: [`f-CensorKeys=key(,key)*,replacement`](http://regexr.com/3d0vn)\n\nExample: `f-CensorKeys=email,--protected--`\n\n    [\n      {\n        \"name\": \"Bob\",\n        \"email\": \"bob@example.com\"\n      },\n      {\n        \"name\": \"Tom\",\n        \"email\": \"tom@example.com\"\n      }\n    ]   \n     \n    ↓\n        \n    [\n      {\n        \"name\": \"Bob\",\n        \"email\": \"--protected--\"\n      },\n      {\n        \"name\": \"Tom\",\n        \"email\": \"--protected--\"\n      }\n    ]\n\n### ReduceKeysFilter (`f-Reduce`)\n\nRuns on a list and returns a list. Usage: [`f-Reduce=(\\w+),(\\w+)(\\.\\w+)*`](http://regexr.com/3d5kp)\n\nExample: `f-Reduce=mail,data.email`\n\n    [\n      {\n        \"id\": \"1\",\n        \"data\": {\n          \"email\": \"bob@example.com\",\n          \"city\": \"Berlin\"\n        }\n      },\n      {\n        \"id\": 2,\n        \"data\": {\n          \"email\": \"tom@example.com\",\n          \"city\": \"Hamburg\"\n        }\n      }\n    ]\n\n    ↓\n    \n    [\n      {\n        \"id\": \"1\",\n        \"data\": {\n          \"email\": \"bob@example.com\",\n          \"city\": \"Berlin\"\n        },\n        \"mail\": \"bob@example.com\"\n      },\n      {\n        \"id\": 2,\n        \"data\": {\n          \"email\": \"tom@example.com\",\n          \"city\": \"Hamburg\"\n        },\n        \"mail\": \"tom@example.com\"\n      }\n    ]\n\n### RemoveKeysFilter (`f-RemoveKeys`)\n\nRuns on a list and returns a list. Usage: [`f-RemoveKeys=key(,key)*`](http://regexr.com/3d0vt)\n\nExample: `f-RemoveKeys=email`\n\n    [\n      {\n        \"name\": \"Bob\",\n        \"email\": \"bob@example.com\"\n      },\n      {\n        \"name\": \"Tom\",\n        \"email\": \"tom@example.com\"\n      }\n    ]\n     \n    ↓\n        \n    [\n      {\n        \"name\": \"Bob\"\n      },\n      {\n        \"name\": \"Tom\"\n      }\n    ]\n\n### SelectKeysFilter (`f-SelectKeys`)\n\nRuns on a list and returns a list. Usage: [`f-SelectKeys=key(,key)*`](http://regexr.com/3d100)\n\nExample: `f-SelectKeys=email`\n\n    [\n      {\n        \"name\": \"Bob\",\n        \"email\": \"bob@example.com\"\n      },\n      {\n        \"name\": \"Tom\",\n        \"email\": \"tom@example.com\"\n      }\n    ]\n\n    ↓\n\n    [\n      {\n        \"email\": \"bob@example.com\"\n      },\n      {\n        \"email\": \"tom@example.com\"\n      }\n    ]\n\n### SelectSubtreeFilter (`f-SelectSubtree`)\n\nRuns on an object and returns a list. Usage: [`f-SelectSubtree=key`](http://regexr.com/3d106)\n\nExample: `f-SelectSubtree=records`\n\n    {\n      \"recordCount\": 2,\n      \"records\": [\n        {\n          \"name\": \"Bob\",\n          \"email\": \"bob@example.com\"\n        },\n        {\n          \"name\": \"Tom\",\n          \"email\": \"tom@example.com\"\n        }\n      ]\n    }\n\n    ↓\n\n    [\n      {\n        \"name\": \"Bob\",\n        \"email\": \"bob@example.com\"\n      },\n      {\n        \"name\": \"Tom\",\n        \"email\": \"tom@example.com\"\n      }\n    ]\n\n### SelectRecordFilter (`f-SelectRecord`)\n\nRuns on a list and returns a list. Usage: [`f-SelectRecord=key:value`]\n\nExample: `f-SelectRecord=email:test2@example.com`\n\n    [\n\t  {\n\t    \"name\": \"Bob\",\n\t    \"email\": \"test1@example.com\"\n\t  },\n\t  {\n\t    \"name\": \"Tom\",\n\t    \"email\": \"test2@example.com\"\n\t  }\n\t]\n\n    ↓\n\n    [\n      {\n\t\t\"name\": \"Tom\",\n\t\t\"email\": \"test2@example.com\"\n\t  }\n    ]\n\n## Available Transformers\n\nThere must be always a transformer at the end of the pipeline.\n\n### InlineListTransformer (`t-InlineList`)\n\nCreates a comma-separated list of values from a list.\n\nUsage: `t-InlineList=key`\n\nWith a list as input, calling `t-InlineList=email`\n\n    [\n      {\n        \"name\": \"Bob\",\n        \"email\": \"bob@example.com\"\n      },\n      {\n        \"name\": \"Tom\",\n        \"email\": \"tom@example.com\"\n      }\n    ]\n    \n    ↓\n    \n    bob@example.com, tom@example.com\n    \nGood for, you guessed it: lists!\n\n### JsonDumpTransformer (`t-JsonDump`)\nDumps the JSON data into a `\u003cpre\u003e` tag. Nice for debugging.\n\n### SingleElementTransformer (`t-SingleElement`)\n\nReturns a single JSON value out of an object or a list. If the input is a list,\nthe SingleElementTransformer will use the first element in the list to display something.\n\nUsage: `t-SingleElement=key`\n\nWith a list as input, calling `t-SingleElement=name`\n\n    [\n      {\n        \"name\": \"Bob\",\n        \"email\": \"bob@example.com\"\n      },\n      {\n        \"name\": \"Tom\",\n        \"email\": \"tom@example.com\"\n      }\n    ]\n    \n    ↓\n    \n    Bob\n    \nWith an object as input, calling `t-SingleElement=name`\n\n    {\n        \"name\": \"Bob\",\n        \"email\": \"bob@example.com\"\n    }\n    \n    ↓\n    \n    Bob\n    \nNice for single values like IDs.\n\n### StackedElementTransformer (`t-StackedElement`)\nCreates a `\u003cbr /\u003e` separated (on top of each other) stack out of an object or a list. If the input\nis a list, the StackedElementTransformer uses the first element in the list and displays that.\n\nWith a list as input:\n\n    [\n      {\n        \"name\": \"Bob\",\n        \"email\": \"bob@example.com\"\n      },\n      {\n        \"name\": \"Tom\",\n        \"email\": \"tom@example.com\"\n      }\n    ]\n    \n    ↓\n    \n    Bob\n    bob@example.com\n    \nWith an object as input:\n\n    {\n        \"name\": \"Tom\",\n        \"email\": \"tom@example.com\"\n    }\n\n    ↓\n    \n    Tom\n    tom@example.com\n\nUseful for address data.\n\n### WikitextTableTransformer (`t-WikitextTable`)\nCreates a nice and sortable Wikitext table out of a list of objects.\n\n    [\n      {\n        \"name\": \"Bob\",\n        \"email\": \"bob@example.com\"\n      },\n      {\n        \"name\": \"Tom\",\n        \"email\": \"tom@example.com\"\n      }\n    ]\n    \n    ↓\n    \n    ╔════════╦═════════════════╗\n    ║ name ▼ ║ email         ▼ ║\n    ╠════════╬═════════════════╣\n    ║ Bob    ║ bob@example.com ║\n    ║ Tom    ║ tom@example.com ║\n    ╚════════╩═════════════════╝\n\n### MediaWikiTemplateTransformer (`t-mwTemplate`)\nCreates Wikitext depending on the given template.\nYou probably have to create a suiting template for the query.\nUses key=value pairs.\n\nWiki-String: {{ template |key=value  }}\n\nUsage: `t-mwTemplate=template`\n\nWith `t-mwTemplate=jsoner-template`\n\n\n\n    [\n      {\n        \"name\": \"Bob\",\n        \"email\": \"bob@example.com\"\n        \"username\": \"bobexample\"\n      },\n      {\n        \"name\": \"Tom\",\n        \"email\": \"tom@example.com\"\n        \"username\": \"tomexample\"\n      }\n    ]\n\n    ↓\n\n    ╔════════╦═════════════════╦══════════════╗\n    ║ name ▼ ║ email         ▼ ║username    ▼ ║\n    ╠════════╬═════════════════╣══════════════╣\n    ║ Bob    ║ bob@example.com ║ bobexample   ║\n    ║ Tom    ║ tom@example.com ║ tomexample   ║\n    ╚════════╩═════════════════╩══════════════╝\n\nThe output is depending on the template you use.\n\n### MediaWikiTemplateTransformerAnonymous (`t-mwTemplateAnonymous`)\nCreates Wikitext depending on the given template.\nYou probably have to create a suiting template for the query.\nDoesn't use key=value pairs, uses the Anonymous templating in the Mediawiki.\nTemplate in this use case :\n  template= {{{1}}} {{{2}}}\n\nUsage: `t-mwTemplateAnonymous=template`\n\n    [\n      {\n        \"name\": \"Bob\",\n        \"email\": \"bob@example.com\"\n        \"username\": \"bobexample\"\n      },\n      {\n        \"name\": \"Tom\",\n        \"email\": \"tom@example.com\"\n        \"username\": \"tomexample\"\n      }\n    ]\n\n    ↓\n\n    Bob bob@example.com Tom tom@example.com \n\nThe output is depending on the template you use.\n\n## Limitations\n\n* If you set `$jsonerUser` and `$jsonerPass`, the authentification is used for every request. There\n  is currently no per-domain or per-request level setting for username and password (and maybe\n  rightfully so). One possibility would be to put a separate call, like `{{ #jsoner-unauth:url=… }}`\n  or something like that.\n\n## Development\n\nThis extension is under development. Anything may change.\n\nYou can clone is using\n\n    git clone git@github.com:noris-network/Jsoner.git \u0026\u0026 cd Jsoner\n    make devenv\n\nTo install it into your development MediaWiki, just symlink it to your `extensions` folder\n\n    # Assuming you are in Jsoner folder\n    cd /path/to/your/extensions/folder\n    ln -s /path/to/the/Jsoner/extension Jsoner\n\nThen, install it [like described above](#installation).\n\nTo see what you can do run one of\n\n    make\n    make help\n\nTo test, you can run\n\n    make test\n    \nTo fix warnings etc. from `make test`, you can run:\n\n    make fix\n    \nTo clean, you can run\n    \n    make clean\n\n## License\nGPL v3\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoris-network%2Fjsoner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnoris-network%2Fjsoner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoris-network%2Fjsoner/lists"}