{"id":1127,"date":"2013-07-14T22:00:39","date_gmt":"2013-07-14T21:00:39","guid":{"rendered":"https:\/\/www.entropywins.wtf\/blog\/?p=1127"},"modified":"2014-03-17T23:31:27","modified_gmt":"2014-03-17T22:31:27","slug":"parserhooks-declarative-oop-api-for-mediawiki-released","status":"publish","type":"post","link":"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/","title":{"rendered":"ParserHooks declarative OOP API for MediaWiki released"},"content":{"rendered":"<div id=\"pN7RmhDXItdrT10z52+dK7YPKS3O1B0IIL9sfNM3k3w=_13fda9c8450:1cc480:9100fcad_entryContent\" itemprop=\"description\">\n<p>Yes, there now is a nice OOP API that allows you to create <a href=\"https:\/\/www.mediawiki.org\/\" target=\"_blank\">MediaWiki<\/a> <a href=\"https:\/\/www.mediawiki.org\/wiki\/Manual:Parser_functions\" target=\"_blank\">parser hooks<\/a> in declarative fashion!<\/p>\n<p>A few years back, I was sitting in <a href=\"http:\/\/www.c-base.org\/\" target=\"_blank\">c-base<\/a> after the <a href=\"http:\/\/events.ccc.de\/congress\/2010\/wiki\/Welcome\" target=\"_blank\">27th Chaos Communication Congress<\/a> had ended. I decided to quickly hack up a decent <a href=\"https:\/\/www.mediawiki.org\/wiki\/Extension:SubPageList\" target=\"_blank\">SubPageList<\/a> extension for MediaWiki on top of a declarative parameter processing library I had created not much earlier, then titled <a href=\"https:\/\/www.mediawiki.org\/wiki\/Extension:ParamProcessor\" target=\"_blank\">Validator<\/a>.<\/p>\n<p>Earlier this year I decided to try out some dependency management approaches (buzzword: dependency injection) in this SubPageList extension. Since there was a lot of resistance from various sources to doing this, I had refrained from fully embracing this approach. Here I could go all the way, and see if it worked out nicely, or if it would, like critics predicted, make everything so complicated that it\u2019d no longer be understandable. I was also determined to get rid of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Single_responsibility_principle\" target=\"_blank\">Single Responsibility Principle<\/a> violations and to abstract away from MediaWiki interfaces to avoid tight coupling, especially from certain poorly designed classes. This also helped to decrease the chance of compatibility breaks.<\/p>\n<p>In the process of refactoring this extension, I ran into usage of the ParserHook class provided by Validator (or rather ParamProcessor, as it is currently called). The idea behind this class was to have a derivative per parser hook that would define the parameters in a declarative fashion and process them using the ParamProcessor functionality before handling them to the actual parser hook handling code. While the idea is great in itself, the implementation of the ParserHook class is very poor. It violates at least half a dozen or so important design principles. Luckily I\u2019m the author of this code, so I have the option to redesign it from ground up and then ditch the evil\u00a0old version.<\/p>\n<p>I\u2019ve also been working on refactoring the ParamProcessor library and had already identified the ParserHook class both as badly designed and misplaced in the ParamProcessor library. I had thus detracted it already. Hence it was pretty clear that for a fresh implementation, the creation of a new component was in order. This is how the ParserHooks library was born.<\/p>\n<p><strong>Library structure and usage<\/strong><\/p>\n<p>The declarative OOP interface provided by this library allows you to define the signatures of your parser hooks and the handlers for them separately. The library makes use of the parameters specified in this definition to do parameter processing via the ParamProcessor library. This means that the handler you write for your parser function will not need to care about what the name of the parser function is, or how the parameters for it should be processed. It has a \u201csizes\u201d parameter that takes an array of positive integers? Your handler will always get an actual PHP array of integer without needing to do any parsing, validation, defaulting, etc.<\/p>\n<p>HookDefiniton<\/p>\n<h3><a href=\"https:\/\/github.com\/wikimedia\/mediawiki-extensions-ParserHooks#hookdefinition\" target=\"_blank\" name=\"hookdefinition\"><\/a><\/h3>\n<p>An instance of the HookDefinition class represents the signature of a parser hook. It defines the name of the parser hook and the parameters (including their types, default values, etc) it accepts. It does not define any behaviour, and is thus purely declarative. Instances of this class are used in handling of actual parser hooks, though can also be used in other contexts. For instance, you can feed these definitions to a tool that generates parser hook documentation based on them.<\/p>\n<p>The parameter definitions are ParamProcessor\\ParamDefinition objects. See the ParamProcessor documentation on how to specify these.<\/p>\n<h3><a href=\"https:\/\/github.com\/wikimedia\/mediawiki-extensions-ParserHooks#hookhandler\" target=\"_blank\" name=\"hookhandler\"><\/a><\/h3>\n<p>HookHandler<\/p>\n<p>The actual behaviour for your parser hook is implemented in an implementation of HookHandler. These implementations have a handle method which gets a Parser and a ParamProcssor\\ProcessingResult, which is supposed to return a string.<\/p>\n<p>Knitting it all together<\/p>\n<p>This library also provides two additional classes, FunctionRunner, and HookRegistrant. The former takes care of invoking the ParamProcessor library based on a HookDefinition. The later takes care of registering the parser hooks defined by your HookDefinition objects to a MediaWiki Parser object.<\/p>\n<pre>$awesomeHookDefinition = new HookDefinition( 'awesome', array( \/* ... *\/ ) );\r\n$anotherHookDefinition = new HookDefinition( 'another', array( \/* ... *\/ ) );\r\n\r\n$awesomeHookHandler = new AwesomeHookHandler( \/* ... *\/ );\r\n$anotherHookHandler = new AnotherHookHandler( \/* ... *\/ );\r\n\r\n$hookRegistrant = new HookRegistrant( $mediaWikiParser );\r\n\r\n$hookRegistrant-&gt;registerFunction( new FunctionRunner( $awesomeHookDefinition, $awesomeHookHandler ) );\r\n$hookRegistrant-&gt;registerFunction( new FunctionRunner( $anotherHookDefinition, $anotherHookHandler ) );<\/pre>\n<p>If you want to have the same hook, but with other default behaviour, you can avoid any kind of duplication by doing something as follows on top of the above code:<\/p>\n<pre>$hookRegistrant-&gt;registerFunction( new FunctionRunner( $extraAwesomeHookDefinition, $awesomeHookHandler ) );<\/pre>\n<p><strong>Current state<\/strong><\/p>\n<p>Today I released version 1.0 of this ParserHooks library. This version is feature complete and stable. I do not expect to make much changes to it in the near future. Or at any point for that matter \u2013 it is not that much code after all, and it\u2019s now doing what it is supposed to do. Currently the only consumer of this library is the SubPageList extension (or rather the 1.0.x branch of SubPageList, the code is not on master just yet). My future related work will mainly be in the form of implementations of the HookHandler interface in other components and on ParamProcessor, which after all provides much of the functionality that makes up this library.<\/p>\n<p>You can <a href=\"https:\/\/github.com\/wikimedia\/mediawiki-extensions-ParserHooks\/blob\/master\/README.md\" target=\"_blank\">read the documentation on GitHub<\/a>. And of course, you can <a href=\"https:\/\/packagist.org\/packages\/mediawiki\/parser-hooks\" target=\"_blank\">install it with Composer<\/a>.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Yes, there now is a nice OOP API that allows you to create MediaWiki parser hooks in declarative fashion! A&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[],"class_list":["post-1127","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>ParserHooks declarative OOP API for MediaWiki released - Blog of Jeroen De Dauw<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"ParserHooks declarative OOP API for MediaWiki released - Blog of Jeroen De Dauw\" \/>\n<meta property=\"og:description\" content=\"Yes, there now is a nice OOP API that allows you to create MediaWiki parser hooks in declarative fashion! A&hellip;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog of Jeroen De Dauw\" \/>\n<meta property=\"article:published_time\" content=\"2013-07-14T21:00:39+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2014-03-17T22:31:27+00:00\" \/>\n<meta name=\"author\" content=\"Jeroen\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/JeroenDeDauw\" \/>\n<meta name=\"twitter:site\" content=\"@JeroenDeDauw\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jeroen\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/\"},\"author\":{\"name\":\"Jeroen\",\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7\"},\"headline\":\"ParserHooks declarative OOP API for MediaWiki released\",\"datePublished\":\"2013-07-14T21:00:39+00:00\",\"dateModified\":\"2014-03-17T22:31:27+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/\"},\"wordCount\":820,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/\",\"url\":\"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/\",\"name\":\"ParserHooks declarative OOP API for MediaWiki released - Blog of Jeroen De Dauw\",\"isPartOf\":{\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/#website\"},\"datePublished\":\"2013-07-14T21:00:39+00:00\",\"dateModified\":\"2014-03-17T22:31:27+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.entropywins.wtf\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"ParserHooks declarative OOP API for MediaWiki released\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/#website\",\"url\":\"https:\/\/www.entropywins.wtf\/blog\/\",\"name\":\"Entropy Wins\",\"description\":\"A blog on Software Architecture, Design and Craftsmanship\",\"publisher\":{\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.entropywins.wtf\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7\",\"name\":\"Jeroen\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g\",\"caption\":\"Jeroen\"},\"logo\":{\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/image\/\"},\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/jeroendedauw\/\",\"https:\/\/x.com\/https:\/\/twitter.com\/JeroenDeDauw\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"ParserHooks declarative OOP API for MediaWiki released - Blog of Jeroen De Dauw","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/","og_locale":"en_US","og_type":"article","og_title":"ParserHooks declarative OOP API for MediaWiki released - Blog of Jeroen De Dauw","og_description":"Yes, there now is a nice OOP API that allows you to create MediaWiki parser hooks in declarative fashion! A&hellip;","og_url":"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/","og_site_name":"Blog of Jeroen De Dauw","article_published_time":"2013-07-14T21:00:39+00:00","article_modified_time":"2014-03-17T22:31:27+00:00","author":"Jeroen","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/JeroenDeDauw","twitter_site":"@JeroenDeDauw","twitter_misc":{"Written by":"Jeroen","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/#article","isPartOf":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/"},"author":{"name":"Jeroen","@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7"},"headline":"ParserHooks declarative OOP API for MediaWiki released","datePublished":"2013-07-14T21:00:39+00:00","dateModified":"2014-03-17T22:31:27+00:00","mainEntityOfPage":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/"},"wordCount":820,"commentCount":1,"publisher":{"@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7"},"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/","url":"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/","name":"ParserHooks declarative OOP API for MediaWiki released - Blog of Jeroen De Dauw","isPartOf":{"@id":"https:\/\/www.entropywins.wtf\/blog\/#website"},"datePublished":"2013-07-14T21:00:39+00:00","dateModified":"2014-03-17T22:31:27+00:00","breadcrumb":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.entropywins.wtf\/blog\/"},{"@type":"ListItem","position":2,"name":"ParserHooks declarative OOP API for MediaWiki released"}]},{"@type":"WebSite","@id":"https:\/\/www.entropywins.wtf\/blog\/#website","url":"https:\/\/www.entropywins.wtf\/blog\/","name":"Entropy Wins","description":"A blog on Software Architecture, Design and Craftsmanship","publisher":{"@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.entropywins.wtf\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7","name":"Jeroen","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g","caption":"Jeroen"},"logo":{"@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/image\/"},"sameAs":["https:\/\/www.linkedin.com\/in\/jeroendedauw\/","https:\/\/x.com\/https:\/\/twitter.com\/JeroenDeDauw"]}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p74TBF-ib","jetpack-related-posts":[{"id":1135,"url":"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/25\/parserhooks-1-1-released\/","url_meta":{"origin":1127,"position":0},"title":"ParserHooks 1.1 released!","author":"Jeroen","date":"2013-09-25","format":false,"excerpt":"ParserHooks is a library that adds an object orientated and declarative parser hook interface on top of MediaWiki. (Read about the initial release) Today I finished up and released version 1.1 The new features are support of tag extensions and a simplified way to register parser hook handlers. If you\u2026","rel":"","context":"Similar post","block_context":{"text":"Similar post","link":""},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1340,"url":"https:\/\/www.entropywins.wtf\/blog\/2014\/05\/06\/wikibase-and-doctrine-dbal\/","url_meta":{"origin":1127,"position":1},"title":"Wikibase and Doctrine DBAL","author":"Jeroen","date":"2014-05-06","format":false,"excerpt":"When I started writing this blog post, I realized some introduction to the query components was first due. You can find it in my last blog post: The Wikidata phase3 software components. In this post I described how the SQLStore uses a database abstraction layer to not bind itself to\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2014\/05\/dbal.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2014\/05\/dbal.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2014\/05\/dbal.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2014\/05\/dbal.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2014\/05\/dbal.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":1172,"url":"https:\/\/www.entropywins.wtf\/blog\/2014\/01\/02\/mediawiki-extensions-to-define-their-mediawiki-compatibility\/","url_meta":{"origin":1127,"position":2},"title":"MediaWiki extensions to define their MediaWiki compatibility","author":"Jeroen","date":"2014-01-02","format":false,"excerpt":"Over the past year support for real dependency management has been gradually added to MediaWiki and selected extensions. This support being based on the Composer software. While extensions have been able to specify their dependencies for a while, such as PHP libraries and other extensions, they where not able to\u2026","rel":"","context":"In \"composer\"","block_context":{"text":"composer","link":"https:\/\/www.entropywins.wtf\/blog\/tag\/composer\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1139,"url":"https:\/\/www.entropywins.wtf\/blog\/2013\/10\/31\/mediawiki-extension-installer\/","url_meta":{"origin":1127,"position":3},"title":"MediaWiki extension installer","author":"Jeroen","date":"2013-10-31","format":false,"excerpt":"During SMWCon earlier this week I hacked up a tool to install MediaWiki extensions with Composer. Composer is a dependency manager, in other words a tool that automates many of the tasks that people installing MediaWiki extensions currently need to deal with manually. Right now one needs to bother with\u2026","rel":"","context":"Similar post","block_context":{"text":"Similar post","link":""},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":941,"url":"https:\/\/www.entropywins.wtf\/blog\/2010\/08\/07\/distribution-extension-for-mediawiki\/","url_meta":{"origin":1127,"position":4},"title":"Distribution extension for MediaWiki","author":"Jeroen","date":"2010-08-07","format":false,"excerpt":"With only 2 days till the suggested Google Summer of Code 'pencils down' date, and a week longer until the firm one, I'm using my remaining time to get some basic functionality working for my GSoC project. I've started creating a new extension called Distribution that will provide an API\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1153,"url":"https:\/\/www.entropywins.wtf\/blog\/2013\/11\/24\/introduction-to-composer-for-mediawiki-developers\/","url_meta":{"origin":1127,"position":5},"title":"Introduction to Composer for MediaWiki developers","author":"Jeroen","date":"2013-11-24","format":false,"excerpt":"This post aims to be a quick start guide for MediaWiki extension developers that want to get their extension to be installable via Composer. If you are not yet familiar with Composer, I recommend you have a look at the Composer page on MediaWiki.org before continuing with this post. Defining\u2026","rel":"","context":"In \"composer\"","block_context":{"text":"composer","link":"https:\/\/www.entropywins.wtf\/blog\/tag\/composer\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2013\/11\/logo-composer-transparent.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts\/1127","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/comments?post=1127"}],"version-history":[{"count":2,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts\/1127\/revisions"}],"predecessor-version":[{"id":1276,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts\/1127\/revisions\/1276"}],"wp:attachment":[{"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/media?parent=1127"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/categories?post=1127"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/tags?post=1127"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}