Community Central
Register
Community Central


These are css/js/parserfunction/magicword hacks that I either developed or "discovered", by myself, by user request, or with the help of other wiki users. Others may have done them proir to me, but in most cases I had no external help in figuring them out (other than the help pages on meta). Mostly this page is to document the requests for tweaks I've been asked to do on wikia, but several also apply to Uncyclopedia or Wikipedia.

See also: Special:Prefixindex/User:Splarka/ and Special:Prefixindex/User:Sannse/ for other handy JS.]].

CSS

Mostly these apply to MediaWiki:Common.css, MediaWiki:Monobook.css and Special:Mypage/Monobook.css (assuming you use the default 'monobook' theme). See also: Wikipedia:Wikipedia:Catalogue_of_CSS_classes.

We've upgraded to 1.9!

The main change the upgrade gave us, in regards to CSS, is a unique (usually) per-page class for the <body> tag. That means, you can restrict a style to any single page with a simple css class definition. For example, this page:

  • <body class="mediawiki ns-2 ltr page-User_Splarka_tricks">

So, lets say I wanted to change the background color of links, just on this page:

  • body.page-User_Splarka_tricks #bodyContent a { background-color: #ff00ff }

Etc.

Limiting TOC to certain depths

In MediaWiki:Common.css:

.toc5 li.toclevel-6 {display:none}
.toc4 li.toclevel-6, .toc4 li.toclevel-5 {display:none}
.toc3 li.toclevel-6, .toc3 li.toclevel-5, .toc3 li.toclevel-4 {display:none}
.toc2 li.toclevel-6, .toc2 li.toclevel-5, .toc2 li.toclevel-4, .toc2 li.toclevel-3 {display:none}
.toc1 li.toclevel-6, .toc1 li.toclevel-5, .toc1 li.toclevel-4, .toc1 li.toclevel-3, .toc1 li.toclevel-2 {display:none}

In Template:TOC1

<div class="toc1">
 __TOC__
 </div>

In Template:TOC2

<div class="toc2">
 __TOC__
 </div>

etc

Un-numbered TOC

In MediaWiki:Common.css:

.utoc .tocnumber { display:none; }
.utoc #toc ul,
.utoc .toc ul {
  line-height: 1.5em;
  list-style-type: square;
  margin: .3em 0 0 1.5em;
  padding: 0;
  list-style-image: url(/skins3/monobook/bullet.gif);
}

And then put a __TOC__ in a <div class="utoc"></div>.

Limiting a DynamicPageList list to one specific letter

Notes:

  • Requires css capable browser or will look funky
  • Does not work well with higher numbers of pages (say ~1000)
  • Lame hack, better to use a custom namespace and Allpages/Prefixindex

In MediaWiki:Common.css:

.alphacat ul {list-style: none; }
.alphacat li a {display: none; }
.alphacat-a li a[title ^="A"] {display: inline }
.alphacat-b li a[title ^="B"] {display: inline }
.alphacat-c li a[title ^="C"] {display: inline }
.alphacat-d li a[title ^="D"] {display: inline }
.alphacat-e li a[title ^="E"] {display: inline }
.alphacat-f li a[title ^="F"] {display: inline }
.alphacat-g li a[title ^="G"] {display: inline }
.alphacat-h li a[title ^="H"] {display: inline }
.alphacat-i li a[title ^="I"] {display: inline }
.alphacat-j li a[title ^="J"] {display: inline }
.alphacat-k li a[title ^="K"] {display: inline }
.alphacat-l li a[title ^="L"] {display: inline }
.alphacat-m li a[title ^="M"] {display: inline }
.alphacat-n li a[title ^="N"] {display: inline }
.alphacat-o li a[title ^="O"] {display: inline }
.alphacat-p li a[title ^="P"] {display: inline }
.alphacat-q li a[title ^="Q"] {display: inline }
.alphacat-r li a[title ^="R"] {display: inline }
.alphacat-s li a[title ^="S"] {display: inline }
.alphacat-t li a[title ^="T"] {display: inline }
.alphacat-u li a[title ^="U"] {display: inline }
.alphacat-v li a[title ^="V"] {display: inline }
.alphacat-w li a[title ^="W"] {display: inline }
.alphacat-x li a[title ^="X"] {display: inline }
.alphacat-y li a[title ^="Y"] {display: inline }
.alphacat-z li a[title ^="Z"] {display: inline }

In a template (which you call via {{sometemplate|a}} to show just 'a')

<div class="alphacat alphacat-{{lc:{{{1|a}}}}}">
 <DynamicPageList>
 category=Some Category
 count=1000
 </DynamicPageList>
 </div>

Style the menus

Done on w:c:scratchpad:MediaWiki:Monobook.css

In MediaWiki:Monobook.css, a base to start fiddling:

#p-wikicities-nav, #p-tb, #p-search, #p-navigation {
   background-color: #fffff6; 
   border:1px solid black;
}
#p-navigation .pBody, #p-search .pBody, #p-tb .pBody, #p-lang .pBody, #p-wikicities-nav .pBody { 
   display: block;
   border: none;
   background-color: transparent;
   padding: 0
}
.portlet h5 {
   font-weight:bold;
   display: block;
   border-bottom: 1px solid #ccccff;
   padding-bottom: .35em;
}
.pBody a { text-decoration: none; }
.pBody ul li:hover { background-color:#ffffcc }
#p-navigation .pBody ul, #p-search .pBody ul, #p-tb .pBody ul, #p-lang .pBody ul, #p-wikicities-nav .pBody ul { 
   list-style-image: none;
   list-style-position: outside;
   list-style-type: circle;
   padding: 0 0 0 1.5em;
   margin: 0;
}
#p-navigation .pBody li, #p-search .pBody li, #p-tb .pBody li, #p-lang .pBody li, #p-wikicities-nav .pBody li { 
   border-left: 1px solid #ffcccc;
   border-bottom: 1px solid #ccccff;
   padding: 0 0 .05em .5em;

less annoying "You have new messages"

In your user/monobook.css :

.usermessage {
   background-color: #FFFFFF;
   border: 1px solid #777777;
   color: Black;
   font-weight: normal;
   margin: .5em 0em .5em 0em;
   padding: 4px;
   vertical-align: middle;
}

Redirects

On Special:Allpages, you can make redirects stand out a lot more. For example (in MediaWiki:Common.css or user/monobook.css):

.allpagesredirect { font-style: italic; }
.allpagesredirect:after { color:grey; content: " (redirect)"}

Makes them italic and appended with the word 'redirect'.

.allpagesredirect a { background: url(/images/5/5c/Allpagesredirect.gif) center left no-repeat; padding-left: 13px; }

Gives each redirect a small image (found here, save and upload to use, public domain (or create your own)) to the side.

Recent Changes tweaks

Hilighting admin/staff

This lets you style the nickname of trusted editors in the recent changes as you wish.

In your user/monobook.css (or in MediaWiki:Common.css with community approval) :

