{"id":1153,"date":"2013-11-24T22:07:07","date_gmt":"2013-11-24T21:07:07","guid":{"rendered":"https:\/\/www.entropywins.wtf\/blog\/?p=1153"},"modified":"2014-10-04T13:12:08","modified_gmt":"2014-10-04T12:12:08","slug":"introduction-to-composer-for-mediawiki-developers","status":"publish","type":"post","link":"https:\/\/www.entropywins.wtf\/blog\/2013\/11\/24\/introduction-to-composer-for-mediawiki-developers\/","title":{"rendered":"Introduction to Composer for MediaWiki developers"},"content":{"rendered":"<p>This post aims to be a quick start guide for MediaWiki extension developers that want to get their extension to be installable via Composer.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignright\" src=\"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2013\/11\/logo-composer-transparent.png\" alt=\"\" width=\"300\" height=\"356\" \/><\/p>\n<p>If you are not yet familiar with Composer, I recommend you have a look at the <a href=\"https:\/\/www.mediawiki.org\/wiki\/Composer\">Composer page on MediaWiki.org<\/a> before continuing with this post.<\/p>\n<p><strong>Defining your package info<\/strong><\/p>\n<p>Each extension or library is a package. And for Composer to be able to work with your package, it needs some information, such as the name of your package. This information goes into a file named composer.json, which you should put at the root of your package. You can <a href=\"http:\/\/getcomposer.org\/doc\/01-basic-usage.md#composer-json-project-setup\">read more on this in the Composer documentation<\/a>.<\/p>\n<p>Important to understand here is that packages are installed into MediaWiki, rather than MediaWiki and extensions being installed into another package. This means one should not list MediaWiki itself as a dependency of your package. Most existing extensions do not have any dependencies, so there is a good chance you just want to specify the minimum PHP version.<\/p>\n<p>[Edit: it is now possible to list MediaWiki as a dependency and thus <a href=\"https:\/\/www.entropywins.wtf\/blog\/2014\/01\/02\/mediawiki-extensions-to-define-their-mediawiki-compatibility\/\">specify MediaWiki compatibility for your extension<\/a>.]<\/p>\n<p><strong>Having your extension loaded<\/strong><\/p>\n<p>When using Composer to install your extension, users no longer have to manually include its entry point from their LocalSettings.php file. Composer takes care of all the autoloading. It does so based on the package definitions, which means you have to specify how to load your package in your composer.json file. This is done in the <a href=\"http:\/\/getcomposer.org\/doc\/04-schema.md#autoload\">autoload section<\/a>.<\/p>\n<p>The simplest way to get this done for your typical MediaWiki extension is to use the \u201cfile\u201d loading support. This will look as follows:<\/p>\n<pre>{\r\n    \"autoload\": {\r\n        \"files\": [\"MyExtension.php\"]\r\n    }\r\n}<\/pre>\n<div id=\"crayon-52ebbf9b4fb8b473152389\" data-settings=\" minimize scroll-mouseover\">\n<p>In this example, MyExtension.php is the entry point of your extension. The path is relative to your package root.<\/p>\n<p><strong>Global scope assumptions<\/strong><\/p>\n<p>Unfortunately just specifying the entry point of your extension is unlikely to make the loading work already. The reason for this being that virtually all MediaWiki extensions assume their entry point gets included from global scope. They do so by accessing global variables (ie wgExtensionCredits or wgAutoloadClasses). This works in the typical MediaWiki use case because these entry points get included from LocalSettings.php, which itself is included from global scope. When this assumption is broken, as is the case when Composer loads your entry point, your code ends up breaking.<\/p>\n<p>The fix for this is to make all references to globals explicit. You can change<\/p>\n<pre>$wgExtensionCredits['awesome'][] = array( \/*...*\/ );<\/pre>\n<p>into<\/p>\n<pre>global $wgExtensionCredits;\r\n$wgExtensionCredits['awesome'][] = array( <code>\/*...*\/<\/code> );<\/pre>\n<p>or into<\/p>\n<pre>$GLOBALS['wgExtensionCredits']['awesome'][] = array( <code>\/*...*\/<\/code> );<\/pre>\n<p>I personally prefer the later approach, as it is much less error prone. There is some religion against using this style in the MediaWiki community though, so luckily going with the former approach works just as fine.<\/p>\n<p>You can make these changes before making the other steps to support Composer. I highly recommend you to avoid global scope assumptions in any new code you write, if it is going to support Composer or not, as it is simply bad practice to not do so. Composer is not the only standard tool that will not work for you when this is done wrong, PHPUnit is another good example, though that is another story altogether.<\/p>\n<p>It is clearly important to verify that you got rid of all global scope assumptions and did not miss one. And to notice if new ones get introduced, even while you might typically not be running your extension via a Composer install. This can be both achieved easily by making your code not execute in global scope, no matter how it is included. You can do this by means of self executing anonymous function. You can use this to wrap the code in your entry point file, or to wrap the inclusion statement for it in your LocalSettings file. The below example demonstrates the second approach, which is simpler, though clearly does not address the issue for other developers:<\/p>\n<pre>call_user_func( function() {\r\n\trequire_once( __DIR__ . \"\/extensions\/MyExtension\/MyExtension.php\" );\r\n} );<\/pre>\n<p><strong>Specifying the package type<\/strong><\/p>\n<p>You might have been wondering where your extension gets put when it is installed.<\/p>\n<p>By default Composer puts packages in a directory called \u201cvendor\u201d. This directory is created in the root of the package into which the Composer install is done. So when using MediaWiki 1.22 or later, this will be in the MediaWiki root. When using <a href=\"https:\/\/github.com\/JeroenDeDauw\/ExtensionInstaller\">the ExtensionInstaller<\/a> for older versions of MediaWiki, it will be in the root of the extension installer, at extensions\/ExtensionInstaller\/vendor.<\/p>\n<p>The packages themselves are by default then put into vendor-name\/package-name. So Semantic MediaWiki would, if it used the default behavior, end up in vendor\/mediawiki\/semantic-mediawiki.<\/p>\n<p>For your typical PHP library this is the desired behavior. However for MediaWiki extensions we rather have them end up in in the extensions directory. For some extensions this might be a requirement, if they assume something about this path (which of course they ideally do not). Furthermore one wants Semantic MediaWiki to send up in extensions\/SemanticMediaWiki, not in extensions\/mediawiki\/semantic-mediawiki. Both these behaviors can be achieved by specifying your package to be of type \u201cmediawiki-extension\u201d.<\/p>\n<pre>{\r\n    \"name\": \"mediawiki\/semantic-mediawiki\",\r\n    \"type\": \"mediawiki-extension\",\r\n    \/\/ ...\r\n}<\/pre>\n<p><strong>Publish on Packagist<\/strong><\/p>\n<p>After you followed the above steps, your extension should be ready to be installed via Composer. Composer needs to be able to find your package so it can install it.<\/p>\n<p>You can have your users specify the location of your source repository in their composer.json file. Read <a href=\"http:\/\/getcomposer.org\/doc\/05-repositories.md\">the repositories documentation<\/a> for more info.<\/p>\n<p>That approach is far from ideal though, as it requires more work from everyone installing your package, and exposes them to the location of your source code. This approach is mainly useful if you have no alternatives, or for getting started yourself with Composer without publishing your package.<\/p>\n<p>The standard approach is to publish your package on the Packagist package repository. This is a public collection of packages, which Composer consults whenever one does an install. So once your package is on there, users are able to install it into MediaWiki with a single \u201ccomposer require vendor-name\/package-name\u201d command. Have a look at <a href=\"https:\/\/packagist.org\/\">Packagist<\/a> and its documentation to get started with this.<\/p>\n<p><strong>Releasing versions<\/strong><\/p>\n<p>Unless users specify that they want to get a development version, Composer will only install stable releases for them. Creating a stable release is done by creating a git tag in <a href=\"http:\/\/semver.org\/\">semantic versioning format<\/a>. For instance \u201c1.4.2\u2033. Once this is done, make sure the package on Packagist gets updated. If you have your code on GitHub, this can be done automatically.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>This post aims to be a quick start guide for MediaWiki extension developers that want to get their extension to&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":[306,92,156,157,313,195,197],"class_list":["post-1153","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-composer","tag-extension-management","tag-mediawiki","tag-mediawiki-extensions","tag-packagist","tag-php","tag-planet-wikimedia"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Introduction to Composer for MediaWiki developers - 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\/11\/24\/introduction-to-composer-for-mediawiki-developers\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Introduction to Composer for MediaWiki developers - Blog of Jeroen De Dauw\" \/>\n<meta property=\"og:description\" content=\"This post aims to be a quick start guide for MediaWiki extension developers that want to get their extension to&hellip;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.entropywins.wtf\/blog\/2013\/11\/24\/introduction-to-composer-for-mediawiki-developers\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog of Jeroen De Dauw\" \/>\n<meta property=\"article:published_time\" content=\"2013-11-24T21:07:07+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2014-10-04T12:12:08+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2013\/11\/logo-composer-transparent.png\" \/>\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\\\/2013\\\/11\\\/24\\\/introduction-to-composer-for-mediawiki-developers\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2013\\\/11\\\/24\\\/introduction-to-composer-for-mediawiki-developers\\\/\"},\"author\":{\"name\":\"Jeroen\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/#\\\/schema\\\/person\\\/4e2ef14f2ca7dc3a0ac137d1692b66b7\"},\"headline\":\"Introduction to Composer for MediaWiki developers\",\"datePublished\":\"2013-11-24T21:07:07+00:00\",\"dateModified\":\"2014-10-04T12:12:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2013\\\/11\\\/24\\\/introduction-to-composer-for-mediawiki-developers\\\/\"},\"wordCount\":1064,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/#\\\/schema\\\/person\\\/4e2ef14f2ca7dc3a0ac137d1692b66b7\"},\"image\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2013\\\/11\\\/24\\\/introduction-to-composer-for-mediawiki-developers\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/wp-content\\\/uploads\\\/2013\\\/11\\\/logo-composer-transparent.png\",\"keywords\":[\"composer\",\"Extension management\",\"MediaWiki\",\"MediaWiki extensions\",\"packagist\",\"PHP\",\"Planet Wikimedia\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2013\\\/11\\\/24\\\/introduction-to-composer-for-mediawiki-developers\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2013\\\/11\\\/24\\\/introduction-to-composer-for-mediawiki-developers\\\/\",\"url\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2013\\\/11\\\/24\\\/introduction-to-composer-for-mediawiki-developers\\\/\",\"name\":\"Introduction to Composer for MediaWiki developers - Blog of Jeroen De Dauw\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2013\\\/11\\\/24\\\/introduction-to-composer-for-mediawiki-developers\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2013\\\/11\\\/24\\\/introduction-to-composer-for-mediawiki-developers\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/wp-content\\\/uploads\\\/2013\\\/11\\\/logo-composer-transparent.png\",\"datePublished\":\"2013-11-24T21:07:07+00:00\",\"dateModified\":\"2014-10-04T12:12:08+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2013\\\/11\\\/24\\\/introduction-to-composer-for-mediawiki-developers\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2013\\\/11\\\/24\\\/introduction-to-composer-for-mediawiki-developers\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2013\\\/11\\\/24\\\/introduction-to-composer-for-mediawiki-developers\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/wp-content\\\/uploads\\\/2013\\\/11\\\/logo-composer-transparent.png\",\"contentUrl\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/wp-content\\\/uploads\\\/2013\\\/11\\\/logo-composer-transparent.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/2013\\\/11\\\/24\\\/introduction-to-composer-for-mediawiki-developers\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.entropywins.wtf\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Introduction to Composer for MediaWiki developers\"}]},{\"@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":"Introduction to Composer for MediaWiki developers - 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\/11\/24\/introduction-to-composer-for-mediawiki-developers\/","og_locale":"en_US","og_type":"article","og_title":"Introduction to Composer for MediaWiki developers - Blog of Jeroen De Dauw","og_description":"This post aims to be a quick start guide for MediaWiki extension developers that want to get their extension to&hellip;","og_url":"https:\/\/www.entropywins.wtf\/blog\/2013\/11\/24\/introduction-to-composer-for-mediawiki-developers\/","og_site_name":"Blog of Jeroen De Dauw","article_published_time":"2013-11-24T21:07:07+00:00","article_modified_time":"2014-10-04T12:12:08+00:00","og_image":[{"url":"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2013\/11\/logo-composer-transparent.png","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\/2013\/11\/24\/introduction-to-composer-for-mediawiki-developers\/#article","isPartOf":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/11\/24\/introduction-to-composer-for-mediawiki-developers\/"},"author":{"name":"Jeroen","@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7"},"headline":"Introduction to Composer for MediaWiki developers","datePublished":"2013-11-24T21:07:07+00:00","dateModified":"2014-10-04T12:12:08+00:00","mainEntityOfPage":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/11\/24\/introduction-to-composer-for-mediawiki-developers\/"},"wordCount":1064,"commentCount":0,"publisher":{"@id":"https:\/\/www.entropywins.wtf\/blog\/#\/schema\/person\/4e2ef14f2ca7dc3a0ac137d1692b66b7"},"image":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/11\/24\/introduction-to-composer-for-mediawiki-developers\/#primaryimage"},"thumbnailUrl":"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2013\/11\/logo-composer-transparent.png","keywords":["composer","Extension management","MediaWiki","MediaWiki extensions","packagist","PHP","Planet Wikimedia"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.entropywins.wtf\/blog\/2013\/11\/24\/introduction-to-composer-for-mediawiki-developers\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/11\/24\/introduction-to-composer-for-mediawiki-developers\/","url":"https:\/\/www.entropywins.wtf\/blog\/2013\/11\/24\/introduction-to-composer-for-mediawiki-developers\/","name":"Introduction to Composer for MediaWiki developers - Blog of Jeroen De Dauw","isPartOf":{"@id":"https:\/\/www.entropywins.wtf\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/11\/24\/introduction-to-composer-for-mediawiki-developers\/#primaryimage"},"image":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/11\/24\/introduction-to-composer-for-mediawiki-developers\/#primaryimage"},"thumbnailUrl":"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2013\/11\/logo-composer-transparent.png","datePublished":"2013-11-24T21:07:07+00:00","dateModified":"2014-10-04T12:12:08+00:00","breadcrumb":{"@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/11\/24\/introduction-to-composer-for-mediawiki-developers\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.entropywins.wtf\/blog\/2013\/11\/24\/introduction-to-composer-for-mediawiki-developers\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/11\/24\/introduction-to-composer-for-mediawiki-developers\/#primaryimage","url":"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2013\/11\/logo-composer-transparent.png","contentUrl":"https:\/\/www.entropywins.wtf\/blog\/wp-content\/uploads\/2013\/11\/logo-composer-transparent.png"},{"@type":"BreadcrumbList","@id":"https:\/\/www.entropywins.wtf\/blog\/2013\/11\/24\/introduction-to-composer-for-mediawiki-developers\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.entropywins.wtf\/blog\/"},{"@type":"ListItem","position":2,"name":"Introduction to Composer for MediaWiki developers"}]},{"@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-iB","jetpack-related-posts":[{"id":1172,"url":"https:\/\/www.entropywins.wtf\/blog\/2014\/01\/02\/mediawiki-extensions-to-define-their-mediawiki-compatibility\/","url_meta":{"origin":1153,"position":0},"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":1153,"position":1},"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":1158,"url":"https:\/\/www.entropywins.wtf\/blog\/2013\/11\/24\/upgrading-an-extension-that-now-uses-composer\/","url_meta":{"origin":1153,"position":2},"title":"Upgrading an extension that now uses Composer","author":"Jeroen","date":"2013-11-24","format":false,"excerpt":"This blog post is aimed at users of the MediaWiki software that have extensions installed, and want to upgrade one or more to a version that makes use of Composer. At present this is of particular relevance for those upgrading to SMW 1.9 beta or Maps 3.0 alpha. If you\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":1160,"url":"https:\/\/www.entropywins.wtf\/blog\/2013\/11\/28\/my-adventures-with-autoloading-in-php\/","url_meta":{"origin":1153,"position":3},"title":"My adventures with autoloading in PHP","author":"Jeroen","date":"2013-11-28","format":false,"excerpt":"This post has as audience developers and will provide readers with insights on how to cleanly autoload classes in PHP. For a long long time, I\u2019ve been one of those MediaWiki developers that just added classes and file names to $wgAutoloadClasses, without really knowing how this made class loading work\u2026","rel":"","context":"In \"Autoloading\"","block_context":{"text":"Autoloading","link":"https:\/\/www.entropywins.wtf\/blog\/tag\/autoloading\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1207,"url":"https:\/\/www.entropywins.wtf\/blog\/2014\/03\/01\/semantic-extra-special-properties-1-0-released\/","url_meta":{"origin":1153,"position":4},"title":"Semantic Extra Special Properties 1.0 released!","author":"Jeroen","date":"2014-03-01","format":false,"excerpt":"I am happy to announce the 1.0 release of the Semantic Extra Special Properties extension! This release fixes various issues and makes the extension compatible with the latest MediaWiki, Semantic MediaWiki and PHP versions. It adds several new special properties such as PAGEID and EXIFDATA, as well as providing performance\u2026","rel":"","context":"In &quot;Software&quot;","block_context":{"text":"Software","link":"https:\/\/www.entropywins.wtf\/blog\/category\/software\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2673,"url":"https:\/\/www.entropywins.wtf\/blog\/2019\/10\/26\/new-mediawiki-blog\/","url_meta":{"origin":1153,"position":5},"title":"New MediaWiki blog","author":"Jeroen","date":"2019-10-26","format":false,"excerpt":"I'm happy to announce a brand new blog dedicated to MediaWiki and all things enterprise wiki related. Half a year ago I launched Professional Wiki together with Karsten Hoffmeyer. Professional Wiki is, as the name suggests, a company providing professional wiki services. We help companies create and manage wikis, we\u2026","rel":"","context":"In &quot;News&quot;","block_context":{"text":"News","link":"https:\/\/www.entropywins.wtf\/blog\/category\/news\/"},"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\/1153","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=1153"}],"version-history":[{"count":8,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts\/1153\/revisions"}],"predecessor-version":[{"id":1411,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/posts\/1153\/revisions\/1411"}],"wp:attachment":[{"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/media?parent=1153"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/categories?post=1153"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.entropywins.wtf\/blog\/wp-json\/wp\/v2\/tags?post=1153"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}