{"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 class=\"igsh-code-box\" id=\"ig-sh-1\"><pre class=\"language-php line-numbers\" data-no-optimize=\"1\" data-cfasync=\"false\"><code class=\"language-php\">$wgExtensionFunctions[] = &#039;registerSampleTag&#039;;\r\n$wgExtensionCredits[&#039;parserhook&#039;][] = array(\r\n\t&#039;name&#039; =&gt; &#039;SampleTag&#039;,\r\n\t&#039;author&#039; =&gt; &#039;Ozh&#039;,\r\n\t&#039;url&#039; =&gt; &#039;http:\/\/planetozh.com\/&#039;,\r\n);<\/code><\/pre><\/div>\n<\/li>\n<li>Tell the wiki that this function will be triggered by tag <strong>&lt;ozh><\/strong>\n<div class=\"igsh-code-box\" id=\"ig-sh-2\"><pre class=\"language-php line-numbers\" data-no-optimize=\"1\" data-cfasync=\"false\"><code class=\"language-php\">function registerSampleTag() {\r\n    global $wgParser;\r\n    $wgParser-&gt;setHook(&#039;ozh&#039;, &#039;printSampleTag&#039;);\r\n}<\/code><\/pre><\/div>\n<\/li>\n<li>Define your special function that will take care of text enclosed in your new tag\n<div class=\"igsh-code-box\" id=\"ig-sh-3\"><pre class=\"language-php line-numbers\" data-no-optimize=\"1\" data-cfasync=\"false\"><code class=\"language-php\">function printSampleTag($input,$params) {\r\n\tforeach ($params as $key=&gt;$value) {\r\n\t\t$args .= &quot;&lt;li&gt;$key = *$value*&lt;\/li&gt;\\n&quot;;\r\n\t}\r\n\treturn(&#039;Text : &#039;.$input.&#039;&lt;br\/&gt;Arguments :&lt;ul&gt;&#039;.$args.&#039;&lt;\/ul&gt;&#039;);\r\n}<\/code><\/pre><\/div>\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 class=\"igsh-code-box\" id=\"ig-sh-4\"><pre class=\"language-php line-numbers\" data-no-optimize=\"1\" data-cfasync=\"false\"><code class=\"language-php\">include(&quot;extensions\/sampleExtension.php&quot;);<\/code><\/pre><\/div>\n<p>That&#39;s it. Now, whenever your write something like <\/p>\n<div class=\"igsh-code-box\" id=\"ig-sh-5\"><pre class=\"language-markup line-numbers\" data-no-optimize=\"1\" data-cfasync=\"false\"><code class=\"language-markup\">&lt;ozh stuff=1 thing=&quot;someparam&quot;&gt;some text&lt;\/ozh&gt;<\/code><\/pre><\/div>\n<p> it will output <\/p>\n<div class=\"igsh-code-box\" id=\"ig-sh-6\"><pre class=\"language-none line-numbers\" data-no-optimize=\"1\" data-cfasync=\"false\"><code class=\"language-none\">Text : some text\r\nArguments :\r\n\tstuff = 1\r\n\tthing = someparam<\/code><\/pre><\/div>\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 class=\"igsh-code-box\" id=\"ig-sh-7\"><pre class=\"language-php line-numbers\" data-no-optimize=\"1\" data-cfasync=\"false\"><code class=\"language-php\">\/\/ Step 1 : add a new function to register\r\n$wgExtensionFunctions[] = &#039;registerSampleFunction&#039;;\r\n$wgExtensionCredits[&#039;parserhook&#039;][] = array(\r\n\t&#039;name&#039; =&gt; &#039;SampleFunction&#039;,\r\n\t&#039;author&#039; =&gt; &#039;Ozh&#039;,\r\n\t&#039;url&#039; =&gt; &#039;http:\/\/planetozh.com\/&#039;,\r\n);\r\n\r\n\/\/ Step 2 : tell the Wiki that this function will be\r\n\/\/ triggered by function tag {{ozh}}\r\nfunction registerSampleFunction() {\r\n    global $wgParser;\r\n    $wgParser-&gt;setFunctionHook(&#039;ozh&#039;, &#039;printSampleFunction&#039;);\r\n}\r\n\r\n\/\/ Step 3 : now define our function\r\nfunction printSampleFunction(&amp;$parser, $arg1, $arg2, $arg3) {\r\n\treturn(&quot;is $arg1 years old, plays $arg2 and writes poor $arg3&quot;);\r\n}<\/code><\/pre><\/div>\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 class=\"igsh-code-box\" id=\"ig-sh-8\"><pre class=\"language-none line-numbers\" data-no-optimize=\"1\" data-cfasync=\"false\"><code class=\"language-none\">svn export --username joe --password 123456 --force http:\/\/svn.project.com\/ \/home\/ozh\/project\r\nfind \/home\/ozh\/project -name &#039;*.*&#039; | xargs wc -l | grep total | sed -e &#039;s\/ total\/\/&#039; &gt; \/home\/ozh\/project\/line.count<\/code><\/pre><\/div>\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}]}}