{"id":1244,"date":"2011-11-08T23:15:18","date_gmt":"2011-11-08T22:15:18","guid":{"rendered":"https:\/\/www.entropywins.wtf\/blog\/?p=1244"},"modified":"2014-03-17T23:16:18","modified_gmt":"2014-03-17T22:16:18","slug":"contest-extension-for-mediawiki","status":"publish","type":"post","link":"https:\/\/www.entropywins.wtf\/blog\/2011\/11\/08\/contest-extension-for-mediawiki\/","title":{"rendered":"Contest extension for MediaWiki"},"content":{"rendered":"<p>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 <strong>awesome<\/strong> laptop, Stanfords AI and ML classes, me moving to Berlin, \u2026), but I decided to give some introduction to <a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.mediawiki.org\/wiki\/Extension:Contest\">my most recent MediaWiki extension: Contest<\/a>.<\/p>\n<p>Contest extension that allows users to participate in admin defined contest challenges. Via a judging interface, judges can discuss and vote on submissions. I created it for the <a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/blog.wikimedia.org\/2011\/10\/20\/announcing-the-october-2011-coding-challenge\/\">Wikimedia October coding challenge<\/a>, so it got a nice amount of review, uncovering some minor misconceptions I had about some core MW code, and it got deployed on MediaWiki.org. The coding challenge is quite <strong>awesome<\/strong>, but I won\u2019t discuss it any further here, so check out the linked blog post if you\u2019re curious\/interested.<\/p>\n<p><strong>Feature overview:<\/strong><\/p>\n<ul>\n<li>Admin interface for managing contests and their challenges.<\/li>\n<li>Landing and signup pages for each contest.<\/li>\n<li>Personal contest list and submission interface for each user.<\/li>\n<li>Summary pages per contest listing contestants, which can be filtered and sorted.<\/li>\n<li>Judging interface that allows for rating and commenting on each participant.<\/li>\n<li>All contests, challenges, contestants, comments and votes can be queried and exported via the API.<\/li>\n<li>Signup and reminder emails.<\/li>\n<\/ul>\n<p><strong>Requirements<\/strong><\/p>\n<ul>\n<li><a title=\"MediaWiki\" href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.mediawiki.org\/wiki\/MediaWiki\">MediaWiki<\/a> 1.18 or above \u2013 yeah! my first <strong>awesome<\/strong> MediaWiki 1.18 or later extension <img decoding=\"async\" alt=\":)\" src=\"https:\/\/web.archive.org\/web\/20121017212310im_\/https:\/\/www.entropywins.wtf\/blog\/wp-includes\/images\/smilies\/icon_smile.gif\" \/><\/li>\n<li>PHP 5.2 or above<\/li>\n<li>MySQL<\/li>\n<\/ul>\n<p><strong>Some screenshots<\/strong><\/p>\n<p><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/11\/800px-Contest-welcome-click.png\"><img loading=\"lazy\" decoding=\"async\" title=\"Contest welcome interface\" alt=\"Contest welcome interface\" src=\"https:\/\/web.archive.org\/web\/20121017212310im_\/https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/11\/800px-Contest-welcome-click.png\" width=\"800\" height=\"508\" \/><\/a><\/p>\n<p>Contest welcome interface<\/p>\n<p><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/11\/800px-Contest-mycontest.png\"><img loading=\"lazy\" decoding=\"async\" title=\"Contest submission and management interface for a single user\" alt=\"Contest submission and management interface for a single user\" src=\"https:\/\/web.archive.org\/web\/20121017212310im_\/https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/11\/800px-Contest-mycontest.png\" width=\"800\" height=\"566\" \/><\/a><\/p>\n<p>Contest submission and management interface for a single user<\/p>\n<p><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/11\/800px-Contest-contests.png\"><img loading=\"lazy\" decoding=\"async\" title=\"Contest administration and judging interface listing all contests\" alt=\"Contest administration and judging interface listing all contests\" src=\"https:\/\/web.archive.org\/web\/20121017212310im_\/https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/11\/800px-Contest-contests.png\" width=\"800\" height=\"271\" \/><\/a><\/p>\n<p>Contest administration and judging interface listing all contests<\/p>\n<p><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/11\/800px-Contest-contestitem.png\"><img loading=\"lazy\" decoding=\"async\" title=\"Contest administration and judging interface for a single contest\" alt=\"Contest administration and judging interface for a single contest\" src=\"https:\/\/web.archive.org\/web\/20121017212310im_\/https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/11\/800px-Contest-contestitem.png\" width=\"800\" height=\"311\" \/><\/a><\/p>\n<p>Contest administration and judging interface for a single contest<\/p>\n<p><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/11\/764px-Contest-editcontest.png\"><img loading=\"lazy\" decoding=\"async\" title=\"Contest editing interface\" alt=\"Contest editing interface\" src=\"https:\/\/web.archive.org\/web\/20121017212310im_\/https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/11\/764px-Contest-editcontest.png\" width=\"764\" height=\"600\" \/><\/a><\/p>\n<p>Contest editing interface<\/p>\n<p><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/11\/800px-Contest-contestant-judging.png\"><img loading=\"lazy\" decoding=\"async\" title=\"Judging interface for a single submission\" alt=\"Judging interface for a single submission\" src=\"https:\/\/web.archive.org\/web\/20121017212310im_\/https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/11\/800px-Contest-contestant-judging.png\" width=\"800\" height=\"554\" \/><\/a><\/p>\n<p>Judging interface for a single submission<\/p>\n<p><strong>Some background<\/strong><\/p>\n<p>When starting with this extension, it was clear pretty quickly that it could really use the <strong>awesome<\/strong> DBObject class I\u2019ve been incrementally creating over my last few extensions and mostly finished in <a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.mediawiki.org\/wiki\/Extension:Survey\">Survey<\/a>. This class is a wrapper for objects of a certain type, which is equivalent to a row in some db table. Even though it\u2019s in essence very simple \u2013 it just has a field that is an associative array with field =&gt; value \u2013 it\u2019s also very powerful and flexible. When I started with this, I had no idea it would turn out to be so neat. The bad news was that I could not use PHP 5.3 or later for Contest, while the DBObject class uses late static binding, which was introduces in PHP 5.3. I came up with a simple hack: all static methods in the base class have been made-non static, but are marked as \u201cshould be static\u201d. Then, every deriving class has a public static function s(), which returns a (cached) instance of the class. So then for every \u201cstatic\u201d method you need to call, instead of ClassName::methodName(), you do ClassName::s()-&gt;methodName(). If you know this, and do not misuse the non-static-but-should-be-static methods in the base class, it retains all it\u2019s niceness, at the cost of something that\u2019s pretty much a tiny bit of syntactic sugar. And it\u2019s quite obvious how easy it will be to replace this with actual LSB usage once this becomes possible <img decoding=\"async\" alt=\":)\" src=\"https:\/\/web.archive.org\/web\/20121017212310im_\/https:\/\/www.entropywins.wtf\/blog\/wp-includes\/images\/smilies\/icon_smile.gif\" \/><\/p>\n<ul>\n<li><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/http:\/\/svn.wikimedia.org\/viewvc\/mediawiki\/trunk\/extensions\/Survey\/includes\/SurveyDBClass.php?view=markup\">Survey DBObject class<\/a> \u2013 <a href=\"https:\/\/web.archive.org\/web\/20121017212310\/http:\/\/svn.wikimedia.org\/viewvc\/mediawiki\/trunk\/extensions\/Survey\/includes\/Survey.class.php?view=markup\">deriving class<\/a><\/li>\n<li><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/http:\/\/svn.wikimedia.org\/viewvc\/mediawiki\/trunk\/extensions\/Contest\/includes\/ContestDBObject.php?view=markup\">Contest DBObject class<\/a> \u2013 <a href=\"https:\/\/web.archive.org\/web\/20121017212310\/http:\/\/svn.wikimedia.org\/viewvc\/mediawiki\/trunk\/extensions\/Contest\/includes\/Contest.class.php?view=markup\">deriving class<\/a><\/li>\n<\/ul>\n<p><strong>Download<\/strong><\/p>\n<ul>\n<li><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/code.google.com\/p\/mwcontest\/downloads\/list\">Release tarballs<\/a><\/li>\n<li><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/http:\/\/svn.wikimedia.org\/svnroot\/mediawiki\/tags\/extensions\/Contest\/\">SVN tags<\/a><\/li>\n<li><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/http:\/\/svn.wikimedia.org\/svnroot\/mediawiki\/trunk\/extensions\/Contest\/\">SVN trunk<\/a><\/li>\n<\/ul>\n<p><strong>What\u2019s next?<\/strong><\/p>\n<p>There are various small additions that could be made, but one things really stands out: contest configuration with version history. Right now, you can create contests and challenges, modify them and delete them. But once you make a change, the previous version is lost. You cannot revert. You cannot compare. You can\u2019t even see who made the change or when. Implementing such a thing is not trivial, especially if you want to have a generic system that can be used by any extension that wants to store data and have version history for it. And if you think about it, quite a few extensions could use this. Let\u2019s have a look at my extensions, latest first, and see if they can use it:<\/p>\n<ul>\n<li><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.mediawiki.org\/wiki\/Extension:Contest\">Contest<\/a> \u2013 well yeah, obviously<\/li>\n<li><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.mediawiki.org\/wiki\/Extension:Survey\">Survey<\/a> \u2013 yes, for the surveys, their configuration, and their questions<\/li>\n<li><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.mediawiki.org\/wiki\/Extension:Semantic_Watchlist\">Semantic Watchlist<\/a> \u2013 yeah, for the watchlist groups<\/li>\n<li><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.mediawiki.org\/wiki\/Extension:Include_WP\">IncludeWP<\/a> \u2013 no<\/li>\n<li><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.mediawiki.org\/wiki\/Extension:SubPageList\">SubPageList<\/a> \u2013 no<\/li>\n<li><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.mediawiki.org\/wiki\/Extension:Live_Translate\">Live Translate<\/a> \u2013 yeah, for the translation memory admin<\/li>\n<li><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.mediawiki.org\/wiki\/Extension:Push\">Push<\/a> \u2013 no, although it could, if it had an admin interface for the push targets<\/li>\n<li><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.mediawiki.org\/wiki\/Extension:Validator\">Validator<\/a> \u2013 no<\/li>\n<li><a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.mediawiki.org\/wiki\/Extension:Maps\">Maps<\/a> and <a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.mediawiki.org\/wiki\/Extension:Semantic_Maps\">SM<\/a> \u2013 yeah, for the map layer definitions currently done as key=value pairs, one per line, in the Layer namespace<\/li>\n<\/ul>\n<p>That\u2019s 6 out of 10 just for the extensions I wrote. What it comes down to is that pretty much any extension that has some sort of settings interface that is not user-specific, could use this. And maybe even the user specific ones, which would obviously include the user preferences in MediaWiki core. So why not store this data in wiki pages, such as done by Maps for layers? You could even store it as JSON or serialized PHP objects if you need more complexity\u2026 The things with this is that it only works for simple use cases (such as the layers in Maps), and even then is limited. You cannot query over the data as you do not have it in relational form. And you cannot have fine grained access and write rights control over the data, which in a lot of cases is quite important. So a generic solution here would be an <strong>awesome<\/strong> addition to MediaWiki if you ask me.<\/p>\n<p>More info on Contest can be found on <a href=\"https:\/\/web.archive.org\/web\/20121017212310\/https:\/\/www.mediawiki.org\/wiki\/Extension:Contest\">it\u2019s documentation page<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As it\u2019s been 2 months since my last blog post, I figured it was time for another one. Quite 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-1244","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Contest extension for MediaWiki - 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\/2011\/11\/08\/contest-extension-for-mediawiki\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Contest extension for MediaWiki - Blog of Jeroen De Dauw\" \/>\n<meta property=\"og:description\" content=\"As it\u2019s been 2 months since my last blog post, I figured it was time for another one. Quite a&hellip;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.entropywins.wtf\/blog\/2011\/11\/08\/contest-extension-for-mediawiki\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog of Jeroen De Dauw\" \/>\n<meta property=\"article:published_time\" content=\"2011-11-08T22:15:18+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2014-03-17T22:16:18+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/web.archive.org\/web\/20121017212310im_\/https:\/\/www.entropywins.wtf\/blog\/wp-includes\/images\/smilies\/icon_smile.gif\" \/>\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=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2011\\\/11\\\/08\\\/contest-extension-for-mediawiki\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2011\\\/11\\\/08\\\/contest-extension-for-mediawiki\\\/\"},\"author\":{\"name\":\"Jeroen\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/#\\\/schema\\\/person\\\/4e2ef14f2ca7dc3a0ac137d1692b66b7\"},\"headline\":\"Contest extension for MediaWiki\",\"datePublished\":\"2011-11-08T22:15:18+00:00\",\"dateModified\":\"2014-03-17T22:16:18+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2011\\\/11\\\/08\\\/contest-extension-for-mediawiki\\\/\"},\"wordCount\":909,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/#\\\/schema\\\/person\\\/4e2ef14f2ca7dc3a0ac137d1692b66b7\"},\"image\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2011\\\/11\\\/08\\\/contest-extension-for-mediawiki\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/web.archive.org\\\/web\\\/20121017212310im_\\\/https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/wp-includes\\\/images\\\/smilies\\\/icon_smile.gif\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2011\\\/11\\\/08\\\/contest-extension-for-mediawiki\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2011\\\/11\\\/08\\\/contest-extension-for-mediawiki\\\/\",\"url\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2011\\\/11\\\/08\\\/contest-extension-for-mediawiki\\\/\",\"name\":\"Contest extension for MediaWiki - Blog of Jeroen De Dauw\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2011\\\/11\\\/08\\\/contest-extension-for-mediawiki\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2011\\\/11\\\/08\\\/contest-extension-for-mediawiki\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/web.archive.org\\\/web\\\/20121017212310im_\\\/https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/wp-includes\\\/images\\\/smilies\\\/icon_smile.gif\",\"datePublished\":\"2011-11-08T22:15:18+00:00\",\"dateModified\":\"2014-03-17T22:16:18+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2011\\\/11\\\/08\\\/contest-extension-for-mediawiki\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2011\\\/11\\\/08\\\/contest-extension-for-mediawiki\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2011\\\/11\\\/08\\\/contest-extension-for-mediawiki\\\/#primaryimage\",\"url\":\"https:\\\/\\\/web.archive.org\\\/web\\\/20121017212310im_\\\/https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/wp-includes\\\/images\\\/smilies\\\/icon_smile.gif\",\"contentUrl\":\"https:\\\/\\\/web.archive.org\\\/web\\\/20121017212310im_\\\/https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/wp-includes\\\/images\\\/smilies\\\/icon_smile.gif\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2011\\\/11\\\/08\\\/contest-extension-for-mediawiki\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Contest extension for MediaWiki\"}]},{\"@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:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g\",\"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:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g\"},\"sameAs\":[\"https:\\\/\\\/www.linkedin.com\\\/in\\\/jeroendedauw\\\/\",\"https:\\\/\\\/x.com\\\/https:\\\/\\\/twitter.com\\\/JeroenDeDauw\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Contest extension for MediaWiki - 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\/2011\/11\/08\/contest-extension-for-mediawiki\/","og_locale":"en_US","og_type":"article","og_title":"Contest extension for MediaWiki - Blog of Jeroen De Dauw","og_description":"As it\u2019s been 2 months since my last blog post, I figured it was time for another one. Quite a&hellip;","og_url":"https:\/\/www.entropywins.wtf\/blog\/2011\/11\/08\/contest-extension-for-mediawiki\/","og_site_name":"Blog of Jeroen De Dauw","article_published_time":"2011-11-08T22:15:18+00:00","article_modified_time":"2014-03-17T22:16:18+00:00","og_image":[{"url":"https:\/\/web.archive.org\/web\/20121017212310im_\/https:\/\/www.entropywins.wtf\/blog\/wp-includes\/images\/smilies\/icon_smile.gif","type":"","width":"","height":""}],"author":"Jeroen","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/JeroenDeDauw","twitter_site":"@JeroenDeDauw","twitter_misc":{"Written by":"Jeroen","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.entropywins.wtf\/blog\/2011\/11\/08\/contest-extension-for-mediawiki\/#article","isPartOf":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2011\/11\/08\/contest-extension-for-mediawiki\/"},"author":{"name":"Jeroen","@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7"},"headline":"Contest extension for MediaWiki","datePublished":"2011-11-08T22:15:18+00:00","dateModified":"2014-03-17T22:16:18+00:00","mainEntityOfPage":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2011\/11\/08\/contest-extension-for-mediawiki\/"},"wordCount":909,"commentCount":0,"publisher":{"@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7"},"image":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2011\/11\/08\/contest-extension-for-mediawiki\/#primaryimage"},"thumbnailUrl":"https:\/\/web.archive.org\/web\/20121017212310im_\/https:\/\/www.entropywins.wtf\/blog\/wp-includes\/images\/smilies\/icon_smile.gif","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.entropywins.wtf\/blog\/2011\/11\/08\/contest-extension-for-mediawiki\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.entropywins.wtf\/blog\/2011\/11\/08\/contest-extension-for-mediawiki\/","url":"https:\/\/www.entropywins.wtf\/blog\/2011\/11\/08\/contest-extension-for-mediawiki\/","name":"Contest extension for MediaWiki - Blog of Jeroen De Dauw","isPartOf":{"@id":"https:\/\/www.entropywins.wtf\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2011\/11\/08\/contest-extension-for-mediawiki\/#primaryimage"},"image":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2011\/11\/08\/contest-extension-for-mediawiki\/#primaryimage"},"thumbnailUrl":"https:\/\/web.archive.org\/web\/20121017212310im_\/https:\/\/www.entropywins.wtf\/blog\/wp-includes\/images\/smilies\/icon_smile.gif","datePublished":"2011-11-08T22:15:18+00:00","dateModified":"2014-03-17T22:16:18+00:00","breadcrumb":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2011\/11\/08\/contest-extension-for-mediawiki\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.entropywins.wtf\/blog\/2011\/11\/08\/contest-extension-for-mediawiki\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.entropywins.wtf\/blog\/2011\/11\/08\/contest-extension-for-mediawiki\/#primaryimage","url":"https:\/\/web.archive.org\/web\/20121017212310im_\/https:\/\/www.entropywins.wtf\/blog\/wp-includes\/images\/smilies\/icon_smile.gif","contentUrl":"https:\/\/web.archive.org\/web\/20121017212310im_\/https:\/\/www.entropywins.wtf\/blog\/wp-includes\/images\/smilies\/icon_smile.gif"},{"@type":"BreadcrumbList","@id":"https:\/\/www.entropywins.wtf\/blog\/2011\/11\/08\/contest-extension-for-mediawiki\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.entropywins.wtf\/blog\/"},{"@type":"ListItem","position":2,"name":"Contest extension for MediaWiki"}]},{"@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:\/\/secure.gravatar.com\/avatar\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g","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:\/\/secure.gravatar.com\/avatar\/d62e6b5b8e332335cf17854fac850d9c70ba367c4692872613c3110ebd4e009b?s=96&d=mm&r=g"},"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-k4","jetpack-related-posts":[{"id":9,"url":"https:\/\/www.entropywins.wtf\/blog\/2009\/05\/24\/semantic-layers\/","url_meta":{"origin":1244,"position":0},"title":"Semantic Layers","author":"Jeroen","date":"2009-05-24","format":false,"excerpt":"This weekend the Google Summer of Code 2009 coding period started. I already did quite some reading an looking into the code before, but now fully got into it. As explained in my original GSoC post, the goal of my project is to create a Semantic Maps extension for Semantic\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/programming\/"},"img":{"alt_text":"Semantic Layers","src":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2009\/05\/semantic_layers_logo.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":962,"url":"https:\/\/www.entropywins.wtf\/blog\/2010\/08\/20\/end-of-google-summer-of-code-2010\/","url_meta":{"origin":1244,"position":1},"title":"End of Google Summer of Code 2010","author":"Jeroen","date":"2010-08-20","format":false,"excerpt":"As Google Summer of Code (GSoC) 2010 has ended, I'm writing this blog post to outline what I've done during the coding period and what the results are. Thanks go to the Wikimedia Foundation and Google for providing the opportunity to do this project, Brion Vibber, who mentored me, and\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/programming\/"},"img":{"alt_text":"Google Summer of Code 2010","src":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2010\/08\/2010_NoURL_300x267px.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":1081,"url":"https:\/\/www.entropywins.wtf\/blog\/2011\/05\/07\/new-mediawiki-extension-ratings\/","url_meta":{"origin":1244,"position":2},"title":"New MediaWiki extension: Ratings","author":"Jeroen","date":"2011-05-07","format":false,"excerpt":"A few weeks back I started work on a new MediaWiki extension to provide decent rating functionality. The reason: I got sick of all the crappy rating extensions out there and decided to write one that both works and has sane code. The new extension is called \"Ratings\". The Ratings\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/programming\/"},"img":{"alt_text":"MediaWiki Ratings extension","src":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2011\/04\/Mediawiki-ratings.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":792,"url":"https:\/\/www.entropywins.wtf\/blog\/2010\/04\/26\/google-summer-of-code-2010\/","url_meta":{"origin":1244,"position":3},"title":"Google Summer of Code 2010","author":"Jeroen","date":"2010-04-26","format":false,"excerpt":"Like last year, I\u2019ve been accepted for GSoC 2010 \u2013 yay! The Google Summer of Code (GSoC) is an annual program, first held from May to August 2005, in which Google awards stipends to hundreds of students who successfully complete a requested free software \/ open-source coding project during the\u2026","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/www.entropywins.wtf\/blog\/category\/programming\/"},"img":{"alt_text":"Google","src":"https:\/\/i0.wp.com\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2010\/04\/google_logo-300x125.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":1153,"url":"https:\/\/www.entropywins.wtf\/blog\/2013\/11\/24\/introduction-to-composer-for-mediawiki-developers\/","url_meta":{"origin":1244,"position":4},"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":[]},{"id":852,"url":"https:\/\/www.entropywins.wtf\/blog\/2010\/06\/10\/extension-management-platform\/","url_meta":{"origin":1244,"position":5},"title":"Extension management platform","author":"Jeroen","date":"2010-06-10","format":false,"excerpt":"After doing a pile of research on how to best create an extension management platform for MediaWiki as my Google Summer of Code project, I realized that a lot of the work that I wanted to do was already done in some form or another, and decided to somewhat augment\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":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts\/1244","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=1244"}],"version-history":[{"count":1,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts\/1244\/revisions"}],"predecessor-version":[{"id":1245,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts\/1244\/revisions\/1245"}],"wp:attachment":[{"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/media?parent=1244"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/categories?post=1244"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/tags?post=1244"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}