{"id":1133,"date":"2013-09-24T22:01:40","date_gmt":"2013-09-24T21:01:40","guid":{"rendered":"https:\/\/www.entropywins.wtf\/blog\/?p=1133"},"modified":"2014-09-16T20:33:46","modified_gmt":"2014-09-16T19:33:46","slug":"mediawiki-subpagelist-rewrite","status":"publish","type":"post","link":"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/","title":{"rendered":"MediaWiki SubPageList rewrite"},"content":{"rendered":"<div id=\"pN7RmhDXItdrT10z52+dK7YPKS3O1B0IIL9sfNM3k3w=_1415156b313:3545226:336ac757_entryContent\">\n<p><strong>How I ended up rewriting the MediaWiki <a href=\"https:\/\/www.mediawiki.org\/wiki\/Extension:SubPageList\" target=\"_blank\">SubPageList extension<\/a>:<\/strong><\/p>\n<p>At the beginning of this year, it was still somewhat controversial in the <a href=\"http:\/\/wikidata.org\/\" target=\"_blank\">Wikidata<\/a> development team that concepts such as the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Single_responsibility_principle\" target=\"_blank\">Single Responsibility Principle<\/a>, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Inversion_of_control\" target=\"_blank\">Inversion of Control<\/a> and <a href=\"https:\/\/en.wikipedia.org\/wiki\/Interface_segregation_principle\" target=\"_blank\">Interface Segregation<\/a> are generally a good idea and practical to implement without creating more problems then they solve. Parts of the MediaWiki community reject those principles in a rather fanatical religious way, and certainly at that time, no one was supporting them very openly.<\/p>\n<p>As I was still pretty new to these ideas and had never \u201cgone all the way\u201d with them, the resistance of nearly everyone in my direct environment caused me to be extra careful in adopting them. I decided to do a <a href=\"http:\/\/redsquirrel.com\/dave\/work\/a2j\/patterns\/BreakableToys.html\" target=\"_blank\">breakable toy project<\/a>, in which I could blatantly ignore the sceptics and try out these practices in full. That way it would be evident if they where practical in the context of MediaWiki development, and it would show if the result would be as clean as I was hoping, or as opaque as the sceptics where predicting.<\/p>\n<p>As breakable toy project I picked creating a redesign of the <a href=\"https:\/\/www.mediawiki.org\/wiki\/Extension:SubPageList\" target=\"_blank\">SubPageList extension<\/a>. The moderate size of the extension was one factor in this decision. Another was the bad sate it was in. It had started as a rewrite of the SubPageList3 extension. And while initially it was certainly cleaner, the code ended up rotting quite badly over time. A reason for this was\u00a0 the main code residing in a single <a href=\"http:\/\/www.martinfowler.com\/eaaCatalog\/transactionScript.html\" target=\"_blank\">transaction script<\/a> like class, that just grew and grew with various options, ending up with insane complexity. Other reasons including lack of tests, and contributions from people not well versed in software design (me). Doing a rewrite project would thus end up fixing this mess, assuming it went well.<\/p>\n<p><strong>The rewriting process<\/strong><\/p>\n<p>I started with the rewrite in February. My main interest at the time was finding out if full <a href=\"https:\/\/en.wikipedia.org\/wiki\/Dependency_injection\" target=\"_blank\">dependency injection<\/a> was feasible in an extension that hooks into MediaWiki at multiple locations, and how this could be done in a clean way.<\/p>\n<p>After doing the initial high level design and implementing the dependency injection mechanisms, I lost interest in this toy project for quite some time. It took till June before I picked it up again and finished most of the <a href=\"http:\/\/martinfowler.com\/eaaCatalog\/ServiceLayerSketch.gif\" target=\"_blank\">data access and domain layer <\/a>implementations.<\/p>\n<p>The old version of the extension was using the ParserHooks class, provided by the ParamProcessor library. This class is very poorly designed and had been deprecated. I\u2019d been thinking of creating a nicer alternative, and decided to do just what as part of this toy project. The result was the <a href=\"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/\" target=\"_blank\">ParserHooks library<\/a>.<\/p>\n<p>All what was left to do was implementation of presentation layer code, which is not my favourite thing in the world, so I ended up not working on the code for another few months. This month I re-discovered the rewrite once again and figured I really ought to get it finished now. So I threw myself on the presentation layer code to be written.<\/p>\n<p>Surprisingly this turned out to be quite a bit of fun. This is probably due to my approach in which I just turned domain objects into wikitext based on services which I created in <a href=\"https:\/\/en.wikipedia.org\/wiki\/Test-driven_development\" target=\"_blank\">test driven<\/a> fashion. Which allowed me to create all the functionality without ever loading a wiki page in my browser.<\/p>\n<p>This was a quite educational little project for me. I\u2019m quite happy with the result \u2013 even though it contains a lot of first attempts at certain approaches, the resulting design and code quality are generally good (at least by my current understanding).<\/p>\n<p>There are a few things that are markedly sub-optimal that I\u2019d do different now, and are prime candidates for improvements later on. Those are however not critical, local, and easy to fix, hence I have not bothered with them yet. Compared to the issues before the rewrite, these are really just nitpicks though.<\/p>\n<p>After 7 months of on-and-mostly-off work and 123 commits, I finally merged in my development branch into master yesterday. It is nearly fully backwards compatible (I dropped some silly features), fully tested, and in such a sate that adding new features to the extension ought to be a breeze from now on. This means you can try out the beta version of SubPageList 1.0 now, by getting the latest master. I will be writing an actual release announcement in the near future, detailing the user relevant changes.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>How I ended up rewriting the MediaWiki SubPageList extension: At the beginning of this year, it was still somewhat controversial&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":[7],"tags":[328,156,215,251],"class_list":["post-1133","post","type-post","status-publish","format-standard","hentry","category-programming","tag-clean-code","tag-mediawiki","tag-refactoring","tag-subpagelist"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>MediaWiki SubPageList rewrite - 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\/09\/24\/mediawiki-subpagelist-rewrite\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"MediaWiki SubPageList rewrite - Blog of Jeroen De Dauw\" \/>\n<meta property=\"og:description\" content=\"How I ended up rewriting the MediaWiki SubPageList extension: At the beginning of this year, it was still somewhat controversial&hellip;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog of Jeroen De Dauw\" \/>\n<meta property=\"article:published_time\" content=\"2013-09-24T21:01:40+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2014-09-16T19:33:46+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\/09\/24\/mediawiki-subpagelist-rewrite\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/\"},\"author\":{\"name\":\"Jeroen\",\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7\"},\"headline\":\"MediaWiki SubPageList rewrite\",\"datePublished\":\"2013-09-24T21:01:40+00:00\",\"dateModified\":\"2014-09-16T19:33:46+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/\"},\"wordCount\":744,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7\"},\"keywords\":[\"Clean Code\",\"MediaWiki\",\"Refactoring\",\"SubPageList\"],\"articleSection\":[\"Programming\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/\",\"url\":\"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/\",\"name\":\"MediaWiki SubPageList rewrite - Blog of Jeroen De Dauw\",\"isPartOf\":{\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/#website\"},\"datePublished\":\"2013-09-24T21:01:40+00:00\",\"dateModified\":\"2014-09-16T19:33:46+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.entropywins.wtf\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"MediaWiki SubPageList rewrite\"}]},{\"@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":"MediaWiki SubPageList rewrite - 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\/09\/24\/mediawiki-subpagelist-rewrite\/","og_locale":"en_US","og_type":"article","og_title":"MediaWiki SubPageList rewrite - Blog of Jeroen De Dauw","og_description":"How I ended up rewriting the MediaWiki SubPageList extension: At the beginning of this year, it was still somewhat controversial&hellip;","og_url":"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/","og_site_name":"Blog of Jeroen De Dauw","article_published_time":"2013-09-24T21:01:40+00:00","article_modified_time":"2014-09-16T19:33:46+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\/09\/24\/mediawiki-subpagelist-rewrite\/#article","isPartOf":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/"},"author":{"name":"Jeroen","@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7"},"headline":"MediaWiki SubPageList rewrite","datePublished":"2013-09-24T21:01:40+00:00","dateModified":"2014-09-16T19:33:46+00:00","mainEntityOfPage":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/"},"wordCount":744,"commentCount":0,"publisher":{"@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7"},"keywords":["Clean Code","MediaWiki","Refactoring","SubPageList"],"articleSection":["Programming"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/","url":"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/","name":"MediaWiki SubPageList rewrite - Blog of Jeroen De Dauw","isPartOf":{"@id":"https:\/\/www.entropywins.wtf\/blog\/#website"},"datePublished":"2013-09-24T21:01:40+00:00","dateModified":"2014-09-16T19:33:46+00:00","breadcrumb":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/24\/mediawiki-subpagelist-rewrite\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.entropywins.wtf\/blog\/"},{"@type":"ListItem","position":2,"name":"MediaWiki SubPageList rewrite"}]},{"@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-ih","jetpack-related-posts":[{"id":1052,"url":"https:\/\/www.entropywins.wtf\/blog\/2011\/01\/01\/new-mediawiki-extension-subpagelist\/","url_meta":{"origin":1133,"position":0},"title":"New MediaWiki extension: SubPageList","author":"Jeroen","date":"2011-01-01","format":false,"excerpt":"During 27c3 someone asked me to install an extension to list subpages onto the hackerspace.be wiki. I picked SubPageList3, as it seemed to most decent one. I did a simple test to see if it was working, and immediately found a namespace bug. So I decided to quickly rewrite it\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/programming\/"},"img":{"alt_text":"SubPageList extension","src":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/01\/Splist_1.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":1137,"url":"https:\/\/www.entropywins.wtf\/blog\/2013\/10\/15\/subpagelist-1-0-released\/","url_meta":{"origin":1133,"position":1},"title":"SubPageList 1.0 released!","author":"Jeroen","date":"2013-10-15","format":false,"excerpt":"I am happy to announce the immediate release of SubPageList 1.0. SubPageList is a MediaWiki extension with the following features: Adds a subpages parser hook that you can use to list subpages. Backward compatible with the SubPageList3 extension. Supports various parameters that enable you to customize the subpage list both\u2026","rel":"","context":"In \"MediaWiki\"","block_context":{"text":"MediaWiki","link":"https:\/\/www.entropywins.wtf\/blog\/tag\/mediawiki\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1127,"url":"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/","url_meta":{"origin":1133,"position":2},"title":"ParserHooks declarative OOP API for MediaWiki released","author":"Jeroen","date":"2013-07-14","format":false,"excerpt":"Yes, there now is a nice OOP API that allows you to create MediaWiki parser hooks in declarative fashion! A few years back, I was sitting in c-base after the 27th Chaos Communication Congress had ended. I decided to quickly hack up a decent SubPageList extension for MediaWiki on top\u2026","rel":"","context":"With 1 comment","block_context":{"text":"With 1 comment","link":"https:\/\/www.entropywins.wtf\/blog\/2013\/07\/14\/parserhooks-declarative-oop-api-for-mediawiki-released\/#comments"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1056,"url":"https:\/\/www.entropywins.wtf\/blog\/2011\/01\/11\/validator-0-4-3introducing-auto-documentation\/","url_meta":{"origin":1133,"position":3},"title":"Validator 0.4.3:introducing auto-documentation","author":"Jeroen","date":"2011-01-11","format":false,"excerpt":"It's been a while since the previous release of Validator, but this minor update includes some cool new functionality. As I was creating the SubPageList extension and it's documentation (at 27c3!), it occurred to me that to document the usage of the <subpages \/> parser hook, all the info I\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/programming\/"},"img":{"alt_text":"Some documentation (for the coordinates parser function) generated using the describe parser hook","src":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/01\/describe-coordinates-table.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/01\/describe-coordinates-table.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/01\/describe-coordinates-table.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/01\/describe-coordinates-table.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":1135,"url":"https:\/\/www.entropywins.wtf\/blog\/2013\/09\/25\/parserhooks-1-1-released\/","url_meta":{"origin":1133,"position":4},"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":1244,"url":"https:\/\/www.entropywins.wtf\/blog\/2011\/11\/08\/contest-extension-for-mediawiki\/","url_meta":{"origin":1133,"position":5},"title":"Contest extension for MediaWiki","author":"Jeroen","date":"2011-11-08","format":false,"excerpt":"As it\u2019s been 2 months since my last blog post, I figured it was time for another one. Quite a few things I could write about (SMWCon, my new awesome laptop, Stanfords AI and ML classes, me moving to Berlin, \u2026), but I decided to give some introduction to my\u2026","rel":"","context":"Similar post","block_context":{"text":"Similar post","link":""},"img":{"alt_text":"Contest welcome interface","src":"https:\/\/i0.wp.com\/web.archive.org\/web\/20121017212310im_\/https%3A\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/11\/800px-Contest-welcome-click.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/web.archive.org\/web\/20121017212310im_\/https%3A\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/11\/800px-Contest-welcome-click.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/web.archive.org\/web\/20121017212310im_\/https%3A\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/11\/800px-Contest-welcome-click.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/web.archive.org\/web\/20121017212310im_\/https%3A\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/11\/800px-Contest-welcome-click.png?resize=700%2C400&ssl=1 2x"},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts\/1133","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=1133"}],"version-history":[{"count":3,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts\/1133\/revisions"}],"predecessor-version":[{"id":1406,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts\/1133\/revisions\/1406"}],"wp:attachment":[{"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/media?parent=1133"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/categories?post=1133"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/tags?post=1133"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}