How to Create a MediaWiki Skin from Scratch

Many sites use the MediaWiki software, including wikiHow! As you can see, despite the fact that MediaWiki comes with a set of ready-to-use skins, many sites, such as wikiHow, choose to have their own skin to give the site a unique look and feel. Customizing how a MediaWiki based site looks can be achieved in many ways all involving skins. Usually, creating a new skin from scratch is not necessary for many levels of customizations. In other situations, creating a skin based on one of the already-implemented ones, such as MonoBook, then tweaking it to your needs will be more than enough. However, if you really want to dramatically change the layout of the wiki, you might need to create your own skin from the ground up. This article will guide you with doing this in a systematic, organized and easy way!
For the purpose of demonstration, the article will assume your new skin will be called TrialSkin. You should replace all references to "TrialSkin" with the name of your skin.

Setting Up Your Skin

Create the basic file structure for your new skin.

This includes creating the following files and folders (all of which should be added to the skins folder of your MediaWiki installation):

  • A TrialSkin.php file – This is where you will put most of the code and define the layout of pages.
  • A TrialSkin.deps.php file – This is a standard file that most likely will contain the same code. It is created to fix a bug with PHP.
  • The trialskin directory – All other files related to your skin should go in this directory, including style-sheets and images.
  • A /skins/trialskin/main.css file which will contain the main stylesheet for the skin – [Optional, but most likely to be needed]
  • Browser specific stylesheet fixes files, such as /skins/trialskin/IE60Fixes.css – [Optional, but preferred]

Add the initialization code.

Replace TrialSkin with the name of your skin and trialskin with the name of your skin after turning all letters to small case.

Add the “Category List Fix” code.

Just copy and paste the following code to the body of the template class (TrialSkinTemplate in this example), preferably after the initialization code.

Define the execute() function, which will be called to output the pages’ contents to client browsers.

Declare the global variable $wgUser in the execute() function and use its getSkin() method to obtain a $skin variable/object.

You will most likely need that variable. However, if you do not need it, then there is no need to do this step. You’ll find a standard example of declaring the execute() function with the most commonly used code in the “Declaration of the execute() Function” sub-section.

Start adding code (both PHP and XHTML) to render pages in your wiki.

Most likely, although you might need to dramatically change the layout, but you’ll need to render the same set of information that normal skins do (with some alterations maybe). The most commonly added elements/components/blocks for a page are (see corresponding sub-sections for details and/or sample codes):

  • The XHTML code which opens (and eventually closes) the HTML output that will be sent to the client’s browser.
  • The head element, which imports style-sheets, scripts, defines the page’s meta data, and specifies the title to be displayed in the browser’s title bar for the specific page being viewed.
  • The body opening tag. This tag opens the body element of the page and specifies what happens when the page loads or is double clicked if such handlers exist.
  • The site’s name block.
  • The site’s logo image.
  • The site’s tag-line
  • Site Notice block.
  • User message notification block (if there is a need for it)
  • The user’s toolbar.
  • Intrapage navigation block.
  • Search.
  • Toolbox.
  • Language links.
  • Page name.
  • Page subtitle.
  • Undelete notice.
  • Page contents.
  • Category links.
  • Page toolbar.
  • Footer.
  • Closing trail.

Adding Code to Your Pages

Use this example for your Main execute() Method Code.

You might remove the lines that declare $wgUser, $wgSitename and $skin if you are not going to use them.

Add the Main XHTML Structure Code.

