{"id":545,"date":"2006-05-30T23:58:30","date_gmt":"2006-05-30T21:58:30","guid":{"rendered":"http:\/\/frenchfragfactory.net\/ozh\/archives\/2006\/05\/30\/how-to-add-a-custom-function-to-mediawiki\/"},"modified":"2008-06-13T21:04:48","modified_gmt":"2008-06-13T19:04:48","slug":"how-to-add-a-custom-function-to-mediawiki","status":"publish","type":"post","link":"https:\/\/planetozh.com\/blog\/2006\/05\/how-to-add-a-custom-function-to-mediawiki\/","title":{"rendered":"How to Add a Custom Function to MediaWiki"},"content":{"rendered":"<p>Recently, I wanted to add some dynamic content to a <a href=\"http:\/\/www.mediawiki.org\/wiki\/MediaWiki\">Mediawiki<\/a> page : I wanted a project page to show how many lines of code the project currently had, and therefore I wanted something like <strong>&lt;linecount><\/strong> to be converted into something special.<\/p>\n<p>Piece of cake ? Piece of cake. Adding custom tags or custom complex functions to your wiki is really easy, and here is how it can be done.<br \/>\n<!--more--><\/p>\n<h2>Adding a custom tag<\/h2>\n<p>For example, let&#39;s create the HTML tag <strong>&lt;ozh><\/strong>. Declaring a custom HTML tags in Mediawiki is done in 3 steps :<\/p>\n<ol>\n<li>Register a new function :\n<div id=\"ig-sh-1\" class=\"syntax_hilite\">\n\n\t\t<div class=\"toolbar\">\n\n\t\t<div class=\"view-different-container\">\n\t\t\t\t\t\t<a href=\"#\" class=\"view-different\">&lt; View <span>plain text<\/span> &gt;<\/a>\n\t\t\t\t\t<\/div>\n\n\t\t<div class=\"language-name\">php<\/div>\n\n\t\t\n\t\t<br clear=\"both\">\n\n\t<\/div>\n\t\n\t<div class=\"code\">\n\t\t<ol class=\"php\" style=\"font-family:monospace\"><li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">$wgExtensionFunctions[] = 'registerSampleTag';<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">$wgExtensionCredits['parserhook'][] = array(<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; 'name' =&gt; 'SampleTag',<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; 'author' =&gt; 'Ozh',<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; 'url' =&gt; 'http:\/\/planetozh.com\/',<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">);<\/div><\/li>\n<\/ol>\t<\/div>\n\n<\/div>\n\n<\/li>\n<li>Tell the wiki that this function will be triggered by tag <strong>&lt;ozh><\/strong>\n<div id=\"ig-sh-2\" class=\"syntax_hilite\">\n\n\t\t<div class=\"toolbar\">\n\n\t\t<div class=\"view-different-container\">\n\t\t\t\t\t\t<a href=\"#\" class=\"view-different\">&lt; View <span>plain text<\/span> &gt;<\/a>\n\t\t\t\t\t<\/div>\n\n\t\t<div class=\"language-name\">php<\/div>\n\n\t\t\n\t\t<br clear=\"both\">\n\n\t<\/div>\n\t\n\t<div class=\"code\">\n\t\t<ol class=\"php\" style=\"font-family:monospace\"><li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">function registerSampleTag() {<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; global $wgParser;<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; $wgParser-&gt;setHook('ozh', 'printSampleTag');<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">}<\/div><\/li>\n<\/ol>\t<\/div>\n\n<\/div>\n\n<\/li>\n<li>Define your special function that will take care of text enclosed in your new tag\n<div id=\"ig-sh-3\" class=\"syntax_hilite\">\n\n\t\t<div class=\"toolbar\">\n\n\t\t<div class=\"view-different-container\">\n\t\t\t\t\t\t<a href=\"#\" class=\"view-different\">&lt; View <span>plain text<\/span> &gt;<\/a>\n\t\t\t\t\t<\/div>\n\n\t\t<div class=\"language-name\">php<\/div>\n\n\t\t\n\t\t<br clear=\"both\">\n\n\t<\/div>\n\t\n\t<div class=\"code\">\n\t\t<ol class=\"php\" style=\"font-family:monospace\"><li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">function printSampleTag($input,$params) {<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; foreach ($params as $key=&gt;$value) {<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; &nbsp; &nbsp; $args .= &quot;&lt;li&gt;$key = *$value*&lt;\/li&gt;\\n&quot;;<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; }<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; return('Text : '.$input.'&lt;br\/&gt;Arguments :&lt;ul&gt;'.$args.'&lt;\/ul&gt;');<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">}<\/div><\/li>\n<\/ol>\t<\/div>\n\n<\/div>\n\n<\/li>\n<\/ol>\n<p>Put these 3 functions in a file named for example <strong>sampleExtension.php<\/strong> in directory <strong>mediawiki\/extensions<\/strong>, then edit <strong>mediawiki\/LocalSettings.php<\/strong> and add the following at the end of the file, before the closing PHP tag <strong>?><\/strong> :<\/p>\n<div id=\"ig-sh-4\" class=\"syntax_hilite\">\n\n\t\t<div class=\"toolbar\">\n\n\t\t<div class=\"view-different-container\">\n\t\t\t\t\t\t<a href=\"#\" class=\"view-different\">&lt; View <span>plain text<\/span> &gt;<\/a>\n\t\t\t\t\t<\/div>\n\n\t\t<div class=\"language-name\">php<\/div>\n\n\t\t\n\t\t<br clear=\"both\">\n\n\t<\/div>\n\t\n\t<div class=\"code\">\n\t\t<ol class=\"php\" style=\"font-family:monospace\"><li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">include(&quot;extensions\/sampleExtension.php&quot;);<\/div><\/li>\n<\/ol>\t<\/div>\n\n<\/div>\n\n<p>That&#39;s it. Now, whenever your write something like <\/p>\n<div id=\"ig-sh-5\" class=\"syntax_hilite\">\n\n\t\t<div class=\"toolbar\">\n\n\t\t<div class=\"view-different-container\">\n\t\t\t\t\t\t<a href=\"#\" class=\"view-different\">&lt; View <span>plain text<\/span> &gt;<\/a>\n\t\t\t\t\t<\/div>\n\n\t\t<div class=\"language-name\">HTML<\/div>\n\n\t\t\n\t\t<br clear=\"both\">\n\n\t<\/div>\n\t\n\t<div class=\"code\">\n\t\t<ol class=\"html4strict\" style=\"font-family:monospace\"><li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\"><span style=\"color: #009900\">&lt;ozh stuff<span style=\"color: #66cc66\">=<\/span><span style=\"color: #cc66cc\">1<\/span> thing<span style=\"color: #66cc66\">=<\/span><span style=\"color: #ff0000\">&quot;someparam&quot;<\/span>&gt;<\/span>some text<span style=\"color: #009900\">&lt;<span style=\"color: #66cc66\">\/<\/span>ozh&gt;<\/span><\/div><\/li>\n<\/ol>\t<\/div>\n\n<\/div>\n\n<p> it will output <\/p>\n<div id=\"ig-sh-6\" class=\"syntax_hilite\">\n\n\t\t<div class=\"toolbar\">\n\n\t\t<div class=\"view-different-container\">\n\t\t\t\t\t\t<a href=\"#\" class=\"view-different\">&lt; View <span>plain text<\/span> &gt;<\/a>\n\t\t\t\t\t<\/div>\n\n\t\t<div class=\"language-name\">code<\/div>\n\n\t\t\n\t\t<br clear=\"both\">\n\n\t<\/div>\n\t\n\t<div class=\"code\">\n\t\t<ol class=\"code\" style=\"font-family:monospace\"><li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">Text : some text<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">Arguments :<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; stuff = 1<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; thing = someparam<\/div><\/li>\n<\/ol>\t<\/div>\n\n<\/div>\n\n<p>Ok, not the most useful stuff, but you get the idea :)<\/p>\n<h2>Adding a custom complex function<\/h2>\n<p>Now, you want to create something more complex, for example you&#39;d like a custom function adequately named ozh that would convert &quot;{{ozh:34|Quake|PHP}}&quot; converted into &quot;is 34 years old, plays Quake and writes poor PHP&quot;.<\/p>\n<p>Your custom function declaration goes through 3 similar steps :<\/p>\n<div id=\"ig-sh-7\" class=\"syntax_hilite\">\n\n\t\t<div class=\"toolbar\">\n\n\t\t<div class=\"view-different-container\">\n\t\t\t\t\t\t<a href=\"#\" class=\"view-different\">&lt; View <span>plain text<\/span> &gt;<\/a>\n\t\t\t\t\t<\/div>\n\n\t\t<div class=\"language-name\">php<\/div>\n\n\t\t\n\t\t<br clear=\"both\">\n\n\t<\/div>\n\t\n\t<div class=\"code\">\n\t\t<ol class=\"php\" style=\"font-family:monospace\"><li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\/\/ Step 1 : add a new function to register<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">$wgExtensionFunctions[] = 'registerSampleFunction';<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">$wgExtensionCredits['parserhook'][] = array(<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; 'name' =&gt; 'SampleFunction',<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; 'author' =&gt; 'Ozh',<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; 'url' =&gt; 'http:\/\/planetozh.com\/',<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">);<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp;<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\/\/ Step 2 : tell the Wiki that this function will be<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\/\/ triggered by function tag {{ozh}}<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">function registerSampleFunction() {<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; global $wgParser;<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; $wgParser-&gt;setFunctionHook('ozh', 'printSampleFunction');<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">}<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp;<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">\/\/ Step 3 : now define our function<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">function printSampleFunction(&amp;$parser, $arg1, $arg2, $arg3) {<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">&nbsp; &nbsp; return(&quot;is $arg1 years old, plays $arg2 and writes poor $arg3&quot;);<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">}<\/div><\/li>\n<\/ol>\t<\/div>\n\n<\/div>\n\n<h2>So &#8230;<\/h2>\n<p>How simple was it ? <\/p>\n<p>For the curious readers, adding a line count from a subversion project was done with a bash script like :<\/p>\n<div id=\"ig-sh-8\" class=\"syntax_hilite\">\n\n\t\t<div class=\"toolbar\">\n\n\t\t<div class=\"view-different-container\">\n\t\t\t\t\t\t<a href=\"#\" class=\"view-different\">&lt; View <span>plain text<\/span> &gt;<\/a>\n\t\t\t\t\t<\/div>\n\n\t\t<div class=\"language-name\">code<\/div>\n\n\t\t\n\t\t<br clear=\"both\">\n\n\t<\/div>\n\t\n\t<div class=\"code\">\n\t\t<ol class=\"code\" style=\"font-family:monospace\"><li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">svn export --username joe --password 123456 --force http:\/\/svn.project.com\/ \/home\/ozh\/project<\/div><\/li>\n<li style=\"font-weight: normal;vertical-align:top\"><div style=\"font: normal normal 1em\/1.2em monospace;margin:0;padding:0;background:none;vertical-align:top\">find \/home\/ozh\/project -name '*.*' | xargs wc -l | grep total | sed -e 's\/ total\/\/' &gt; \/home\/ozh\/project\/line.count<\/div><\/li>\n<\/ol>\t<\/div>\n\n<\/div>\n\n<p>The script is run periodically via cron, and a custom tag <strong>&lt;linecount><\/strong> simply calls a function that returns <strong>file_get_content(&#39;\/home\/ozh\/project\/line.count&#39;);<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Create your own complex functions in your wiki.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21],"tags":[5,2,10,76,171],"class_list":["post-545","post","type-post","status-publish","format-standard","hentry","category-published","tag-bash","tag-code","tag-php","tag-tips","tag-wiki"],"_links":{"self":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/posts\/545","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/comments?post=545"}],"version-history":[{"count":0,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/posts\/545\/revisions"}],"wp:attachment":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/media?parent=545"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/categories?post=545"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/tags?post=545"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}