ul.special li a[title="User:Angela"],
ul.special li a[title="User:Sannse"],
ul.special li a[title="User:Splarka"] { font-weight: bold; font-style: italic; color: #ff00ff; }

This example shows Angela, Sannse, and Splarka as bold, magenta, and italic, in recent changes.

table.diff a[title="User:Splarka"], 
ul#pagehistory li a[title="User:Splarka"], 
ul.special li a[title="User:Splarka"] { color: #33dd33; font-weight:bold; }

This example shows Splarka as bold and green, in diffs, page histories, and recent changes.

Finding new users

In MediaWiki:Common.css or user/monobook.css:

ul.special li a[title ^="User talk:"].new { color:#ff00ff;font-weight:bold }

Will show a bright pink Talk link on recent changes, for all users who do not have talk pages.

ul.special li a[title ^="User talk:"].new { color:#ff00ff;font-weight:bold }
ul.special li a[title ="Special:Contributions"] + a[title ^="User talk:"].new { color:#CC2200;font-weight:normal }

Will do the same, but only for logged in users, and not IPs. Note that it does this by resetting IP talk links to normal, so whatever changes done have to be undone.

Float the namespace selector to the right

In user/monobook.css:

div.namespacesettings {
   float: right;
   clear: none;
   position: relative;
   top: -8em;
   width: 175px;
   border: 1px dotted #AAAAAA;
   padding: 4px;
}

Gets it out of the way.

Various minor tweaks

In user/monobook.css:

.newpage { color : #990000; }
.minor { color : #AAAAAA; }
.unpatrolled { color : #ff00ff; }

This changes the N (new page) letter to red, the m (minor edit) letter to grey, and the ! (unpatrolled edit) exclamation mark to bright pink. Lots of things can be done in excess to this, such as images, extra comments, and blinking.


Make some links look like regular links

This is useful if you want to make inline templates with a mixture of internal/interwiki/external links but don't want a clash of link formatting associated with such. In MediaWiki:Common.css:

#bodyContent .stealthexternallink a { background: none; padding: 0; color: #002bb8; }
#bodyContent .stealthexternallink a.new { color: #CC2200 !important; }
#bodyContent .stealthexternallink a:visited { color: #5a3696; }
#bodyContent .stealthexternallink a:active { color: #faa700; }
#bodyContent .stealthexternallink a:hover { text-decoration: underline; }

And then put such links in <span class="stealthexternallink"></span>

Make class="new" inheritable

This allows you to force links to be red, by putting links in a block or inline element in class="new": In MediaWiki:Common.css:

.new a { color:#cc2200; }
.new a:visited { color:#a55858; }

And then: <span class="new">[[Blah]]</span> should always be red.

Different logos per...

Per namespace

You can change the logos in each namespace, via MediaWiki:Monobook.css. For example:

body.ns-110 #p-logo a { background-image: url(/images/6/61/Forum_Logo_Soapboxes.png) !important; }
body.ns-111 #p-logo a { background-image: url(/images/d/db/Forum_talk.png) !important; }

Note that you must determine the image location and namespace number yourself. To determine the image location: upload an image, right click on it, and 'copy image location' (mozilla) or 'properites' (ie). To determine the namespace number, go to a page in that namespace and view page source, the <body> tag will have it as a class, eg user might be <body class="ns-2 ltr"> indicating body.ns-2 is the identifier for that namespace. Hint: Lots of customizations are possible by namespace.

Per pagename

If you look at the page source, you'll see the <body> tag has quite a lot of classes as of MediaWiki: 1.9. For example, this page:

<body  class="mediawiki ns-2 ltr page-User_Splarka_tricks">

If one wanted to change the logo, just of this page, one could put in MediaWiki:Monobook.css

body.page-User_Splarka_tricks #p-logo a { background-image: url(http://somelink) !important; }

This opens up the possibility to make certain pages, such a your main page or certain help pages, quite unique.

Misc user css tweaks

Mostly for user/monobook.css:

Make action tab links change color when visited:

#p-cactions .new a:visited { color: #ba6644; }
#p-cactions li a:visited { color: #492FAF; }

Position the delete confirmation button at the same place on every page (useful for mass deletions in tabs):

#deleteconfirm { position: absolute; top: 130px; left: 150px; }

Remove gap between action tabs (talk/edit, and move/watch (or history/watch)):

li#ca-watch, li#ca-unwatch { margin-right: 1.6em; margin-left: .05em; }
li#ca-talk { margin-right: .4em; }

Show "Templates used on this page" as an inline list instead of long bullet pointed list.

.templatesUsed ul { list-style: none; }
.templatesUsed li { display: inline; padding: 0 0 0.1em 0; margin: 0 0.3em 0 0; }

Make edit pages much smaller (by removing copyright warning and tools) Warning: for advanced users only, could get you banned for ignoring site rules

#editpage-copywarn { display: none !important; }
#editpage-tools { display: none !important; }

Removes block expiry dropdown on Special:Blockip (I always type in a time manually).

#wpBlockExpiry { display: none !important; }

That annoying updated marker!

.updatedmarker {display: none}

Wanna change your edit box font?

textarea {font-family: "Comic Sans MS"; font-size:110%;} 

Printed links Underlined

in user/monobook.css:

@media print {
    a, a.external, a.new, a.stub {
        color: blue ! important;
        text-decoration: underline ! important;
    }
}

Border on LaTeX images

Experimental, requires CSS2.

a img[alt="math"] { border:1px solid green;background-color:white;padding:3px; }

Also (from Lapper):

#bodyContent a[href ^="/extensions/wiki/text/tmp/"] { border:1px solid green;background-color: hite;padding:3px; }

Per-namespace tab buttons

A quick trick to let you customize messages per namespace.

For example, to prefix a namespace-specific word before 'discussion' on every talk page:

body.ns-0 #ca-talk a:before { content: "Article "}
body.ns-1 #ca-talk a:before { content: "Article "}
body.ns-2 #ca-talk a:before { content: "User "}
body.ns-3 #ca-talk a:before { content: "User "}
body.ns-4 #ca-talk a:before { content: "Project "}
body.ns-5 #ca-talk a:before { content: "Project "}
body.ns-6 #ca-talk a:before { content: "Image "}
body.ns-7 #ca-talk a:before { content: "Image "}
body.ns-8 #ca-talk a:before { content: "Message "}
body.ns-9 #ca-talk a:before { content: "Message "}
body.ns-10 #ca-talk a:before { content: "Template "}
body.ns-11 #ca-talk a:before { content: "Template "}
body.ns-12 #ca-talk a:before { content: "Help "}
body.ns-13 #ca-talk a:before { content: "Help "}
body.ns-14 #ca-talk a:before { content: "Category "}
body.ns-15 #ca-talk a:before { content: "Category "}
body.ns-100 #ca-talk a:before { content: "Lodging "}
body.ns-101 #ca-talk a:before { content: "Lodging "}
body.ns-102 #ca-talk a:before { content: "Restaurant "}
body.ns-103 #ca-talk a:before { content: "Restaurant "}
body.ns-110 #ca-talk a:before { content: "Forum "}
body.ns-111 #ca-talk a:before { content: "Forum "}

(CSS2 - won't work on all browsers)

Poor-man's hit counter

Putting this under CSS since it is mostly CSS.

First you go to a hit counter site like http://hitslog.com/ or http://server3.web-stat.com/ and sign up and get an embeddable image (These are by far the easiest to use with mediawiki. The ones that require a <script> tag or raw html are no good). Then in your MediaWiki:Monobook.css stick the image in the footer with something like:

#f-copyrightico { width:190px; text-align: left; background: white url(http://h2.hitslog.com/myspace/#####.png) no-repeat top right}
Hitslog example

It might look like this.

Alternately, you can put it in MediaWiki:Sidebar as an empty link, like:

 * hit counter
 ** http://hitslog.com/|

And then show it with something like:

#p-hit_counter ul, #p-hit_counter li { list-style: none; padding:0; }
#p-hit_counter li#n- a {border:0px solid white; display:block; width:88px; height: 31px; background: white url(http://h2.hitslog.com/myspace/#####.png) no-repeat 0 0}

(note that the ID of the header line in Sidebar must match the #p- ID in the CSS)

Javascript (untested in 1.9 yet)

Note: I haven't tested all the scripts in this section in 1.9 yet. When I do, I'll move them to the next section or remove them (if they are not needed).

Usually for MediaWiki:Monobook.js or Special:Mypage/monobook.js

Trimmed main page

NOTE: As we've upgraded to 1.9, javascript is no longer needed (rev:17119). This section should be moved to the CSS sections above.

To style a specific page, in MediaWiki:Monobook.css (or user css, or MediaWiki:Common.css if it is not unique to the user interface), use the body tag page class. Examples:

body.page-Main_Page #lastmod, #siteSub, #contentSub, h1.firstHeading { display: none !important; }

body.page-Main_Page #p-cactions, #p-personal, #lastmod, #siteSub, #contentSub, h1.firstHeading

body.page-Main_Page #p-logo a { background-image: url(http://upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png) !important; }

Per-Page CSS support

Deprecated due to upgrade.: this is now supported natively in Wikia. View page history for code if you wish to use it elsewhere.


Patrolled edits popups

Deprecated due to upgrade.: this should happen automatically now.

Link generation page

Not highly tested. Known to have problems with non-english content languages (like Polish in MediaWiki: namespace).

This lets you create a template with parameter that generates a multitude of links that, for example, search for that parameter (Similar to Book_sources on Wikimedia, eg: Wikipedia:Wikipedia:Book_sources)

addOnloadHook(linkInsert);
function linkInsert() {
    //parameters
    var linkpage = 'MediaWiki:Links';
    var linkparm = 'link';
    var magic = 'MAGICWORD';

    //aborts
    if(document.title.indexOf(linkpage) != 0) return;
    if(!queryString(linkparm)||(queryString(linkparm)==magic)) return;

    //loop
    var body = document.getElementById('bodyContent')
    alert(body.innerHTML.indexOf(magic));
    while (body.innerHTML.indexOf(magic) != -1) { 
        body.innerHTML = body.innerHTML.replace(magic, queryString(linkparm))
    }
}

function queryString(p) {
  var re = RegExp('[&?]' + p + '=([^&]*)');
  var matches;
  if (matches = re.exec(document.location)) {
    try { 
      return decodeURI(matches[1]);
    } catch (e) {
    }
  }
  return null;
}

To use it, create a template with contents like:

[{{fullurl:MediaWiki:Links|link={{urlencode:{{{1|}}}}}}} search]

And then if your template is called, eg {{foo|pink floyd the wall}} it will generate a link to /index.php?title=MediaWiki:Links&link=pink+floyd+the+wall ... and all occurences of MAGICWORD on MediaWiki:Links will be replaced by pink+floyd+the+wall, eg:

http://www.google.com/search?q=MAGICWORD

becomes

http://www.google.com/search?q=pink+floyd+the+wall


Re-link 'Talk:' Categories

Often, to keep maintenace/project category clutter on large wikis to a minimum, the talk page is categorized instead.

Someone requested am on-demand script to change links on category pages from "Talk:Pagename" to "Pagename", and "Namespace_talk:Pagename" to "Namespace:Pagename".

function catSwapButton() {
  if(document.title.indexOf('Category:' == 0)) {
    var tabs = document.getElementById('p-cactions').getElementsByTagName('ul')[0];
    addlilink(tabs, 'javascript:catSwap()', 'De-talkify', 'ca-catswap');
  }
}
addOnloadHook(catSwapButton)

function catSwap() {
  var cat = document.getElementById('bodyContent');
  cat.innerHTML = cat.innerHTML.replace(/Talk\:/g,'').replace(/[_\s]talk\:/g,':');
}

function addlilink(tabs, url, name, id) {
    var na = document.createElement('a');
    na.href = url;
    na.id = id;
    na.appendChild(document.createTextNode(name));
    var li = document.createElement('li');
    li.appendChild(na);
    tabs.appendChild(li);
    return li;
}


Watchlist styler

If you want to hilight certain aspects of your watchlist, you can do so thusly.

var wstyle = [];
wstyle[wstyle.length] = {
  'match': 'Hydrogen',
  'color': '#ffff00',
  'bgcol': '#00ff00'}
wstyle[wstyle.length] = {
  'match': 'MediaWiki',
  'color': '#ff0000'}
wstyle[wstyle.length] = {
  'match': 'Talk:',
  'bgcol': '#000000'}

function watchlistStyle() {
  if(document.title.indexOf('My watchlist -') != 0) return;
  var links = document.getElementById('bodyContent').getElementsByTagName('a');
  for(var i=0;i < links.length;i++) {
    for(var k=0;k < wstyle.length;k++) {
      if(links[i].innerHTML.indexOf(wstyle[k].match)!= -1) {
        if(wstyle[k].color) links[i].style.color = wstyle[k].color
        if(wstyle[k].bgcol) links[i].style.backgroundColor = wstyle[k].bgcol
      }
    }
  }
}
addOnloadHook(watchlistStyle)

Note that you can expand this to work on other content pages, or all content pages, by modifying the return conditions. For example, if you'd like this to work on recent changes too:

  if((document.title.indexOf('My watchlist -') != 0)&&(document.title.indexOf('Recent changes - ') != 0)) return;

Also, this can be done in CSS (similar to User:Splarka/tricks#Hilighting_admin.2Fstaff).

body.ns--1 #bodyContent a[title*="Template"] {color: red; background-color:blue;}

This will be more effective per-page (such as just watchlist or just recent changes) after then 1.9 upgrade

Javascript 1.9+

Stuff here has been tested on and works under 1.9. Will migrate/simplify stuff and move it here this week.

Note that with MediaWiki:Common.js functionality: do not make the mistake of moving all your javscript there directly. Much of the Javascript used is specifically for Monobook.

Changeable preloads

Here is a quick and dirty way to add a dropdown selection menu:

function preloadMenu() {
  if(document.createbox.preload) {
    var cb = document.createbox;
    if(cb.preload.value == 'Template:Default') {
      var sel = 'Preloads: <select name="presel" onChange="document.createbox.preload.value = document.createbox.presel.value">\n'
      sel += '<option value="">Default: '+ document.createbox.preload.value +'</option>\n';
      sel += '<option value="Template:Foo"> Foo page</option>\n';
      sel += '<option value="Template:Bar"> Bar page</option>\n';
      sel += '<option value="Template:Baz"> Baz page</option>\n';
      sel += '</select>\n';
      cb.innerHTML = sel + cb.innerHTML;
    }
  }
}
addOnloadHook(preloadMenu);

If the above script finds an input box with a preload=, and if it finds the default template matching (as a way to limit its operation), it will then create a dropdown list that you specify, and allow you to choose a different preload. For example, the following inputbox would trigger the above script:

<inputbox>
 type=create
 break=no
 preload=Template:Default
 </inputbox>

There are 3 demo options listed above (you can add or remove as needed).

sel += '<option value="Template:Foo"> Foo page</option>\n';

The editable parts:

  • value="" specifies the exact name of the template (spaces or underscores allowed).
  • The text between the >< specifies the text seen in the dropdown box.

You can add more cases, just duplicate the inner if() and simply change the conditions.

Add checkuser link to contribs

This adds a link to Special:CheckUser, w:Special:LookupContribs, and w:Special:MultiLookup (if you're checking an IP) on user contrib pages in the contentSub heading.

Before: For 127.0.0.1 (Talk | block | Block log | Logs )
After: For 127.0.0.1 (Talk | block | Block log | Logs | Checkuser | LookupContribs | MultiLookup )

Updated to check rights first, and do it with almost proper DOM handling. Hint: this is pretty easy to expand with some copy/paste and small tweaks.

function contribtools() {
  if(wgPageName!="Special:Contributions") return
  var ug = wgUserGroups.join(' ');
  var cs = document.getElementById('contentSub');
  // poorman contribs type finder. -1 = existing user
  var ctype = cs.getElementsByTagName('a')[0].href.indexOf('User_talk');

  if(ug.indexOf('staff') + ug.indexOf('checkuser') > -2) {
    if(ctype==-1) {
      var culink = '/wiki/Special:CheckUser?subuser=OK&user=';
    } else {
      var culink = '/wiki/Special:CheckUser?subipusers=OK&ip=';
    }
    var cu1 = document.createTextNode(' | ');
    var cu2 = document.createElement('a');
    cu2.href = culink + document.forms[0].target.value;
    cu2.setAttribute('title', cu2.href);
    cu2.appendChild(document.createTextNode('Checkuser'));
    cs.insertBefore(cu1,cs.childNodes[cs.childNodes.length-1]);
    cs.insertBefore(cu2,cs.childNodes[cs.childNodes.length-1]);
  }

  //may need tweaking for you personally, like if(1==1)
  if(ug.indexOf('staff') + ug.indexOf('lookupcontribs') > -2) {
    var lulink = 'http://www.wikia.com/wiki/Special:Lookupcontribs?mode=normal&view=full&target=';
    var lu1 = document.createTextNode(' | ');
    var lu2 = document.createElement('a');
    lu2.href = lulink + document.forms[0].target.value.replace(/_/g,'+');
    lu2.setAttribute('title', lu2.href);
    lu2.appendChild(document.createTextNode('LookupContribs'));
    cs.insertBefore(lu1,cs.childNodes[cs.childNodes.length-1]);
    cs.insertBefore(lu2,cs.childNodes[cs.childNodes.length-1]);
  }

  if((ug.indexOf('staff') > -1)&&(ctype!=-1)) {
    var mulink = 'http://www.wikia.com/wiki/Special:MultiLookup?wpIP=';
    var mu1 = document.createTextNode(' | ');
    var mu2 = document.createElement('a');
    mu2.href = mulink + document.forms[0].target.value;
    mu2.setAttribute('title', mu2.href);
    mu2.appendChild(document.createTextNode('MultiLookup'));
    cs.insertBefore(mu1,cs.childNodes[cs.childNodes.length-1]);
    cs.insertBefore(mu2,cs.childNodes[cs.childNodes.length-1]);
  }
}
addOnloadHook(contribtools);

Default version addable from:

document.write('<script type="text/javascript" src="' 
             + 'http://www.wikia.com/index.php?title=User:Splarka/contribtools.js' 
             + '&action=raw&ctype=text/javascript&dontcountme=s"></script>');

List of all Wikia

MediaWiki:Wikialist.js

This is just a list of all the Wikia on Wikia. It isn't current (as it has to be manually created from the database list), and it excludes all the non-wikia domains (uncyclopedia.org/memoryalpha.org). It would be nice if someday it was referenceable from a url like www.wikia.com/stats/wikialist.js (hint hint).

As it is, you can reference it via:

<script type="text/javascript" src="http://wikia.com/index.php?title=MediaWiki:Wikialist.js&action=raw&ctype=text/javascript&dontcountme=s"></script>

And then use it for something in JS that needs a list of lots of wikia. Whatever.

Customize the search box

You can add this to your user/monobook.js to change the search box.

This changes the go button to view, and the search button to edit (the value and label should stay at these words), and the name of both to action. The consequece of this is: clicking edit takes you to /w/index.php?title=WHATEVER&action=edit, and clicking go *should* take you to /w/index.php?title=WHATEVER&action=view ... however, it takes me (at least) directly to /wiki/WHATEVER, even if the page does not exist (and not to the edit page). Note that this still does not let you manually type &action=edit but it does let you just click 'edit' instead.

function customsearch() {
  if(document.getElementById('searchform')) {
    document.getElementById('searchform').action = "/index.php";
    document.getElementById('searchInput').name = "title";
    document.getElementById('searchGoButton').name = "action";
    document.getElementById('searchGoButton').value = "view";
    document.getElementById('mw-searchButton').name = "action";
    document.getElementById('mw-searchButton').value = "edit";
  }
}
addOnloadHook(customsearch);


This sets the focus on a page load, to the search box:

addOnloadHook(function() {document.getElementById('searchInput')..focus(); return false;});

Change the favicon

On Wikia you can upload a custom favicon per wiki, but if you personally want to put a notably different favicon on each wiki you edit, you can add to your user/monobook.js:

var fav = document.createElement('link');
fav.setAttribute('rel','shortcut icon');
fav.setAttribute('href','link to icon');
document.getElementsByTagName('head')[0].appendChild(fav);

Where link to icon is the full url to a 16x16 icon.

You can also use the wgPageName variable to give specific pages specific favicons. Evil. --Splarka (talk) 06:35, 1 May 2007 (UTC)

Extra search box

function whoisip() {
    if(!document.getElementById) return;
    var searchForm = document.getElementById("searchform");
    var whoisForm=document.createElement('form');
    whoisForm.action = 'http://www.dnsstuff.com/tools/whois.ch';
    whoisForm.method - 'GET';
    whoisForm.innerHTML = '<input accesskey="1" TYPE=text NAME=ip SIZE=16 class="std"><input TYPE=submit VALUE="WHOIS" class="send-btn">';
    searchForm.appendChild(whoisForm);
};
addOnloadHook(whoisip);

Search link reassign

Originally from Wookieepedia, but this version is updated for 1.9. This should cause no errors in Common.js, but the image only ever loads in the Monobook skin, so only needs to be added to Monobook.js. This reassigns the Image:Search_logo.png link on the side to point to Special:Search. If the div or anchor tags do not exist, it does nothing.

function searchLink() {
  if ((document.getElementById('searchform'))&&(document.getElementById('searchform').getElementsByTagName('a').length != 0)) {
      document.getElementById('searchform').getElementsByTagName('a')[0].href = wgArticlePath.replace(/\$1/,'Special:Search');
  }
}
addOnloadHook(searchLink);

Supercustomize edit buttons

Now that we have support for custom edit buttons, it is easy to add buttons to the edit tools, but say you want to rearrange the existing ones? Pretty easy, just disable the default ones, and re-add them in any order you want (you will lose translations, so be warned).

For example, Say you want to put a redirect button before the other buttons:

function addButton() {
  return;
}

if (mwCustomEditButtons) {
  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "http://images.wikia.com/central/images/c/c8/Button_redirect.png",
    "speedTip": "Redirect",
    "tagOpen": "#REDIRECT [[",
    "tagClose": "]]",
    "sampleText": "Insert text"};

  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "/skins/common/images/button_bold.png",
    "speedTip": "Bold text",
    "tagOpen": "\'\'\'",
    "tagClose": "\'\'\'",
    "sampleText": "Bold text"};

  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "/skins/common/images/button_italic.png",
    "speedTip": "Italic text",
    "tagOpen": "\'\'",
    "tagClose": "\'\'",
    "sampleText": "Italic text"};

  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "/skins/common/images/button_link.png",
    "speedTip": "Internal link",
    "tagOpen": "[[",
    "tagClose": "]]",
    "sampleText": "Link title"};

  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "/skins/common/images/button_extlink.png",
    "speedTip": "External link (remember http:// prefix)",
    "tagOpen": "[",
    "tagClose": "]",
    "sampleText": "http://www.example.com link title"};

  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "/skins/common/images/button_headline.png",
    "speedTip": "Level 2 headline",
    "tagOpen": "\n== ",
    "tagClose": " ==\n",
    "sampleText": "Headline text"};

  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "/skins/common/images/button_image.png",
    "speedTip": "Embedded image",
    "tagOpen": "[[Image:",
    "tagClose": "]]",
    "sampleText": "Example.jpg"};

  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "/skins/common/images/button_media.png",
    "speedTip": "Media file link",
    "tagOpen": "[[Media:",
    "tagClose": "]]",
    "sampleText": "Example.ogg"};

  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "/skins/common/images/button_math.png",
    "speedTip": "Mathematical formula (LaTeX)",
    "tagOpen": "<math>",
    "tagClose": "<\/math>",
    "sampleText": "Insert formula here"};

  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "/skins/common/images/button_nowiki.png",
    "speedTip": "Ignore wiki formatting",
    "tagOpen": "<nowiki>",
    "tagClose": "<\/nowiki>",
    "sampleText": "Insert non-formatted text here"};

  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "/skins/common/images/button_sig.png",
    "speedTip": "Your signature with timestamp",
    "tagOpen": "--~~~~",
    "tagClose": "",
    "sampleText": ""};

  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "/skins/common/images/button_hr.png",
    "speedTip": "Horizontal line (use sparingly)",
    "tagOpen": "\n----\n",
    "tagClose": "",
    "sampleText": ""};
}

Note: There is no need to upload the images for the default ones (just use the local /skins/ url), and if the custom buttons have possible use across wikia, please upload them to the Central Wikia (see Help:Custom edit buttons. --Splarka (talk) 09:13, 28 March 2007 (UTC)

Semi-automated deletions

Note: This method has been used to delete thousands of images on commons.wikimedia, and can be very effective for those with nothing but Firefox to semo-automate a process, or those having problems getting the PyWikipediaBot to work while logged in as a sysop.

This is actually, basically, one line of code (along with a query string checker, like volte's below. If the query string contains &submitdelete=true, the delete button is submitted by the javascript.

function checkdelete() {
    if(queryString("submitdelete")=="true") document.getElementById('deleteconfirm').wpConfirmB.click()
}
addOnloadHook(checkdelete);

function queryString(p) {
  var re = RegExp('[&?]' + p + '=([^&]*)');
  var matches;
  if (matches = re.exec(document.location)) {
    try { 
      return decodeURI(matches[1]);
    } catch (e) {
    }
  }
  return null;
}

The trick, then, is simply generating a list of files to delete as URLs. For example, to delete this page:

Would become:
You can also add a default reason, using MediaWiki query-input syntax:

Having generated several dozen or thousand links (with a search/replace or other method of your choice), you can then put them on a temporary wiki page, select about 50 at a time, right click, and 'open in new tabs' (in Firefox). And then go through and close all the tabs as soon as they finish.

Hint: This can be used on some other forms with some modification, like Special:Block.

Hint: The "Open links in new tabs" functionality may need a FireFox plugin, such as linky.

Hint: The above javascript code is user-specific. If the new tabs stay at a confirmation page rather than automatically deleting the page, make sure you're logged onto the same account that has the javascript in its user-specific monobook.js.

Batch upload

A batch file upload is often requested, but usually requires a greasemonkey-type plugin or specially written Python bot. There is a way to highly automate the process in vanilla Mozilla/Firefox, but it requires temporarily relaxing security settings (as explained in the script comments). There are three parts to using it (note that, except for testing, you should really do step 3, the URL generation, first, so that you don't leave your browser insecure longer than needed):

The script

This goes into your user/monobook.js on the Wiki you need to upload to. It can stay in your script indefinitely as it is rather passive unless triggered:

// ==================================================
// Begin batch upload script for Mozilla/FF - Splarka
// ==================================================
/* 
This is a highly evil and somewhat esoteric script 
that allows fast and multiple batch uploading of 
files to a wiki.

-------------------DISCLAIMER------------------------
It requires TEMPORARILY relaxing default security 
settings in your browser. Specifically: Javascript
should *not* be able to arbitrarily upload files of
a given name. But this is exactly what this script
requires to operate. While relaxing your security,
you should not visit any other sites except the 
wiki in question.

To enable:
* Go to the URL about:config in firefox
* find/create and set to 'true': 
** signed.applets.codebase_principal_support

To disable: 
* Go to the URL about:config in firefox
* find/create and set to 'false': 
** signed.applets.codebase_principal_support

For more info/troubleshooting see:
http://www.wikia.com/wiki/User:Splarka/tricks#Batch_upload
*/

function uploadbatch() {
  if((document.title.indexOf('Upload file - ') == 0)&&(queryString('wpUploadFile'))) {
    try { netscape.security.PrivilegeManager.enablePrivilege('UniversalFileRead'); }
    catch($err) {
      var $privileges = false;
      alert('Error: Unable to perform file upload. App was denied elevated privileges to do so.');
      return;
    }
    if((queryString('wpUploadFile'))&&(document.getElementById('wpUploadFile').value == '')) document.getElementById('wpUploadFile').value = decodeURIComponent(queryString('wpUploadFile')).replace(/\+/g,' ')
    if((queryString('wpDestFile'))&&(document.getElementById('wpDestFile').value == '')) document.getElementById('wpDestFile').value = decodeURIComponent(queryString('wpDestFile')).replace(/\+/g,' ')
    if((queryString('wpUploadDescription'))&&(document.getElementById('wpUploadDescription').value == '')) document.getElementById('wpUploadDescription').value = decodeURIComponent(queryString('wpUploadDescription')).replace(/\+/g,' ')
    if(queryString('wpUpload') == 'submit') document.forms[0].wpUpload.click()
  }
}
addOnloadHook(uploadbatch);

function queryString(p) {
  var re = RegExp('[&?]' + p + '=([^&]*)');
  var matches;
  if (matches = re.exec(document.location)) {
    try { 
      return decodeURI(matches[1]);
    } catch (e) {
    }
  }
  return null;
}

// ==================================================
// End batch upload script for Mozilla/FF - Splarka
// ==================================================

The security

Enabling this script is somewhat of a pain. There are several ways to do it and not all of them work. You will get a warning message the first time (usually you can select a default answer).

As explained in the script, to enable it in Firefox/Mozilla, go to about:config

  • To enable:
"signed.applets.codebase_principal_support" to "true"
  • To disable:
"signed.applets.codebase_principal_support" to "false"

Alternately, you can add these to the browser's prefs.js (usually in a subfolder of "documents and settings\user\application data") directly (comment out to disable):

user_pref("signed.applets.codebase_principal_support", true);

Or to the browser's default prefs definition defaults\pref\firefox.js (comment out to disable):

pref("signed.applets.codebase_principal_support", true);

Note, if the above fails, you may have luck by adding (temporarily) this to your prefs.js:

user_pref("capability.principal.codebase.p0.granted", "UniversalFileRead");

The URL generation and usage

Now, once you have this infrastructure in place, what do you do with it?

The easiest way, is to generate a set of URLs which you can then list on a temporary wikipage and batch-upload by hilighting large groups and using the "open links in new tabs" feature of Firefox. Then, after they've loaded, all you have to do is close the tabs (if there are no warning messages).

The javascript takes 4 URL parameters which must be escaped/encoded into URL-speak (hex values for nonalphanumeric characters, %20 = space, %A0 = linefeed, etc) :

  • wpUploadFile (string, required): determines the local path of your file to upload. Like &wpUploadFile=c:%5Cwiki%5Cimage%201.gif (encoded version of "c:\wiki\image 1.gif")
  • wpDestFile (string, optional): file name, if different.
  • wpUploadDescription (string, optional): information box for the upload. Put license info here. For example: wpUploadDescription=Some%20file%0A%0A%3D%3DLicense%3D%3D%0A%7B%7BGFDL%7D%7D
  • wpUpload (string, optional): if set to "submit" the form will submit automatically, meaning you only have to open the URL in a new tab, and close it when done.

So for example:

/wiki/Special:Upload?wpUploadFile=c:%5Cwiki%5Cimage%201.gif&wpUploadDescription=Some%20file%0A%0A%3D%3DLicense%3D%3D%0A%7B%7BGFDL%7D%7D&wpUpload=submit
Note: Mostly working tool to automate this: Batch upload generator.

&bot=1

Add a bot=1 parameter to user contribs pages, to hide the rollbacks from Special:Recentchanges (if spammy).

function hiderollback() {
  if(document.title.indexOf('User contributions')==-1) return;
  var tabs = document.getElementById('p-cactions').getElementsByTagName('ul')[0];
  var botlink = document.location.href;
  if(botlink.indexOf('?')==-1) {
    botlink += '?bot=1';
  } else {
    botlink += '&bot=1';
  }
  addlilink(tabs, botlink, '&bot=1', 'ca-bot');
}
addOnloadHook(hiderollback)

function addlilink(tabs, url, name, id) {
    var na = document.createElement('a');
    na.href = url;
    na.id = id;
    na.appendChild(document.createTextNode(name));
    var li = document.createElement('li');
    li.appendChild(na);
    tabs.appendChild(li);
    return li;
}

Hide namespaces in categories

A quick script to hide namespace prefixes in category lists. Just add <div id="catnoprefix" style="display:none;"></div> to the category description page to activate it.

function catprefix() {
  if(!document.getElementById('catnoprefix')) return
  var anchors = document.getElementById('mw-pages').getElementsByTagName('a');
  for(var i=0;i < anchors.length;i++) {
    if(anchors[i].firstChild.nodeValue.indexOf(':') != -1) {
      anchors[i].firstChild.nodeValue = anchors[i].firstChild.nodeValue.substring(anchors[i].firstChild.nodeValue.indexOf(':')+1);
    }
  }
}
addOnloadHook(catprefix)

Here is another version:

<nowiki>
addOnloadHook(function() {if(document.getElementById('catnoprefix')) document.getElementById('mw-pages').innerHTML = document.getElementById('mw-pages').innerHTML.replace(/\<a href\=([^\>]*\>)[^\:|\<]*\:/g,'<a href=$1');});

Countdown timers

Note: This is a completely revamped version, for the old version, click here.
// **************************************************
// Experimental javascript countdown timer (Splarka)
// Version 0.0.3
// **************************************************
//
// Usage example:
//  <span class="countdown" style="display:none;">
//  Only <span class="countdowndate">January 01 2007 00:00:00 PST</span> until New years.
//  </span>
//  <span class="nocountdown">Javascript disabled.</span>

function updatetimer(i) {
  var now = new Date();
  var then = timers[i].eventdate;
  var diff = count=Math.floor((then.getTime()-now.getTime())/1000);

  // catch bad date strings
  if(isNaN(diff)) { 
    timers[i].firstChild.nodeValue = '** ' + timers[i].eventdate + ' **' ;
    return;
  }

  // determine plus/minus
  if(diff<0) {
    diff = -diff;
    var tpm = 'T plus ';
  } else {
    var tpm = 'T minus ';
  }

  // calcuate the diff
  var left = (diff%60) + ' seconds';
    diff=Math.floor(diff/60);
  if(diff > 0) left = (diff%60) + ' minutes ' + left;
    diff=Math.floor(diff/60);
  if(diff > 0) left = (diff%24) + ' hours ' + left;
    diff=Math.floor(diff/24);
  if(diff > 0) left = diff + ' days ' + left
  timers[i].firstChild.nodeValue = tpm + left;

  // a setInterval() is more efficient, but calling setTimeout()
  // makes errors break the script rather than infinitely recurse
  timeouts[i] = setTimeout('updatetimer(' + i + ')',1000);
}

function checktimers() {
  //hide 'nocountdown' and show 'countdown'
  var nocountdowns = getElementsByClassName(document, 'span', 'nocountdown');
  for(var i in nocountdowns) nocountdowns[i].style.display = 'none'
  var countdowns = getElementsByClassName(document, 'span', 'countdown');
  for(var i in countdowns) countdowns[i].style.display = 'inline'

  //set up global objects timers and timeouts.
  timers = getElementsByClassName(document, 'span', 'countdowndate');  //global
  timeouts = new Array(); // generic holder for the timeouts, global
  if(timers.length == 0) return;
  for(var i in timers) {
    timers[i].eventdate = new Date(timers[i].firstChild.nodeValue);
    updatetimer(i);  //start it up
  }
}
addOnloadHook(checktimers);

// **************************************************
//  - end -  Experimental javascript countdown timer
// **************************************************

Changes since 0.0.2:

  • Uses 3 spans instead of 2 (one is optional): An outer wrapping span class="countdown", a child span class="countdowndate" containing the literal date, and an outer span class="nocountdown" for default javascript-free message (optional).
  • Did away with "until" and "ago since", now uses "T minus" and "T plus".

The new syntax is:

<span class="countdown" style="display:none;">
countdown text <span class="countdowndate">date</span> countdown text
</span>
<span class="nocountdown">no javascript text</span>

For example:

<span class="countdown" style="display:none;">
New years is in <span class="countdowndate">January 01 2007 00:00:00 PST</span>.
</span>
<span class="nocountdown">Counter unavailable.</span>

Could generate:

New years is in T minus 251 days 7 hours 19 minutes 51 seconds.
Not highly tested yet. Feedback welcome.

Whatlinkshere delete link

Quick and dirty script to add 'delete' link to Unlinked pages, if you are on Special:Whatlinkshere (requested).

function whatlinksheredel() {
  if(wgPageName!='Special:Whatlinkshere') return
  if(!document.getElementById('nolinkshere')) return
  if(document.getElementById('nolinkshere').childNodes[1].nodeType!=1) return
  var url=document.getElementById('nolinkshere').childNodes[1].firstChild.href;
  if(url.indexOf('action=edit')!=-1) return;
  var link = document.createElement('a');
  link.setAttribute('id','nolinkdel');
  link.setAttribute('href', url + '&action=delete');
  link.setAttribute('style', 'font-size:90%;padding-left:20px');
  link.appendChild(document.createTextNode('delete'));
  document.getElementById('nolinkshere').appendChild(link);
}
addOnloadHook(whatlinksheredel);

Block reasons dropdown

This is actually added in a very recent modification to MediaWiki, but was requested by unmentioned impatient parties.

This script grabs an invisible div you define in MediaWiki:Blockiptext, for example:

<div id="ipbreason-dropdown-js" style="display:none;"><nowiki>
* Common block reasons
** Inserting false information
** Removing content from pages
** Spamming links to external sites
** Inserting nonsense/gibberish into pages
** Intimidating behaviour/harassment
** Abusing multiple accounts
** Vandalism
* Foo
** Bar
</nowiki></div>

The script itself goes into your MediaWiki:Common.js or user.js

// ==================================================
// Begin default dropdown block reasons - Splarka
// ==================================================
function blockreasons() {
  if(!document.getElementById('ipbreason-dropdown-js')) return;
  var reasondiv = document.getElementById('ipbreason-dropdown-js');
  var reasons = document.getElementById('ipbreason-dropdown-js').firstChild.nodeValue.split('\n');

  var selsel = document.createElement('select');
  selsel.setAttribute('onchange','blockreasonchange();');
  selsel.setAttribute('id','blockreasonsel');
  var firstop = document.createElement('option');  
  firstop.appendChild(document.createTextNode('Predefined block reasons'));
  selsel.appendChild(firstop);

  var groupop = new Array(); var gpn = 0;
  var op = new Array(); var opn = 0;
   for(var i=0;i<reasons.length;i++) {
    if(reasons[i].substring(0,1)=='*') {
    if(reasons[i].substring(0,2)=='**') {
      op[opn] = document.createElement('option');
      op[opn].setAttribute('value',reasons[i].substring(2));
      op[opn].appendChild(document.createTextNode(reasons[i].substring(2)));
      groupop[gpn].appendChild(op[opn]);
      opn++;
    } else {
      if(groupop[gpn]) selsel.appendChild(groupop[gpn])
      gpn++;
      groupop[gpn] = document.createElement('optgroup');
      groupop[gpn].setAttribute('label',reasons[i].substring(1));
    }
    }
  }
  selsel.appendChild(groupop[gpn]);

  var reasonparent = document.getElementById('blockip').wpBlockReason.parentNode;
  reasonparent.appendChild(document.createElement('br'));
  reasonparent.appendChild(selsel);
}
if(wgPageName=='Special:Blockip') addOnloadHook(blockreasons);

function blockreasonchange() {
  var selsel = document.getElementById('blockreasonsel');
  var reasonbox = document.getElementById('blockip').wpBlockReason;
  if(selsel.selectedIndex == 0) return
  reasonbox.value = selsel.options[selsel.selectedIndex].value;
}
// ==================================================
// End default dropdown block reasons 
// ==================================================

(To add)

Javascript 1.10+

Here are some scripts I used or made on Wikipedia. Note that they either require 1.10 features (either due to laziness (some can be rewritten easily) or do to advanced functions or elements) or simply don't have much use on Wikia.

Note to self:

var isIE = navigator.appName.indexOf("Microsoft") != -1; //IE checker

Modify a page list on a category

Adds a button to make talk page links on a category temporarly go to the subject page (bit outdated, should rewrite without innerHTML).

function catSwapButton() {
  if(document.title.indexOf('Category:' == 0)) {
    addPortletLink('p-cactions','javascript:catSwap();','De-Talkify','ca-catswap','change category links from talk pages to article pages');
  }
}
addOnloadHook(catSwapButton)

function catSwap() {
  var cat = document.getElementById('mw-pages');
  cat.innerHTML = cat.innerHTML.replace(/Talk\:/g,'').replace(/[_\s]talk\:/g,':');
}

Adds a button to make all page links on a category link to the delete pages (with optiona

function catDelButton() {
  if(wgCanonicalNamespace == 'Category') {
    addPortletLink('p-cactions','javascript:catDel();','Delete links','ca-catdelete','change all links to delete links');
  }
}
addOnloadHook(catDelButton)

function catDel() {
  var links = document.getElementById('mw-pages').getElementsByTagName('a');
  reason = prompt('Generic reason? (escape for mediawiki default)','');
  if(reason!=null) reason = '&wpReason=' + encodeURIComponent(reason)
  for(var i=0;i < links.length;i++) {
    links[i].href += '?action=delete' + reason;
    links[i].firstChild.nodeValue = 'delete ' + links[i].firstChild.nodeValue;
  }
  document.getElementById('ca-catdelete').style.display = 'none';
}
Hint: many other possibilities are... possible

Add "save" button to actions

Save action button super delux transform morph go!

addOnloadHook(addsaveaction);
function addsaveaction() {
 if(document.title.indexOf('Editing ') == 0) addPortletLink('p-cactions','javascript:document.getElementById("wpSave").click();','save','Save');
}

Make personal 'talk' link blink for new messages

Not much use on Wikia with shared new messages. Possibly will make a popdown list or something (as of this writing, shared new messages are broken, though).

function checkMsgs() {
  var divs = document.getElementById('bodyContent').getElementsByTagName('div');
  if(divs.length <= 2) return;
  for(var i=0;i<divs.length;i++) {
    if(divs[i].className == 'usermessage') {
      divs[i].style.display = 'none';
      var talk = document.getElementById('pt-mytalk').firstChild;
      talk.style.color='#ffff00';
      talk.style.textDecoration='blink';
      talk.style.background='#ffff00 url(http://upload.wikimedia.org/wikipedia/commons/9/96/New_%28animated%29.gif) no-repeat 0 0';
      talk.style.paddingLeft='32px';
    }
  }
}
addOnloadHook(checkMsgs)

Simple top/bottom edit page insertion tabs

Unlike the custom edit buttons, these are for insertion at the top or the bottom of the current edit window (full page or simple section). I've gotten enough requests for this that it is worthwhile to simply list them here (though I know many others have done it, although differently).

Note: You must wrap this code in (/* <nowiki> */) on the .js file if it contains valid template or signature characters
if(document.title.indexOf('Editing ') == 0) addOnloadHook(addEditTools)
function addEditTools() {
  // usage: addPortletLink(portlet, href, text, [id], [tooltip], [accesskey], [nextnode])
  addPortletLink('p-cactions','javascript:addEditTop("{{delete}}");','{{delete}}','ca-templatedelete');
  addPortletLink('p-cactions','javascript:addEditBottom("~~~~");','signature','ca-signature');
}
function addEditTop(stuff) {
  if(!document.getElementById('wpTextbox1')) return
  var text = document.getElementById('wpTextbox1');
  if(text.value.replace(/ /g,'')=='') {
    text.value += stuff;
  } else {
    text.value = stuff + '\n' + text.value;
  }
}
function addEditBottom(stuff) {
  if(!document.getElementById('wpTextbox1')) return
  var text = document.getElementById('wpTextbox1');
  if(text.value.replace(/ /g,'')=='') {
    text.value += stuff;
  } else {
    text.value += '\n' + stuff ;
  }
}

One-click top/bottom edit page insertion tabs

These work on almost any action (edit, view, history, diff, oldid). Be very careful when using. These also are one-click, they save immediately!

// ================================================================================
// START Automated tagging script system
// ================================================================================
// Note: Advanced and a bit spooky.

if(wgNamespaceNumber != -1) addOnloadHook(addTaggingButtons)
function addTaggingButtons() {
  //in 1.11 you can use (wgAction == 'edit')
  if(document.title.indexOf('Editing ') == 0) {   
    var iTop = 'javascript:insertTop';
    var iBottom = 'javascript:insertBottom';
  } else {
    var iTop = 'javascript:insertGoTop';
    var iBottom = 'javascript:insertGoBottom';
  }

  // addPortletLink( portlet , JS link , button text, element id );
  // Add new buttons here
  addPortletLink('p-cactions',iTop + '("{{delete}}");','{{delete}} top','ca-templatedelete');
  addPortletLink('p-cactions',iBottom + '("That is my story and I am sticking to it ~~~~");','that is my story','ca-story');
}

function insertTop(stuff) {
  if(!document.getElementById('wpTextbox1')) return
  var text = document.getElementById('wpTextbox1');
  if(text.value.replace(/ /g,'')=='') {
    text.value += stuff;
  } else {
    text.value = stuff + '\n' + text.value;
  }
  document.getElementById('wpSummary').value += ' * semiautomated tagging with: ' + stuff;
  document.getElementById('wpSave').click();
}

function insertBottom(stuff) {
  if(!document.getElementById('wpTextbox1')) return
  var text = document.getElementById('wpTextbox1');
  if(text.value.replace(/ /g,'')=='') {
    text.value += stuff;
  } else {
    text.value += '\n' + stuff ;
  }
  document.getElementById('wpSummary').value += ' * semiautomated tagging with: ' + stuff;
  document.getElementById('wpSave').click();
}

function insertGoTop(stuff) {
  var url = document.getElementById('ca-edit').firstChild.href;
  document.location.href = url + '&insert=true&inserttop=' + encodeURIComponent(stuff);
}

function insertGoBottom(stuff) {
  var url = document.getElementById('ca-edit').firstChild.href;
  document.location.href = url + '&insert=true&insertbottom=' + encodeURIComponent(stuff);
}

function processInsert() {
  if(queryString('insertbottom')) {
      insertBottom(queryString('insertbottom'));
  }
  if(queryString('inserttop')) {
    insertTop(queryString('inserttop'));
  }
}
if(queryString('insert')=='true') addOnloadHook(processInsert)

function queryString(p) {
  var re = RegExp('[&?]' + p + '=([^&]*)');
  var matches;
  if (matches = re.exec(document.location)) {
    try { 
      return decodeURI(matches[1]);
    } catch (e) {
    }
  }
  return null;
}

// ================================================================================
// END Automated tagging script system
// ================================================================================

One-click delete buttons

In the same style as the previous section's tagging stuff.

// ================================================================================
// START Automated deletion button script system
// ================================================================================
// Adds customizable one-click deletion buttons to any deletable page.
addOnloadHook(checkdelete);
function checkdelete() {
    if(queryString("submitdelete")=="true") document.getElementById('deleteconfirm').wpConfirmB.click()
}

if(wgNamespaceNumber != -1) addOnloadHook(addDeleteButtons)
function addDeleteButtons() {
  if(!document.getElementById('ca-delete')) return
  var url=document.getElementById('ca-delete').firstChild.href
  //examples:
  addPortletLink('p-cactions', url + '&submitdelete=true&wpReason=' + encodeURIComponent('This is spam') ,'delete spam','ca-delete1');
  addPortletLink('p-cactions', url + '&submitdelete=true&wpReason=' + encodeURIComponent('This is an unused redirect'),'delete redirect','ca-delete2');
}

function queryString(p) {
  var re = RegExp('[&?]' + p + '=([^&]*)');
  var matches;
  if (matches = re.exec(document.location)) {
    try { 
      return decodeURI(matches[1]);
    } catch (e) {
    }
  }
  return null;
}

// ================================================================================
// END Automated deletion button script system
// ================================================================================

Tabbed navigation (folding multi wiki tabs)

Note: This is an updated version that will work in multiple instances on the same page. For the old version, see here.

Sometimes requested, is something similar to dynamic navigation, but more like the tabs on Special:Preferences. Here is a basic framework for such. It needs some javascript, some CSS (optional actually), and some wikicode/html (that can be templateified).

The javascript

Just pop this into MediaWiki:Common.js.

Hint: If you want to have it only trigger on certain pages, put in a check for wgTitle on the addOnloadHook

// ==================================================
//  Folding Multi Wiki Tabs (experimental)
// ==================================================

addOnloadHook(foldingTabsMulti);
function foldingTabsMulti() {
  var len=0;
  ftsets = getElementsByClassName(document, 'div', 'foldtabSet');  //global object array thingy
  if(ftsets.length==0) return

  for(var i=0;i<ftsets.length;i++) {  
    ftsets[i].head = getElementsByClassName(ftsets[i], 'div', 'foldtabHead')[0];
    ftsets[i].links = ftsets[i].head.getElementsByTagName('a');
    ftsets[i].boxen = getElementsByClassName(ftsets[i], 'div', 'foldtabBox');

    if(ftsets[i].links.length < ftsets[i].boxen.length) {
      len = ftsets[i].boxen.length;
    } else {
      len = ftsets[i].links.length;
    }

    for(var j=0;j<len;j++) {
      ftsets[i].links[j].href = 'javascript:showmultitab(\'' + i + '\',\'' + j + '\');';
      ftsets[i].links[j].title = 'click to display tab ' + j + ' of set ' + i;
    }
    showmultitab(i,'0');
    ftsets[i].head.style.display = 'block';
  }
}

function showmultitab(set,num) {
  for(var j=0;j<ftsets[set].boxen.length;j++) {
    if(j==num) {
      ftsets[set].boxen[j].style.display = 'block';
    } else {
      ftsets[set].boxen[j].style.display = 'none';
    }
  }
  for(var j=0;j<ftsets[set].links.length;j++) {
    if(j==num) {
      ftsets[set].links[j].className = 'selected';
      ftsets[set].links[j].blur();
    } else {
      ftsets[set].links[j].className = '';
    }
  }
}

// ==================================================
//            END Folding Multi Wiki Tabs
// ==================================================

The CSS

To style the tabs, you can copy/paste one of these to MediaWiki:Common.css:

These make the links look like folder tabs, sort of like the monobook p-caction tabs.
/* Folding wiki tabs: folder-like tab style */
.foldtabSet {
  position: relative;
}
.foldtabBox {
  padding:.5em;
  background-color:#ffffff;
  overflow:auto;
  border:1px solid #0000aa;
  position: relative;
  z-index: 1;
}
.foldtabHead a { 
  border:1px solid #0000aa; 
  padding:.13em 1em;
  background-color:#e0e0ff;
  -moz-border-radius-topleft:.35em;
  -moz-border-radius-topright:.35em;
  text-decoration:none;
  color:#0000aa;
  font-size:150%;
  position: relative;
  z-index: 0;
}
.foldtabHead a.selected { 
  border-width:2px;
  border-bottom:none;
  background-color:#ffffff;
  z-index: 2;
}
.foldtabHead p { padding:0;margin:0; }
These make the links and content look more like inset/outset boxes (sort of like in Special:Preferences)
/* Folding wiki tabs: inset box style */
.foldtabSet {
}
.foldtabBox {
  padding:.5em;
  background-color:#fffff2;
  border:2px inset grey;
}
.foldtabHead {
  padding-bottom:10px;
}
.foldtabHead a { 
  border:2px outset grey;
  padding:8px;
  text-decoration:none;
  background-color:#f2f2f2;
}
.foldtabHead a.selected { 
  border:2px inset grey;
  background-color:#f2f2f2;
  font-weight:bold;
}
.foldtabHead p { padding:0;margin:0; }
Or you can create your own style.

The wikicode/html

Here is an example of how to activate the js/css:

<div class="foldtabSet">
<div class="foldtabHead" style="display:none;">
[[#top|First]]
[[#top|Second]]
[[#top|Third]]
</div>
<div class="foldtabBox">
stuff 1
</div>
<div class="foldtabBox"> 
stuff 2
</div>
<div class="foldtabBox">
stuff 3
</div>
</div>
Note that in this newer version, all "id" definitions have been replaced with "class" for proper multiple instances. Because of this, the "foldtabHead" div must be inside the "foldtabSet" div for proper logical association.

Some tricks for the wikicode/html:

  • In the above example, the javascript-fail fallback is to display all the tabs. If you add style="display:none;" to all the class="foldtabBox" divs except one, they will all be permanently hidden for non-JS browsers.
  • In the class="foldtabHead" div, you can remove the style="display:none;" and link the wikilinks to somewhere else besides #top. Then, if javascript is disabled, the user will be taken to an alternate page.
  • You can style the tabs by manipulating the CSS in the previous section, or with inline CSS (except the links).

Open searches in new window

addOnloadHook(function(){
  if(!document.getElementById('searchform')) return
  var search = document.getElementById('searchform');
  var check = document.createElement('input');
  check.setAttribute('type','checkbox');
  check.setAttribute('name','newwindow');
  check.setAttribute('id','newwindow');
  check.setAttribute('value','true');
  check.setAttribute('onclick','searchTargetSwap(this.checked);');
  search.appendChild(check);
  search.appendChild(document.createTextNode('new window'));
});

function searchTargetSwap(chkd) {
  var search = document.getElementById('searchform');
  if(chkd) {
    search.setAttribute('target','_blank');
  } else {
    search.setAttribute('target','');
  }
}

Collapsible portlets

Per a request, a simple method to make all sidebar portlets collapsible. Note that it uses default images in the /skins folder and shows the first portlet (usually 'Navigation') by default. These can be customized in the CSS. Should work in IE now.

In Common.js:

// ==================================================
//  Collapsible Portlets (experimental)
// ==================================================

function foldingPortlets() {
  var portlets = getElementsByClassName(document.getElementById('column-one'),'div','portlet');
  var portskip = ['p-personal', 'p-cactions', 'p-logo', 'ads-top-left'];
  var first=true;

  for(var i=0;i<portlets.length;i++) {
    if(portskip.join(' ').indexOf(portlets[i].id)==-1) {
      var pd = portlets[i].getElementsByTagName('div')[0];
      var ph = portlets[i].getElementsByTagName('h5')[0];
      ph.className = 'portletCollapsible'
      pd.setAttribute('id','pbody-'+i);
      pd.style.display='none';

      var link = document.createElement('a');
      var head = getAllText(ph);
      while(ph.firstChild) ph.removeChild(ph.firstChild);
      link.appendChild(document.createTextNode(head));
      link.setAttribute('href','javascript:showPortlet(\'' + i + '\');');
      link.setAttribute('id','plink-'+i);
      link.className = 'portletClosed';
      ph.appendChild(link);

      if(first==true) { 
        first=false; showPortlet(i);
      }
    }
  }
}
if(skin=='monobook') addOnloadHook(foldingPortlets)

function getAllText(thing) {
  if (thing.nodeType == 3) return thing.nodeValue;
  var text = new Array(); var i=0;
  while(thing.childNodes[i]) {
    text[text.length] = getAllText(thing.childNodes[i]);
    i++;
  }
  return text.join('');
}

function showPortlet(id) {
  var pd = document.getElementById('pbody-'+id);
  var pl = document.getElementById('plink-'+id);

  if(pd.style.display=='none') {
    pd.style.display='block';
    pl.className = 'portletOpened';
  } else {
    pd.style.display='none';
    pl.className = 'portletClosed';
  }
}

// ==================================================
//  End Collapsible Portlets
// ==================================================

In Monobook.css:

/* Classes for collapsible portlets, customize as needed */
h5.portletCollapsible {
  display:block;
  padding:0;
  height:auto;
  border:1px outset grey;
}
.portletCollapsible a {
  padding:1px 1px .2em 15px;
  display:block;
  text-decoration:none;
  color:black;
}
.portletClosed { background:center left url("http://images.wikia.com/common/skins/common/images/Arr_d.png") no-repeat; }
.portletOpened { background:center left url("http://images.wikia.com/common/skins/common/images/Arr_u.png") no-repeat; }

Open in new windows

Per request, a way to specify some links as target=_blank (open in new window):

addOnloadHook(newwindows);
function newwindows() {
  if(window.killnewwindows) return;
  var nw = getElementsByClassName(document,'*','newWindow');
  for(var i=0;i<nw.length;i++) {
    var nwl = nw[i].getElementsByTagName('a');
    for(var j=0;j<nwl.length;j++) {
      nwl[j].target = '_blank';
      nwl[j].title += ' (opens in new window)';
//      nwl[j].className += ' external';
      nwl[j].setAttribute('style','color:#339900;');
    }
  }
}

To specify which links will get this treatment, wrap them in a div or a span with class="newWindow" (you can wrap as many as you want). This example styles them green colored, but the commented-out example also adds them to class 'external'.

Individual users can put the following line into their user js, to disable this feature for them:

var killnewwindows=true;

Be aware this is unadvised for mass usage, as almost all modern browsers let users very easily open in new windows or new tabs with a simple ctrl+click, shift+click or middle-click. Also, adding this script to your Common.js will allow anyone to use it.

Missing Image Tools

Suppose you hate clicking a red image link, not knowing if you'll get the edit page, an upload page, or a free trip to Antarctica. Well, give this a try.

This is an overly customized script, but can be easily adapted for a wide variety of nefarious uses.

// ==================================================
//  Image Redlink Toolkit
// ==================================================
addOnloadHook(redImageTools);
function redImageTools() {
  var img = getElementsByClassName(document.getElementById('bodyContent'),'a','new');
  for(var i=0;i<img.length;i++) {
    var iu = img[i].href;
    if(iu.search(/Special\:Upload/i)!=-1) {
      var it = 'Image:' + iu.substring(iu.indexOf('wpDestFile=')+11,iu.length);
      insertWrappedLinkAfter(img[i], wgScriptPath + '/index.php?title=Special:Log&page=' + it,'logs');
      insertWrappedLinkAfter(img[i], wgScriptPath + '/index.php?title=' + it + '&action=edit','edit');
      insertWrappedLinkAfter(img[i], wgScriptPath + '/index.php?title=' + it,'view');
      img[i].className = 'new newimage';
    } else if(iu.search(/title\=Image\:/i)!=-1) {
      var it = iu.substring(iu.indexOf('title=')+6,iu.indexOf('&action=edit'));
      insertWrappedLinkAfter(img[i], wgScriptPath + '/index.php?title=Special:Upload&wpDestFile=' + it,'upload');
      insertWrappedLinkAfter(img[i], wgScriptPath + '/index.php?title=Special:Log&page=' + it,'logs');
      insertWrappedLinkAfter(img[i], wgScriptPath + '/index.php?title=' + it,'view');
      img[i].className = 'new newimage';
    }
  }
}
 
function insertWrappedLinkAfter(object,link,text) {
  var sm = document.createElement('small');
  var li = document.createElement('a');
  li.href = link;
  var tx = document.createTextNode(text);
  var po = document.createTextNode(' (');
  var pc = document.createTextNode(')');
  li.appendChild(tx);
  sm.appendChild(po);
  sm.appendChild(li);
  sm.appendChild(pc);
  object.nextSibling && object.parentNode.insertBefore(sm,object.nextSibling) || object.parentNode.appendChild(sm)
}
// ==================================================
//  End Image Redlink Toolkit
// ==================================================


Replace &uselang=wgContentLanguage with user's pref language, in links

Say you want to link somewhere offsite with &uselang={{CONTENTLANGUAGE}}, but you don't want to over-ride people's user language settings, or &uselang= parameter. Well, wrap those links in an object with class="userlang-pref", and it'll replace any &uselang=xx (where xx matches wgContentLanguage) with &uselang=yy (where yy is wgUserLanguage). Okay, so you probably don't need it, but it is stil nifty, eh?

if(wgUserLanguage!=wgContentLanguage) addOnloadHook(uselangPrefOverride)
function uselangPrefOverride() {
  var upo = getElementsByClassName(document,'*','uselang-pref');
  if(upo.length==0) return;
  var r = new RegExp('uselang\=' + wgContentLanguage,'i');

  for(var i=0;i<upo.length;i++) {
    var a = upo[i].getElementsByTagName('a');
    for(var j=0;j<a.length;j++) {
      if(a[j].href.search(r)!=-1) {
        a[j].href = a[j].href.replace(r,'uselang=' + wgUserLanguage);
        a[j].title = a[j].title.replace(r,'uselang=' + wgUserLanguage);
        for(var k=0;k<a[j].childNodes.length;k++) {
          if(a[j].childNodes[k].nodeType==3) {
            a[j].childNodes[k].nodeValue = a[j].childNodes[k].nodeValue.replace(r,'uselang=' + wgUserLanguage);
          }
        }
      }
    }
  }
}

Filter Special:Log results

This takes the results of a Special:Log query and regex-searches (from prompt, activated by new portlet button) the plain text representation of each line.

could probably be applied to any special page that returns a single <ul> of results)
if(wgPageName=='Special:Log') {
  addOnloadHook(function() {
    addPortletLink('p-cactions','javascript:speciallogRegexFilter()','Filter','p-logfilter','Regex filter the results on this page');
  });
}

var filter='Image\:';
function speciallogRegexFilter() {
  filter = prompt('Please enter a regular expression for this search',filter);
  if(filter==null) filter = '.*'
  var pattern = new RegExp(filter,'');
  var li=document.getElementById('bodyContent').getElementsByTagName('ul')[0].getElementsByTagName('li');
  var links=[];
  for(var i=0;i<li.length;i++) {
    litxt = getText(li[i]);
    (litxt.search(pattern)!=-1) ? li[i].style.display='block' : li[i].style.display='none'
  }
}

function getText(obj) {
  if (obj.nodeType == 3) return obj.nodeValue;
  var txt = new Array();
  var i=0;
  while(obj.childNodes[i]) {
    txt[txt.length] = getText(obj.childNodes[i]);
    i++;
  }
  return txt.join('');
}

Other

Parserfunctions/magicwords/messages

"Did you delete the talk page?"

Note: It should no longer be necessary to put this into a template and transclude it. It should work directly from inside these MediaWiki message in most cases.

From a thread on Wikipedia:WP:VP/T: When deleting pages, often times the talk pages are forgotten, this can cause a rash of orphaned talk pages to hover around indefinitely. Sometimes a talk page should be kept as a valid indicator as to previous conversations about the page and why it should not exist, but most times the talk pages should be deleted (except in user: namespace). As of this writing, parserfunctions don't work in MediaWiki:Deletedtext, but transcluded parserfunctions do. (should work now without transcluding).

In: MediaWiki:Deletedtext:

{{Template:Talkexist}}
 "$1" has been deleted.
 See $2 for a record of recent deletions.

In Template:Talkexist:

{{#ifexist:{{TALKPAGENAME}}|{{#ifeq:{{SUBJECTPAGENAMEE}}|{{FULLPAGENAMEE}}|{{#ifeq:{{TALKSPACEE}}|User_talk||
'''<span style="color:#00ff00;text-decoration:blink">Note:</span> A [[{{TALKPAGENAME}}|talk page]] (<span class="plainlinks">[{{fullurl:{{TALKPAGENAME}}|action=delete&wpReason=Orphaned%20talk%20page}} del]</span>) exists for this page.'''<br /><br />}}}}}}

This can also be added to MediaWiki:Confirmdeletetext (and will show up similar to the "This page has a history" alert).

Per-namespace sitenotice

Sometimes this is requested. It is fairly straightforward with m:ParserFunctions, just put something like this into MediaWiki:Sitenotice:

{{#ifeq:{{NAMESPACEE}}|Image_talk|This is an image talk page}}

The main namespace can sometimes cause problems as it is null, best to wrap it in dashes:

{{#ifeq:-{{NAMESPACEE}}-|--|This is an article}}

Slightly more advanced is putting a message in multiple namespaces, like for example all talk namespace. This is easier done with a #switch:

{{#switch:-{{NAMESPACEE}}-
 |-{{ns:1}}-|-{{ns:3}}-|-{{ns:5}}-|-{{ns:7}}-|-{{ns:9}}-
 |-{{ns:11}}-|-{{ns:15}}-|-{{ns:101}}-|-{{ns:103}}-|-{{ns:105}}-
 |-{{ns:107}}-|-{{ns:109}}-|-{{ns:111}}-|-{{ns:113}}-|-{{ns:115}}-
 |-{{ns:117}}-= This is a talk page}}

Image upload prompt

A template to ask you to upload an image if it doesn't exist, and automatically display it if it does.

{{#ifexist:Image:{{{1|}}}
|[[Image:{{{1|}}}|{{{size|150}}}px|]]
|<table style="width:{{{size|150}}}px;height:{{{size|150}}}px;" cellpadding=0 cellspacing=0><tr>
<td style="border:1px solid black;background-color:#eeeeff;text-align:center;padding:.5em" valign="middle">
This file doesn't exist yet. You can [{{fullurl:Special:Upload|wpDestFile={{urlencode:{{{1|}}}}}}} upload it!]
</td></tr>
}}