This is the Oening Code – here, you instruct the skin to output the HTML tag and declare all necessary XHTML namespaces. The following code is a standard declaration that you might customize but most likely will not need to.

  • The head element – here, you output the head element along with all its contents. This includes style-sheets links, client-side scripts and meta data for robots and browsers. The code included here is a standard code that you might need to modify to include any custom scripts or style-sheets to be included.For this code to work as expected you’ll need to have the following files (you may remove the lines importing any of these style-sheets if you don’t need them):/common/commonPrint.css – style-sheet for printing pages. You might change the path to this style-sheet if you don’t want to use the standard print style-sheet.main.css, contents.css – main style-sheets for your skin. These must be in your skin’s directory (/skins/trialskin in this example)handheld.css – a style-sheet to be used with hand-held devices.IE50Fixes.css, IE55Fixes.css, IE60Fixes.css, IE70Fixes.css – fixes for different browsers. You may copy these files from one of the already-existing skins, most likely you’ll need to change nothing on these files.The last lines, starting at “/*** various MediaWiki-related scripts and styles ***/ ” include user specific, page specific and site-wide specific style-sheets. If you don’t support these features, just remove them all up to the comment.It has been noticed that the $this->html(‘headscripts’) call sometimes causes trouble, so if anything goes wrong try to remove it.In case the code does not work for some reason, you might forget about this code altogether and write your own, including the style-sheet links, scripts, and title tag all written by your own code! <meta http-equiv=”Content-Type” content=”text(‘mimetype’) ?>; charset=text(‘charset’) ?>” /> html(‘headlinks’) ?>/*<![CDATA[*/ @import “text(‘stylepath’) ?>/text(‘stylename’) ?>/main.css?”; @import “text(‘stylepath’) ?>/text(‘stylename’) ?>/contents.css?”; /*]]>*/ <link rel=”stylesheet” type=”text/css” data[‘printable’]) ) { ?>media=”print” href=”text(‘stylepath’) ?>/common/commonPrint.css?” /> <link rel=”stylesheet” type=”text/css” media=”handheld” href=”text(‘stylepath’) ?>/text(‘stylename’) ?>/handheld.css?” /> data); ?> <script type=”text(‘jsmimetype’) ?>” src=”text(‘stylepath’) ?>/common/wikibits.js?”>data[‘jsvarurl’]) { ?> <script type=”text(‘jsmimetype’) ?>” src=”text(‘jsvarurl’) ?>”>data[‘pagecss’]) { ?> html(‘pagecss’) ?>data[‘usercss’]) { ?> html(‘usercss’) ?>data[‘userjs’]) { ?> <script type=”text(‘jsmimetype’) ?>” src=”text(‘userjs’ ) ?>”>data[‘userjsprev’]) { ?> <script type=”text(‘jsmimetype’) ?>”>html(‘userjsprev’) ?>data[‘trackbackhtml’]) print $this->data[‘trackbackhtml’]; ?> html(‘headscripts’) ?>
  • For this code to work as expected you’ll need to have the following files (you may remove the lines importing any of these style-sheets if you don’t need them):/common/commonPrint.css – style-sheet for printing pages. You might change the path to this style-sheet if you don’t want to use the standard print style-sheet.main.css, contents.css – main style-sheets for your skin. These must be in your skin’s directory (/skins/trialskin in this example)handheld.css – a style-sheet to be used with hand-held devices.IE50Fixes.css, IE55Fixes.css, IE60Fixes.css, IE70Fixes.css – fixes for different browsers. You may copy these files from one of the already-existing skins, most likely you’ll need to change nothing on these files.
  • /common/commonPrint.css – style-sheet for printing pages. You might change the path to this style-sheet if you don’t want to use the standard print style-sheet.
  • main.css, contents.css – main style-sheets for your skin. These must be in your skin’s directory (/skins/trialskin in this example)
  • handheld.css – a style-sheet to be used with hand-held devices.
  • IE50Fixes.css, IE55Fixes.css, IE60Fixes.css, IE70Fixes.css – fixes for different browsers. You may copy these files from one of the already-existing skins, most likely you’ll need to change nothing on these files.
  • The last lines, starting at “/*** various MediaWiki-related scripts and styles ***/ ” include user specific, page specific and site-wide specific style-sheets. If you don’t support these features, just remove them all up to the comment.
  • It has been noticed that the $this->html(‘headscripts’) call sometimes causes trouble, so if anything goes wrong try to remove it.
  • In case the code does not work for some reason, you might forget about this code altogether and write your own, including the style-sheet links, scripts, and title tag all written by your own code! <meta http-equiv=”Content-Type” content=”text(‘mimetype’) ?>; charset=text(‘charset’) ?>” /> html(‘headlinks’) ?>/*<![CDATA[*/ @import “text(‘stylepath’) ?>/text(‘stylename’) ?>/main.css?”; @import “text(‘stylepath’) ?>/text(‘stylename’) ?>/contents.css?”; /*]]>*/ <link rel=”stylesheet” type=”text/css” data[‘printable’]) ) { ?>media=”print” href=”text(‘stylepath’) ?>/common/commonPrint.css?” /> <link rel=”stylesheet” type=”text/css” media=”handheld” href=”text(‘stylepath’) ?>/text(‘stylename’) ?>/handheld.css?” /> data); ?> <script type=”text(‘jsmimetype’) ?>” src=”text(‘stylepath’) ?>/common/wikibits.js?”>data[‘jsvarurl’]) { ?> <script type=”text(‘jsmimetype’) ?>” src=”text(‘jsvarurl’) ?>”>data[‘pagecss’]) { ?> html(‘pagecss’) ?>data[‘usercss’]) { ?> html(‘usercss’) ?>data[‘userjs’]) { ?> <script type=”text(‘jsmimetype’) ?>” src=”text(‘userjs’ ) ?>”>data[‘userjsprev’]) { ?> <script type=”text(‘jsmimetype’) ?>”>html(‘userjsprev’) ?>data[‘trackbackhtml’]) print $this->data[‘trackbackhtml’]; ?> html(‘headscripts’) ?>
  • The body opening tag – renders the opening body tag. Most likely, you won’t need to modify this unless you want to hard code the body styles into the tag.<body data[‘body_ondblclick’]) { ?>ondblclick=”text(‘body_ondblclick’) ?>” data[‘body_onload’]) { ?>onload=”text(‘body_onload’) ?>” class=”mediawiki text(‘nsclass’) ?> text(‘dir’) ?> text(‘pageclass’) ?>”>
  • Closing trail – this is appended at the end of the file. It closes any opened tags, scripts, php code … etc. All following code should be put before this, it should be the last lines of the skin file.html(‘bottomscripts’); /* JS call to runBodyOnloadHook */ ?>html(‘reporttime’) ?>data[‘debug’] ): ?><!– Debug output:text( ‘debug’ ); ?> –>

Use this example of common site elements’ code.

The use of $this->text($msg) and $this->html($msg). it will be used a lot across the skin.

  • Site’s name:text(‘sitename’) ?>
  • Site’s logo image:

    <script type=”text(‘jsmimetype’) ?>”> if (window.isMSIE55) fixalpha();

  • Site’s tag-line:

    msg(‘tagline’) ?>

  • The site-notice block – site notice content is usually edited and added to the WikiMedia:Sitenotice message page.data[‘sitenotice’]) { ?>
    html(‘sitenotice’) ?>
  • User message notification block:data[‘newtalk’]) { ?>
    html(‘newtalk’) ?>
  • Intrapage navigation block – this is optional.data[‘showjumplinks’]) { ?>

Incorporate common page elements’ code.

  • Page name:

    data[‘displaytitle’]!=””?$this->html(‘title’):$this->text(‘title’) ?>

  • Page subtitle:
    html(‘subtitle’) ?>
  • Page contents:html(‘bodytext’) ?>
  • Category links:data[‘catlinks’]) { ?>
  • Footer – this code is iterative so take care while copying it!

Use this example of common toolbars code.

  • This renders the user’s navigation links such as the user’s page, talk page, logout link … etc.
    msg(‘personaltools’) ?>

      data[‘personal_urls’] as $key => $item) { ?> <li id=”pt-” class=”active”><a href=””tooltipAndAccesskey(‘pt-‘.$key) ?> class=””>
  • Page toolbar – which includes the edit, create, discuss links along with others depending on the user’s group.
    msg(‘views’) ?>

      data[‘content_actions’] as $key => $tab) { ?> <li id=”ca-” class=””><a href=””tooltipAndAccesskey(‘ca-‘.$key) ?>>
  • Undelete notice – if the page was deleted before and the user can undelete pages, this link should appear (if you choose to).data[‘undelete’]) { ?>
    html(‘undelete’) ?>

Incorporate portlets (main navigation blocks).

  • Search portlet – the search box. This is a minimal implementation that only shows what needs to be outputted for the search box to work.
  • msg(‘toolbox’) ?>
      • data[‘notspecialpage’]) { ?>

      Toolbox portlet:

      • <a href=”data[‘nav_urls’][‘whatlinkshere’][‘href’]) ?>”tooltipAndAccesskey(‘t-whatlinkshere’) ?>>msg(‘whatlinkshere’) ?>

    data[‘nav_urls’][‘recentchangeslinked’] ) { ?>

      • <a href=”data[‘nav_urls’][‘recentchangeslinked’][‘href’]) ?>”tooltipAndAccesskey(‘t-recentchangeslinked’) ?>>msg(‘recentchangeslinked’) ?>

    data[‘nav_urls’][‘trackbacklink’])) { ?>

    data[‘feeds’]) { ?>

    data[‘nav_urls’][$special]) { ?><li id=”t-“><a href=”data[‘nav_urls’][$special][‘href’]) ?>”tooltipAndAccesskey(‘t-‘.$special) ?>>msg($special) ?>

    data[‘nav_urls’][‘print’][‘href’])) { ?>

      • <a href=”data[‘nav_urls’][‘print’][‘href’]) ?>”tooltipAndAccesskey(‘t-print’) ?>>msg(‘printableversion’) ?>

    data[‘nav_urls’][‘permalink’][‘href’])) { ?>

    data[‘nav_urls’][‘permalink’][‘href’] === ”) { ?> <li id=”t-ispermalink”tooltip(‘t-ispermalink’) ?>>msg(‘permalink’) ?>

  • Language links:data[‘language_urls’] ) { ?>
    msg(‘otherlanguages’) ?>
      data[‘language_urls’] as $langlink) { ?> <li class=””><a href=””>

Tips

  • All code in this article provides a standard minimum implementation. It is meant to show the reader how to extract information from the skin template class and what he/she needs to consider about each piece of information. You may (and most likely will) modify the default behaviors included in this implementation.
  • As your code grows longer, you might want to separate some of it in a separate file and include it in your main skin file.
  • You might create separate functions to render specific parts of the interface. This is especially useful for parts needing long code and requiring modifications from your side.

Warnings

  • Always backup your MediaWiki database, installation directory and any related items before attempting to create or change your new skin.
  • This procedure should be performed by someone (or at least under the supervision of someone) with moderate knowledge of the MediaWiki software and the PHP language. Errors in code might cause unexpected results and bugs.

Leave a Comment