Documentation for Kicksecure ™ Wiki Devs

From Kicksecure
< Dev
Jump to navigation Jump to search

Your support makes
all the difference!

We believe security software like Kicksecure needs to remain open source and independent. Would you help sustain and grow the project? Learn more about our 10 year success story and maybe DONATE!

Layout, Skin, CSS, JavaScript, Links, Header, Footer, CodeSelect, Mobile Frontend, Miscellaneous

Getting Started - MediaWiki Setup (meta)[edit]

Extension CSS Fork[edit]

  • We use the MediaWiki, but a which we wrote ourselves.
  • The extension and the fork in general have 3 options: One to write page specific inline CSS in the MediaWiki page itself. The second option allows to link locally hosted CSS files. The third option allows to link internal CSS pages raw as files
    • Caution: The first option of this ORIGINAL extension (not our fork) for a page specific CSS seems experimental to us, because the CSS text is encoded as a base64 string and imported link so <link rel="stylesheet" href="data:text/css;charset=UTF-8;base64,I3Np...Q7Cn0=">. This is not widely supported in all browsers so this options does not seem reliable and therefore is not recommended for production use!
  • Our fork
    • Usage option 1 - inline: You can write inline code, e.g. {{#css: body { background-color: green; } }} . Our fork implements this as a style-tag (instead of a link tag with base64 like the original extension, see above)
    • Usage option 2 - locally hosted: You can reference locally hosted files, e. g. {{#css:/src-copy/Page_Homepage.min.css}} . NOTE: For this the file has to be hosted in the locally allowed folder. In our case this is set to /mw-autogen in localSettings.php via the variable $wgCSSPath which belongs to the Extension:CSS . This means our example {{#css:/src-copy/Page_Homepage.min.css}} actually (relatively) references the local file /mw-autogen/src-copy/Page_Homepage.min.css
    • Usage option 3 - from the DB: You can reference files hosted in the DB, e.g. {{#css:MediaWiki:Header.css}} . This calls the file from the wiki. In our fork we allow the admin to set allowed namespaces, so CSS files in these namespaces are not "sanitized" by Mediawiki which sometimes leads to unexpected problems. In our case we set the namespace "MediaWiki:" to be not sanitized
  • MediaWiki upstream: feature requests and patches:

Extension HeadScript[edit]

  • We use the MediaWiki to circumvent the usual code inclusion into the <head> area. This is only used where MediaWiki doesn't offer a realistic option to realize a solution otherwise. See LocalSettings.php for the implementation of Headscript
  • Here is a current snapshot of the content that we include via Headscript
<!-- Begin Extension:HeadScript
* server-type  :  production
* Path to scripts : /mw-autogen
* Url query parameter "debug" : undefined
* Url query parameter "dontload" : undefined
* $wgResourceLoaderDebug : "" (empty string)
<link rel="stylesheet" media="print" onload="'all'" href="/libs/Font-Awesome/css/all.min.css" fetchpriority=low>

<link rel="stylesheet" fetchpriority="low" media="print" onload="'all'" href="/libs/Prism/prism.css" >
<script id="highlight-code-script" defer fetchpriority="low" type="text/javascript" src="/libs/Prism/prism.js" data-manual></script>

<link rel="stylesheet" type="text/css" href="/mw-autogen/mw-combined-wikicss.min.css">
<script defer type="text/javascript" src="/mw-autogen/mw-combined-wikijs.min.js"></script>

<style type="text/css">
  @font-face { font-family: Roboto; src: url(/libs/Roboto/Roboto-Regular-webfont.woff); font-display: swap; }
  @font-face { font-family: Roboto; font-weight: 300; src: url(/libs/Roboto/Roboto-Light-webfont.woff); font-display: swap; }
  @font-face { font-family: Cousine; src: url(/libs/Cousine/Cousine-Regular.woff); font-display: swap; }
<link rel="preload" href="/libs/Roboto/Roboto-Regular-webfont.woff" as="font" crossorigin fetchpriority=low>
<link rel="preload" href="/libs/Roboto/Roboto-Light-webfont.woff" as="font" crossorigin fetchpriority=low>
<link rel="preload" href="/libs/Cousine/Cousine-Regular.woff" as="font" crossorigin fetchpriority=low>

<link rel="icon" type="image/svg+xml" href="/favicon.svg" sizes="any">

<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">

<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="theme-color" content="#ffffff">

<meta name="msapplication-TileColor" content="#da532c">

<!-- -----------------------
End Extension:HeadScript -->
  • Solved by this
    • Font-Awesome is included that way
    • Other libraries are included
    • Our general minified css included
    • Our general minified JavaScript included
  • Additional info : In the top comment there are multiple relevant variables printed in their current state
    • server-type indicates if it's production or development
    • Path to scripts : The path where CSS and JS files are situated
    • debug : This query parameter determines if the minified version or the readable version is printed (if debug = true)
    • dontload : This parameter offers to not load our auto-generated js or css files. There are 3 options: ?dontload=js ?dontload=css and ?dontload=jscss
    • $wgResourceLoaderDebug is a setting for LocalSettings.php where the whole wiki can go into debug mode. Similar to the url parameter debug
  • Our fonts are now also referenced and loaded with preload this way for better performance. This includes Roboto (regular font), Cousine (monospace font for pre, code etc) and Font Awesome (Icons)
    • Regarding preload a good article as a resource is this:
    • If crossorigin is omitted the fonts are loaded twice due to the crossorigin settings on the server
    • Only preload is possible. defer or async is only supported by browsers for scripts but not for fonts.
  • There are also some additions regarding favicons

File auto-generation, Combine, Minify, Host Locally, mw-autogen, src-copy[edit]

  1. We use #Extension HeadScript to include our own auto-generated files in the wiki page
  2. These files are generated from wiki files, through a specific process using our own scripts
    1. We created file MediaWiki:Build.json. In this file we describe a build order for all JavaScript files. And also all CSS files.
      • Note that this file has to have a specific structure. Top level are the keywords "wikijs" (JS applied to the whole wiki), "wikicss" (CSS applied to the whole wiki), "skincss" (CSS only if the custom header is present) and "justcopy" (files that will just by copied, not combined). Also there can be the keyword "__comments" at the top which will be ignored by the parse.
      • Every of those keywords has an array of strings below them. These string should all be callable wiki file pages like "MediaWiki:Header.css" etc. Exception: You can use comments if a string STARTS with "//"
    2. Then we created a php build script which has to be executed and combines all files which are mentioned in Build.json and which are then loaded from the wiki files pages. After that the build script combines all files and saves them to the folder /mw-autogen as a - what we call - "mw-combined"-file and minifies it and saves it to a second file "mw-combined.min" etc.
    3. These files are then called via #Extension_HeadScript and can also be called in their human readable form if the URL has the parameter ?debug=true
    4. The source files are also copied to a subfolder /mw-autogen/src-copy/ for optional use by other software (e. g. forums) on the same web domain. And for each file a minified version is also created in the same folder [filename.ext] + [filename.min.ext]
  3. specific locations
  4. By these measures we drastically improved the load time of the wiki, made it really stable and functional again and circumvented the use of Common.js as also suggested by Wikipedia
  5. NOTE: By using this solution the source files (css js etc) are not directly called when the page is loaded. They are merely the source which the combined, minified files are rendered from. So every time there is a change in the source files it first has to be rendered to the output files.
    • One exception is the use of Extension:CSS where we want to use scripts only on specific pages like so {{#css:/src-copy/Page_Homepage.min.css}}. In this case the source copy folder is very useful

Javascript specific[edit]

  • We decided to not use MediaWiki:Common.js to implement a lot of JavaScript.
    • Calling a lot of JavaScript files via Common.js lead to unexplainable errors in MediaWiki, even small crashes (site not available even when it was) and considerably longer load times.
    • Our speculation is that Common.js or the mw.loader.load uses some pre-parsing to check if JS-files are safe. Other speculation is that it just creates to much load if JavaScript files are always freshly loaded from the wiki db
    • Even Wikipedia states in their
  • Keep code in MediaWiki:Common.js to a minimum as it is unconditionally
  • loaded for all users on every wiki page. If possible create a gadget that is
  • enabled by default instead of adding it here (since gadgets are fully
  • optimized ResourceLoader modules with possibility to add dependencies etc.)
  • Since custom scripts offer additional functionality but might degrade performance or break unrelated functionality (even noJS functionality such as session handling) they have to be handled with care.
  • As earlier discussed in this chapter MediaWiki:Common.js cannot be used to integrate scripts. However we want to know when Common.js is loaded so we can be sure that the core modules are loaded - specifically jQuery and others
  • Therefore we introduced a Javascript specific wrapper which is used only in generated files for Javascript. This wrapper is not listed in the MediaWiki:Build.json under "generaljswrapper". This file is currently MediaWiki:MwCombineJsWrapper.js. The file will be pulled and then split at the keyword "/*WRAPPEDCONTENT*/". The first part comes before all other Javascript. the second part comes after all Javascript.
  • In the Wrapper you will find that we listen to an event called "mediaWikiCommonJsIsLoaded". This event is triggerd in Common.js and is the only use that we have for Common.js
  • The wrapper also introduces the property mwDev globally into the window object. This is basically a variable for us to share data between scripts and other dev strategies. The data is shared in the sub property
  • Also we use this wrapper for the dontload functionality which you can learn more about in our convenience tool Dev/mediawiki#Debug-via-url-modal for this purpose

Javascript source mapping[edit]

  • In order to be very transparent and debug more easily we decided to use a source map for our combined wiki js file
  • This way developers can find problems and study the source code even though the minified JS file is loaded for normal users
  • Some information on uglify
    • This is the official documentation . But it might be a bit confusing
    • This is the command we're using (only [file-dir] is a placeholder) uglifyjs '/[file-dir]/mw-autogen/mw-combined-wikijs.js' --output '/[file-dir]/mw-autogen/mw-combined-wikijs.min.js' --source-map "base='/[file-dir]/mw-autogen',root='/mw-autogen',url='/mw-autogen/'"
      • The first parameter is the source file
      • --output or -o specifies the target file
      • [DEPRECATED-BY-US] --compress removes unnecessary the code. We don't use this anymore because this led to errors of variables being removed that we actually needed. See
      • [DEPRECATED-BY-US] --mangle "minifies" the names in the code (renames to shorter names if possible and if not accessible to external functions). We don't use this anymore because it's error prone linke --compress
      • --source-map creates the source map
        • All it's sub parameters have to be wrapped in one big quote.
        • base - this sub parameter specifies the base path in the file system. This path will be OMITTED in the source map "sources" property. Example: If a file has /[file-dir]/file1.js and base='/[file-dir]' then in sources it will be listed as "sources":["file1.js"] else it would have its full path
        • root - this sub parameter specifies the url route (path) that the browser needs to find the file. This will be added to sourcesRoot in the source map. Example: If a file has /[file-dir]/file1.js and base='/[file-dir]/' (see description above for this part) and root='/public' then in source map it will be listed as "sourceRoot":"/public","sources":["file1.js"] and the browser would find the source file under /public/file1.js
        • url - the url sub parameter is the browser route (path) to the source map. It tells the browser where the source map is located in case the user (most likely developer) requests the source code


Extension CookieToBodyClass[edit]

  • We created our own Mediawiki extension
  • This extension passes cookies through the server back to a CSS class in the body tag
  • This is especially useful for cookies written with Javascript which then in turn can activate CSS styling AS SOON as the page is loaded and NOT JUST when Javascript is finally loaded. This simplifies styling in some cases extremely because there's no need to wait for Javascript to add some crucial class
  • Usage
    • It's as simple as writing a cookie - via Server or Javascript
    • The cookie HAS TO have the prefix "ctbc_" (which stands for CookieToBodyClass). For example "ctbc_myTestCookie"
    • The value given to the cookie has to be CSS class compatible, a regexp representing this is: /^-?[_a-zA-Z]+[_a-zA-Z0-9-]$/. For example "my-testValue"
    • When the page is loaded the next time this will result in a combination of cookie name and value as a body class. For example <body class="ctbc_myTestCookie_my-testValue ...
    • When the dev has chosen a value that is not CSS friendly, for example "my/testValue", the body class will be a CSS compatible error for the dev. For example <body class="ctbc_myTestCookie_ctbc-error_cookie-value-not-css-compatible ...
    • This error is a compromise so the user does not see any error on the site, but also so the dev has a change to identify and / or catch errors
  • Other use cases
    • This is also an excellent tool for testing: The dev can create a cookie just in his own browser like "ctbc_mycookie" and set it to whatever he likes e. g. "2". Not he can write CSS and JS cases to just react conditionally on this cookie existing. CSS body.ctbc_mycookie_2 .my-class{...}. JS if( $.cookie('ctbc_mycookie') == '2' ) {...}

Extension BodyScript2 - not in use[edit]

  • We created an extension based on the outdated BodyScript-extension and the still active HeadScript extension
  • With the variable $wgBodyScript2Code in LocalSettings.php we can insert Code at the end of <body> with the help of the hook onSkinAfterContent

Extension Flagged Revisions[edit]

  • We use the Extension Flagged to manage content on our wikis. As our content is security and privacy relevant it would not be acceptable to have unexamined content be shown to visitors. However we are always thankful for good content contributions which are mostly accepted. Flagged revisions prevents unchecked content from being shown to visitors and gives a practical way to manage revisions.
  • The top bar will only be shown to admins if there is a pending revision which the admin then can easily accept
  • The bottom bar is always present and gives admins the opportunity to directly accept and unaccept a revision, give a comment and rate the revision in question for accuracy

Extension Dark Mode (Fork)[edit]

  • We use the extension to offer our users a dark mode experience on our Wikis
  • The extension uses a css filter to invert all colors on the page to dark - except images. We add our own CSS to make the look consistent
  • At the current time (2022-10-25) Tor Browser does not support this mode fully (some weird color glitches) because Tor Browser is currently based on an older Firefox version which had problems with this filter. In the future this will probably be fixed
  • We added a custom button to our custom footer to activate dark mode. This button uses the normal functionality of the extension.
  • Our fork enhances the extension by adding a mode for anonymous users. The original extension saves the "dark mode preference" to the personal user settings of a registered user. Non-registered or non-logged-in users (the majority) therefore have no ability to use dark mode. They can activate it, but once they reload or navigate to another page the dark mode is gone. We fix this by saving the dark mode setting to a cookie with the name "usedarkmode" which is ONLY saved if the user is anonymous and is either "0" (off) or "1" (on). Our fork of the extension will check if this cookie is set to one and activate dark mode - but again ONLY if the user is anonymous. Therefore the basic idea of the extension is kept alive, we just enhanced it for another use case.
  • upstreaming:


  • We maintain multiple wikis for different projects which are very similar in some ways, in particular Kicksecure and Whonix at the moment. We therefore decided to reuse general code on all wikis to avoid code duplication, have consistency and simplify maintenance. "General code" means our own small libraries, usually CSS and JavaScript which are hosted within the wiki content system and usually have the namespace "MediaWiki:".
  • As there is no practical import option in MediaWiki for our purpose we use a "cascading multi-wiki" approach with the assistance of automated scripting.
    • One wiki is the master wiki, this is the Kicksecure wiki.
    • On this and only on this master wiki the "library or general purpose level" code is written and the "cascaded" (one way distributed and overwritten downstream) to the other wikis.
    • All "library or general purpose level" code is given the Category:MultiWiki. Only this code will be "cascaded" when the MultiWiki script is executed
  • Therefore it is very sensible and sometimes necessary to split up files in two files: one which is very specific for the wiki and the other which is general purpose.
    • Note that when creating a new wiki we usually also copy the non-MultiWiki files of course because they are also necessary. But the MultiWiki script will only update the MultiWiki files where

Category:MultiWiki is used as a tag. Wiki pages with this tag are the only ones mirrored from the Kicksecure wiki to the Whonix wiki when the script is executed

Adding a Page to the MultiWiki canon[edit]

  • To add a wiki page to Category:MultiWiki the following text needs to be added to that wiki page. By convention, it should be in the footnotes or section or very bottom the footer of the wiki page.
    1. If it is a wiki page, add:
    2. If it is a wiki template or a widget, add:
    3. If it is a CSS page or JavaScript page, add:


  • to start mirroring (cascading), from one wiki (Kicksecure wiki) to another wiki (Whonix wiki), run: mw-multi-wiki
  • Note : Pages that have not been changed in the source wiki will not result in a recorded change (null edit) in the destination wiki.
  • How to test:
    1. Modify a page that is already in Category:MultiWiki such as Testpage in the source wiki.
    2. Then run mw-multi-wiki
    3. Check for example if Testpage was modified in the destination by looking at its content or Testpage

Structure of our wikis (How to build)[edit]

  1. Our wikis rely on a specific methodology to separate the "backend" from "frontend" look which would usually be the same in other MediaWikis. For page visitors we want to show a "local skin augmentation" which is a more optically pleasing look. This is our own "skin" but not realized as a true MediaWiki skin, but as an augmentation via CSS and JS. But as soon as you edit or go on a special page you get the "common look" of our current MediaWiki skin. This is accomplished by using the Template:Header. Only wiki pages which have {{Header}} will have the special look of our local skin augmentation
  2. Note: There are basically 3 categories for files on our wikis
    1. LocalWiki means: for the local wiki only. This file is not part of the cascading MultiWiki auto deploy
    2. LocalSkin means: for the local skin augmentation only. The skin is also influenced by the "LocalWiki" files, but local skin is even more specific
    3. MultiWiki means: for all wikis, but as general as "LocalWiki".
  3. Entry points
    1. The relevant files are all found in MediaWiki:Build.json. This file has multiple sections. These sections are divided by MultiWiki and LocalWiki files and their dependencies are noted here. So this file is a great way to see the application structure. Sections:
      1. wikijs : These files will be combined into one file whose methods will be available on the whole wiki even without the skin applied
      2. wikicss : These files will be combined into one file whose styles will be available on the whole wiki even without the skin applied
      3. skincss : These files will be combined into one file whose styles will only be available of the {{Header}} template is included in a page
      4. NOTE: All of the files in these categories are also copied into a separate source file folder and also a minified version of them. Read more here #File_auto-generation.2C_Combine.2C_Minify.2C_Host_Locally.2C_mw-autogen.2C_src-copy
      5. justcopy : These files will NOT be combined in any way. They will just be copied as described above. Note that these files can be mixed and don't need to be exclusively Javascript or CSS
    2. #Extension_HeadScript - Import combined files which are rendered from Build.json
    3. Template:Header / LocalSkin - Import CSS files for local skin pages. This file has a double function. It introduces the "local skin augmentation" as well as its header. Files are loaded using #Extension CSS Fork
  4. Important CSS files
    1. MediaWiki:Common.css / MultiWiki - not in use, but MultiWiki, because it's an important system file
    2. MediaWiki:Utility.css / MultiWiki - Define styles which can be used like tools on the site. This file has styles which can be used for all of our wikis. It's general styles which can be used like tools and boilerplate setup styles for things in all wikis which we need to fix
    3. MediaWiki:Boilerplate.css / MultiWiki - Define styles which make up our "basic" style on all our wikis. This file has styles which can be used for all of our wikis. Boilerplate.css is what all our local wikis skins have in common. It is like LocalSkin.css but for all our wikis. It's also only available if the Header (and therefore LocalSkin) is active
      1. MediaWiki:LocalSkin.css / LocalSkin - Define styles for local skin. This file has styles which will only be active on local skin pages
  5. Important JavaScript files
    1. MediaWiki:Common.js / MultiWiki - Trigger / hook to notify our JS that MediaWiki is ready

New Vector Skin and Skin Preferences[edit]

  • MediaWiki states:

Over the next few years, we will be gradually updating the Vector skin. Legacy Vector will allow you to view the old version of Vector (as of December 2019). To learn more about the updates, go to our project

For the admin: Here are the MediaWiki settings to remove the skin preference choices

  1. Under
    1. remove "Enable responsive mode"
    2. remove "Adapt layout to screen size on mobile"
    3. $wgHiddenPrefs = array( "skin-responsive", );
  2. Under
    1. remove "Vector legacy (2010) (Preview)"
    2. hide 'Vector legacy (2010)'
    3. keep 'Vector 2022'
$wgSkipSkins = [


  • We MediaWiki's default Vector skin as a base.
  • We avoid custom MediaWiki skins as these break every now and then which then would force us to stick with MediaWiki oldstable or LTS, unable to update to MediaWiki stable. [1]
  • We create Template:Footer and a Template:Header which is manually included at the top (header) or bottom (footer) in all relevant content pages such as Documentation, Download, FAQ and so forth.
    • The header template completely replaces the navigation of the Vector skin and has its own style and JavaScript functionality.
    • The footer template also has its own style and JavaScript functionality.
  • The Header template injects CSS styles from internal MediaWiki:CSS files via our Extension:CSS fork.
    • Example: {{#css:Mediawiki:Header.css}}
    • So only on pages where the header is present these CSS files will apply.
    • This means that for example on Special:SpecialPages the unchanged Vector style will be shown.
    • This solution gives us the opportunity to have an appearance like a new skin while also having the fallback to a clean Vector skin.


  • Sometimes Javascript is only needed on specific pages for specific tasks. This happens very rarely.
  • So we created MediaWiki:Pages.js - a LocalWiki file where the page specific JS functions are combined


  • FontAwesome is used as a local webfont to make the site more beautiful.
  • We use our own implementation via mediawiki extension HeadScript. (See #Extension HeadScript)
  • Therefore it is available on all pages.
  • Only works when JavaScript is enabled.
  • Has a graceful no-JS fallback, in that case simply no symbols will be shown.
  • Loaded using CSS (async). Not loaded using JS. Loading using JS would require a different syntax to use FontAwesome.

Usage Examples[edit]

  • FontAwesome is used on all wiki pages because the supermenu symbols use it.
  • Donors cards are using it.
  • Whonix homepage VPN table is using it.

fontawsome font-display: swap[edit] says

When fonts are loaded with default display settings, like font-display="block", browsers will hide text entirely for several seconds instead of showing text with a fallback font.

Font Awesome 5 Free 900 normal

Add font-display: swap

What we currently have:

<link rel="stylesheet" type="text/css" href="/libs/Font-Awesome/css/all.min.css">

<link rel="stylesheet" type="text/css" href="/mw-autogen/mw-combined-wikicss.min.css">

<style type="text/css">
  @font-face { font-family: Roboto; src: url(/libs/Roboto/Roboto-Regular-webfont.woff); font-display: swap; }
  @font-face { font-family: Roboto; font-weight: 300; src: url(/libs/Roboto/Roboto-Light-webfont.woff); font-display: swap; }
  @font-face { font-family: Cousine; src: url(/libs/Cousine/Cousine-Regular.woff); font-display: swap; }
<link rel="preload" href="/libs/Roboto/Roboto-Regular-webfont.woff" as="font" crossorigin fetchpriority=low>
<link rel="preload" href="/libs/Roboto/Roboto-Light-webfont.woff" as="font" crossorigin fetchpriority=low>
<link rel="preload" href="/libs/Cousine/Cousine-Regular.woff" as="font" crossorigin fetchpriority=low>

There are two different ways we currently add fonts.

  • 1) link rel="stylesheet" for font awesome
  • 2) <style type="text/css"> for Roboto / Cousine

Would it make sense to load font awesome the way Roboto is load?


  • The problem is that fontAwesome is loaded in its own CSS file .../Font-Awesome/css/all.min.css - this means that adding and preloading the font is already done by the CSS. It's probably hard to separate this step from
  • There is a very good post about it here with probably the best quote

You cannot mark it swap by default - this will cause random characters to appear (or in the best case squares). This is a very bad UX.

See the explanation from Google: swap gives the font face a zero second block period and an infinite swap period. This means the browser draws text immediately with a fallback if the font face isn’t loaded, but swaps the font face in as soon as it loads.

This behavior is desired for small blocks of text (e.g. headings). For big chunks of texts you should use fallback for big blocks (e.g. article contents). The block setting gives the user no icons on load and loads them as soon as possible, which is better than broken icons blinking into proper icons.

MediaWiki Default Links[edit]

The default links in the wiki are realized via the MediaWiki Extension

Wiki editor software enhancements[edit]

  • The standard wiki editor software is enhanced in multiple ways
  • Extensions
  • In-wiki improvements
    • We created a Fullscreen mode for the editor, see #EditorFullscreen
    • We created a saving mode which doesn't reload the page, see #Editor SaveAndContinue
    • We created an auto-backup for wikitext which automatically saves your edits to the browser's localStorage, so you don't lose progress when something goes wrong, see #EditorAutoBackup

MediaWiki limitations[edit]

  • Not everything is easily implemented with MediaWiki. One problem we found is that the page content will always be delivered in div#content
  • This leads to problems when elements need repositioning with CSS especially regarding div#mw-data-after-content which will always be rendered after the div#content and which is inconvenient in our case because the footer should be the last thing which can be seen
  • We solved this in the file MediaWiki:Utility.css where we put the whole div#mw-data-after-content with position absolute "above" the footer so it (and for example the Revision bottom bar) is still usable and not hidden by the footer
  • This might be considered a "harmless" hack. Still it can be deactivated by commenting out the lines in the chapter "Flagged revisions Bottom bar" in MediaWiki:Utility.css

Implementation Details (in-wiki)[edit]

Crypto QR Code Image Templates[edit]



<div class="our-special-own-footer"></div>

References and Footer[edit]

The footer is structually (html) positioned in the main content area. The vector skin footer is made invisible so there is no overlap. If references are auto-generated by mediawiki then they are below the footer structure and so they are overlapped, this is not desirable. Therefore it is common practice to always write the "references..." keyword in the page so the references headline is generated above the footer structure


  • Deprecated. Reasons: causes issues with caching, keeps MediaWiki busy, might confuse search engines.
  • RandomNews in the footer shows random whonix wews which are fed from Template:RandomNews
  • The Template is not directly imported into the footer widget, because widgets can take Templates as parameters.
  • The RandomNews template is included in the Template:Footer and made display:none via CSS. If Javascript is present then the RandomNews will be moved to the footer and replace the standard text which is in the RandomNews box in the footer. This happens via MediaWiki:Footer.js

Homepage (/wiki/Homepage)[edit]

  • The Homepage is an improved version of the old Kicksecure ™ plain HTML/CSS based
  • It is realized via Widget:Page_Homepage and Mediawiki:Page_Homepage.css
  • Visitors can view it under
    • is the canonical domain name.
    • Implemented using
    • uses Disallow: /wiki/Homepage to avoid duplicate search engine indexing.
      • can of course be index normally.
    • while far from being a secret, a technical implementation detail, should not be shown to users as it would confusing.
    • Editing will result in making changes to
  • Structure
    • The page is wrapped in div with the class section-wrapper
    • Right below there are the sections which can be CSS references via .section-wrapper > div. They all have classes as names that start with section-, e. g. section-banner, section-download, section-press
    • Inside every section there is a div directly below the parent which has the class inner-wrapper, which wraps the inner content and helps with positioning. It is also a resource for future designers to design the content via CSS
    • Right below the section-wrapper there can also be other elements
    • h2 is the standard tag for headlines
  • There are special classes for sections which can be used give those sections a special look
    • dark-section : a dark section has a dark background. It can be combined with row-3- and row-5-sections. The dark section spans over the whole page, while the inner content is max 960px
    • row-3-section : These sections have 3 elements on wide displays, 2 on medium displays and 1 on small displays. They are used for testimonials, features or other text heavy tasks
    • row-5-section : The sections have 5 elements on wide displays, 3 on medium displays and 2 on small displays. They are used for icons and low information items
  • There is also a special class for images image-contain which is optional. By default images are in the background with background-size: cover; so the image always fills the whole area but because of the some parts might a cut. While with image-contain the image has background-size: contain; so the image will be fully visible but not cover the whole area. See example below

Creating a new section

  • copy the following structure inside of <div class="section-wrapper"></div> and exchange yourSectionName by something of your choice
<div class="section-yourSectionName">
 <div class="inner-wrapper">
  • put all your content inside of the div with inner-wrapper
  • if you want to use one of the special classes, put them behind section-yourSectionName in the class attribute


  • If you used row-3-section the direct children of inner-wrapper need to look like this
 <i style="background-image:url('/w/images/thumb/path-to-your-image.bmp');" title="Your title"></i>
  Your text and possibly links


 <a class="image image-contain" href="/your-link" target="_blank" title="Your title"
  Your text and possibly links
  • As you can see: The image can be either realized with an i-tag or an a-tag. But if you use an a-tag it needs to have the class "image"
  • Also note there is an example here for the optional use of image-contain, see the explanation of image-contain from above
  • It is also important to note: You can use h4, p and span elements as content


  • If you used row-5-section the direct children of inner-wrapper need to look like this
<a href="/your-link" target="_blank" rel="noopener">
 <img src="/w/images/thumb/path-to-your-image.bmp" alt="Alt description" />
 <span>Your text</span>

Fixed Header Overlap for anchors[edit]

  • We have a fixed header because this is a modern solution which works good for mobile and desktor alike
  • A usual problem with fixed headers however is that the overlap "jump points" / inner page links / anchor links within the page.
    • So you click a link with # and you jump within the current page to the position.
    • However the fixed header appears on top of the element (e.g. a headline) which you therefore can't see
  • We know 3 solutions to this problem
    • The first one is to position and anchor-element (usually <a> but any element with id-attribute works) enough pixels BEFORE the point where you want to jump
      • This is not possible for us, because were using Vector skin and therefore cannot decide the HTML structure
    • The second solution is to use the CSS property scroll-padding-top. This works in most modern browsers but not always reliably when you have a URL with the # jump point already in it
    • The third solution is to give the element a top padding via CSS and counter via the top margin in the other direction (e.g. padding-top: 50px; margin-top: -50px)
  • Because of the structure of mediawiki and vector skin we use solution two: scroll-padding-top and a version of solution three where we give the headline subelement .mw-headline a padding top which does not show up in the content the element is display inline, but most browser jump to the top position

CSS: Chrome anchor bug with special chars[edit]

  • For the fixed header to work we add a padding to the id-element with the class .mw-headline within the headline (h1-h6), so when jumping the header does not overlay on the headline
  • however this is not working with Chrome when there are special characters in the ID at the moment (2022-02-02) and this [bug seems to be known but] by the dev team
  • to be fair, Mediawiki ultimately causes the problem itself by generating anchor IDs with special characters which is forbidden in HTML. Headline: "What is up?" - ID: #what_is_up?
    • Maybe this can be changed by an extension or by a setting in localsettings.php ?

Table of Contents[edit]

  • toc is auto-generated on top of a page or explicitely by markup in the body
  • we modified toc in its looks and appearance (expand/collapse instead of show/hide)
  • we also prevent selection of the toc numbering. This means the text in span.tocnumber will not be selected and copied. This is useful when copying parts of the toc to post somewhere
    • CAUTION: This unfortunately doesn't complete work in Chrome. If you mark a little bit more than one toc bullet point and have a space, newline or a part of the next bullet point then the tocnumber in between will be copied to clipboard by Chrome. This is undesired behaviour but tolerated

Supermenu and Edit Button[edit]

  • The supermenu template Template:Header passes 2 parameters to the widget Widget:Header : $page and $revision
  • By that the edit link is constructed: /w/index.php?title=<!--{$page}-->&action=edit&oldid=<!--{$revision}-->
  • This means that even the current revision has the "oldid" url query parameter which is not necessary, but at the moment (2022-02-02) and for the foreseeable future will not cause any problems.
  • However if there will be a problem in the future simply go to Widget:Header and change the line to /w/index.php?title=<!--{$page}-->&action=edit
  • Upgrade via JS (2023-02-06) in Mediawiki:Header.js
    • Via Javascipt it is checked whether in the URL there is a query parameter oldid.
    • The presence of this oldid parameter would indicate that the user visits and old page and therefore if he clicks "edit" he wants to edit based on this old version of the page. In this case the edit link in the super menu will stay as described above.
      • For NoJS users this is the only case.
    • On the other hand if the oldid url query parameter is NOT present then the user would not want to edit an oldid version - even if this version happens to be the current one. This is due to us using the Extension Flagged Revisions. If the extension is late (which it sometmes is) then editing with oldid can cause problems.
      • So if the oldid query parameter is not present in the current page url then via Javascript the href attribut of the "edit" link in the super menu will be manipulated. The oldid parameter will be completely deleted while all the other parameters will stay untouched. Therefore making this link a standard edit link for the page

Combined New Custom Header with MediaWiki Custom Header[edit]

For demonstrative purposes only:

Images, Files and usage of thumb[edit]

Best Practices[edit]

  1. Thumbnails have a specific look to them, but sometimes it is unnecessary to have an enlarge button. Therefore we create hide-enlarge, see #hide-enlarge and thumb-hide-enlarge class
    • We first tried to use frame instead of thumb, as in [[File:abc.png|frame|50px]], but the option frame ignores the forced size by design, see
    • Next we tried border as in [[File:abc.png|border|50px]]. This might be useful in some cases, because it does not ignore forced size. But to make it look like thumb is very time consuming
  2. MediaWiki auto-generates thumbs when give specific links. We use this features for HTML pages (widgets) within the wiki. However there is a problem that these images do not upscale or upscale unpreditably.
    • NOTE: We're talking about the thumb link autogen - not the Mediawiki autogen (wrapper) where mediawiki delivers the original if thumb generation does not work like with [[File:...]]
    • Example: Version works while Version doesn't. The original is 1280px large
    • Now it would be great if thumbs would just always work either by upscaling or by just delivering the original image if the thumb is larger than the original. But as it seems with upscaling (AND the original size too) the thumb does not work
    • We solve this problem with the following best practice
      1. Upload all images way larger than needed
      2. If an existing image does not have a large version try to use an AI image upscaling online tool or create a new representative image
      3. Always use thumb-autogen and give the size in which an image is needed. That way bandwidth is saved and we never need to later applay thumb-autogen selectively
      4. Check if the thumb was successfully generated if not you probably need to upload a larger version

Responsive Thumbnails[edit]

  • Thumbnails are by default made responsive. This leads to a cleaner and more predictable look for users and is also better to handle for editors
  • Thumbnails in this context are defined as
    1. all images that are generated by the [[File...|thumb]] syntax in wikitext.
    2. They have the predictable structure: .thumb > .thumbinner [> a.image] > img
    3. They can be in all parts of the document, not just at the top
  • The new behavior of thumbnails is the following
    1. Normally a thumbnail floats at the right side of the document
    2. It can have as much size at it needs. But it can only take 50% with of the screen, because there needs to be room for something on the left
    3. Once a certain threshold is reached (and below) the thumbnail switches to 100% screen size (and a bit of spacing) and loses floating

Back To Top Button[edit]

Illustrative, cropped screenshot of the back to the top scrolling button

Figure: Back to the Top Button


  • Back to Top Button is realized via MediaWiki:BackToTopButton.css and MediaWiki:BackToTopButton.js which are imported in Common.css and Common.js and thereby available for all pages, including Vector styled pages
  • The button is automatically integrated in all pages and created a button which only becomes visible when the user is scrolling and offers the feature to "jump" to the top
  • MediaWiki:BackToTopButton.js has one implicit (but not critical) dependency of FontAwesome for its symbol
    • suggestion: If FontAwesome is removed the <i class="fas fa-chevron-up"></i> can be replaced by <span>UP</span>

Printing pages[edit]

  • We made some effort to make all pages printable (physically with a browser)
  • Simply press Ctrl+P or select "Print page" in your browser to print the wiki page to your printer or as a PDF file
  • We added some print specific styles in MediaWiki:Boilerplate.css
    • Especially important: Usually the browser optimizes the web page for printing and does for example not print background-images. We force the browser to print background-images for all elements with the class "image", because those are basically images, just embedded differently via background-image
      • The CSS command for this is "print-color-adjust: exact;" and "-webkit-print-color-adjust: exact;" for @media print.
      • Elements with "image" often have their own style attached to it. So if there are elements which also need to be printed because they are background-images, but cannot have the specific image styles, then we use "bg-image" (e. g. <i class="bg-image" style="background-image:url(...)"></i>) which has no other style attached to it other than being visible in @media print

Instant Page - Fast Navigation Rendering[edit]

  • We use the Javascript library to speed up the internal page navigation. For Nojs users everything stays the same.
    • Normally a user would navigate to an internal page on the wiki and have the browser load the new page when they click the link
    • With instantpage the new page is automatically preloaded (via Ajax) once the user hovers over the link for some milliseconds
    • This way the new page renders very quickly making navigation and staying on the site much more attractive
  • There's a couple of for the usage
    • Normally the preloading would start 65ms (hard coded preset) after hovering (so the user does not load every link which he does not click) to save bandwidth
    • By using the attribute data-instant-intensity="mousedown-only" the developer can make the linked page only preload after mouse button was pressed (but already before it was released) being more reliable to only load links that the user really wants to visit
    • On some pages with many links the wait time for hovering may need to be increased like data-instant-intensity="150" to preload only after the given amount of milliseconds
    • Elements can be shown as soon as they're visible - good for smartphones - by using data-instant-intensity="viewport" to the BODY tag (the value can also be "viewport-all" which is even more liberal)
  • The official repository is and there are some forks.
  • Whonix admin suggested setting link rel attribute to "prerender" instead of "prefetch" (like it is currently in the library). This would result in an even faster page load experience, since not only are the elements already fetch ("prefetch") they are also readily rendered ("prerender") and will seemlessly replace the page once the link is clicked possibly result in an "instant navigation experience"

Exclusion of text parts from search engine indexing[edit]

<div class="robots-nocontent"><!--googleoff: index--><!--noindex-->CONTENT<!--/noindex--><!--googleon: index--></div>

Development Rules[edit]

Every developer please follow these rules and consult with the admin. A wiki is a collaborative process so compliance with the rules makes everyone's life easier. Thank you.


  • no external libraries hosted on third party servers
  • locally running Open Source code: yes
  • external libraries preferred from bullseye
  • non-javascript fallbacks required for any new developments
  • Whonix vs Kicksecure website should look different
  • improve from now ~30% design to ~80% design if the remaining ~20% would take \80% of the time
  • keep Dev/CSS in mind
  • screenshot before / after major changes (will be used for public reports)
  • svg is nice as base format but incompatible with Tor Browser maximum security slider setting
  • keep relative link support

MediaWiki Upstream Bugs Reports and Feature Requests[edit]


Using a really small fork:

  • Whonix-Wiki source code folder (MediaWiki including all extensions) (Whonix-Wiki should be renamed to be more generic) contains a patches subfolder which contains all files which are patched. (LocalSettings.php, robots.txt, mediawiki-widgets-extension.json.)
  • The script wiki-fix-permissions on the server deletes the original extensions/Widgets/extension.json file and replaces it with a symlink in the patches folder, file mediawiki-widgets-extension.json.
  • This patch would be no longer required if Allow API (allow API editing pull gets merged.

Wiki convention regarding Widgets:

  • Widgets shall always be wrapped / encapsulated in Templates and (if possible) never be used except via this Template (or another Template using this widget)
  • Reasons
    • Templates are easier to use for wiki editors.
    • Templates support Special:WhatLinksHere, widgets do not. So we can see where a module is used which makes testing and debugging easier
  • Exception:: In some Widgets we use arrays over which we can loop. This works with Widgets but does not work with Templates. This is also how the Extension:Widgets suggests using arrays. See . Moreover the Extension:Widgets does not allow the modifier "explode" which would usually be used to convert a string to an array in the Smarty template engine. That is why we sometimes use widgets instead of templates. To bypass the "findability" problem of widgets you can search #widget:widget_name to find all Widget instances


Performance Testing[edit]

  1. We have implemented a couple of performance testing measures
  2. The test results are documented here: PerformanceTests
  3. The relevant Files are
    1. MediaWiki:MwCombineJsWrapper.js
    2. MediaWiki:JsPerformanceTests.js
  4. In MwCombineJsWrapper there is the function window.mwDev.test.pageLoading which measures different (manually triggered) events and outputs the difference between all of them
    1. The two events currently in use are "pageLoadStart" and "pageLoadFinished". These are written to the console directly.
    2. For each event there's the time of occurrence and the diff to all previous events
  5. In MwCombineJsWrapper there is also a functionality which gets activated if the url query parameter ?delayedPageLoad=true is used
    1. This hides the page for 20 seconds after it is loaded and then makes the page reappear
    2. This is done to test whether gtmetrix and pagespeed ignore Javascript or really reander the pages property. Our research from 2022-10-15 shows the both testing pages correctly hid the page and therefore reacted to the javascript correctly
  6. In JsPerformanceTests there are these functions. The can be called in the browser console or in other scripts. mwDev is in the global namespace
    1. mwDev.test.jsJammer = function( bursts = 10, pause = 300, runs = 100 ) : This method will create 1 millions times bursts (of heavy processor load) with pauses in milliseconds for given amount of runs (repetitions). This is to slow down the browser and create a low performance browser scenario for testing reasons.
    2. mwDev.test.scrollPageTest = function( time = 600, runs = 10 ) : This method will scroll the whole page up and down in the give time milliseconds for the given amount of runs (repetitions). One run down will take time to complete. The measurement however is down and up again, so time * 2. Against this will be measured the time it actually took to scroll the page. The difference should give a hint if the page is performing well or not

Development: use files only if needed[edit]

Bug report to upstream[edit]

Sometimes (seldomly) there needs to be a bug report or feature request or suggestion to upstream. Below are the necessary steps for this, demonstrated on a real request which we sent

Example: gerrit patch compare

git clone mediawiki-extension-css

cd mediawiki-extension-css

git fetch refs/changes/96/759196/1

git checkout -b change-759196 FETCH_HEAD

git remote add adre

git fetch adre

git diff -C adre/all-css

Image Optimizations[edit]

Image Optimizations Installation[edit]

sudo apt update sudo apt install mat2 optipng jpegoptim webp

mat2 - strip of metadata[edit]

To strip files of meta data use mat2 on linux.

Strip images of metadata in place - in the directory where you're in. Caution: Might reduce quality or totally break images in case of SVGs!

mat2 image-file-name

If that fails, try:

  • mat2 --lightweight image-file-name
    • Minor space saving effect on images that have been created using gimp.
    • Removes metadata.


  • mat2 --show original-file-name
  • mat2 --show cleaned-file-name

PNG Optimizations[edit]

Specifically for PNG.

optipng -quiet -o7 -zm9 -zc9 -zm9 -zs3 -f5 --strip all -preserve image-file-name

JPG and JPEG Optimizations[edit]

Specifically for JPG and JPEG.

jpegoptim --quiet -o --strip-all image-file-name

Convert to WEBP[edit]

Convert to WEBP.

cwebp -mt -lossless -z 9 input-file-name -o output-file-name.webp

SVG Optimizations[edit]

SVG Optimizations - Introduction[edit]

WARNING: SVG is particularity vulnerable to metadata!

1. Saving the SVG as "optimized" in inkscape as this might be more reliable than scour.

2. Try scour (documented below).

3. Check image quality. If unchanged, keep changes by scour. Otherwise, revert.

4. Try svgo (documented below).

5. Check image quality. If unchanged, keep changes by svgo. Otherwise, revert.

6. Check image for metadata using text editor.

Open in a text editor and search for file paths containing Linux user account name.

7. Check image for metadata using other tool.

TODO: Did we use any? If not, skip.

8. Upload.

9. Done

SVG Optimizations - scour[edit]

WARNING: scour can break the SVG!

scour --enable-viewboxing --enable-id-stripping --enable-comment-stripping --shorten-ids --indent=none -i input-file-name -o output-file-name

SVG Optimizations - svgo[edit]


SVG Optimizer is a (Node.js-based) tool for optimizing SVG vector graphics files.


Install re.sonny.OhMySVG via flatpak.

1. Add flathub repository. [2]

Platform specific.

  • A) Kicksecure ™: flatpak remote-add --if-not-exists flathub
  • B) Kicksecure ™ for Qubes Template (kicksecure-16): http_proxy= flatpak remote-add --if-not-exists flathub
  • C) Kicksecure ™ for Qubes App Qube (kicksecure): flatpak --user remote-add --if-not-exists flathub

2. Install the flatpak re.sonny.OhMySVG package.

Platform specific.

  • A) Kicksecure ™: flatpak install flathub re.sonny.OhMySVG
  • B) Kicksecure ™ for Qubes Template (kicksecure-16): http_proxy= flatpak install flathub re.sonny.OhMySVG
  • C) Kicksecure ™ for Qubes App Qube (kicksecure): flatpak --user install flathub re.sonny.OhMySVG

3. Done.

The procedure of installing re.sonny.OhMySVG is complete.

4. Upgrades notice.

Note: this procedure will not keep the software up-to-date. How to update installation installed by flatpak is also documented on the Operating System Software and Updates wiki page.


flatpak run re.sonny.OhMySVG


Using HTML comments as spacers in Templates[edit]

  • We realized that MediaWiki seems to render (seemingly) unnecessary p-paragraphs if there is a gap between templates used in a page. This leads to unwanted spacing. But if we do not use newlines then the code is very hard to read
  • This seems to be standard behavior and not a bug, as also reported here, especially when dealing with div-elements
  • In this link there is also a suggestion to deal with the problem: adding HTML comments as spacing like so
  • This would also apply for using templates like so


  • This is not the most beautiful solution, but better than the alternative having to write everything in the same line
  • This should not be used permanently. We occasionally use this as a workaround until this is fixed by MediaWiki

Debug Images Cache[edit]

webp images are automatically created from jpg, jpeg and png once per day on the server. Modern web browser are sending the accept HTTP header. The browser is using that header to advertise that the browser supports for example the webp image format. If the HTML markup contains a request for a jpg, jpeg and png but a a webp is already available and the browser supports it, the webp will be delivered instead.

This can sometimes be confusing.

To explicit download the original image format it is the easiest to use a command line downloader such as wget. This works because command line downloaders are in the experience of the author not sending the accept HTTP header. Hence, the server will deliver the actual file and not "upgrade" to webp. For example:

wget ''

To debug if the image is a jpg, webp or otherwise use the commands.


curl --silent --head '' | grep content-type:

content-type: image/jpeg

curl --silent -H 'accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8' --head '' | grep content-type:

content-type: image/webp

Code Resources for MediaWiki[edit]

As inspiration or directly as a code source.

Example Pages for CSS Enhancements[edit]

BIMI Images[edit]

Instructions to create a bimi logo from an inkspace svg (tested method)

  1. open logo in inkscape
  2. Save as -> optimized SVG, choose "remove meta information"
  3. open logo in gedit (or similar)
  4. in svg-tag remove x= and y= attributes and use version="1.2" attribute and add (if not present) baseProfile="tiny-ps" attribute
  5. add title="your-title" attribute directly under svg tag. your-title can be your company or product name
  6. optionally add desc="your-description" directly after title tag. your-description can be a description of your company or product
  7. remove all animations from logo (if present, usally not)
  8. Upload to wiki
  9. Check with


MediaWiki Purge : deleting cached file[edit]

If you click purge on page or use the respective urls (examples below) then the cached file on the server is deleted and you should get the newest version

mediawiki cache purge:

nginx Cache Bypass[edit]

nginx bypass cache example (not really deleting the cache either yet):

If successful, the HTTP response header x-cache-status will show BYPASS.

x-cache-status: BYPASS

MediaWiki special resources[edit]

Those are hard to find via Google, so they are listed here

Special code resources (possibly outdated)[edit]

Debugging CSS JS mw-autogen[edit]

1. Check:

Are all files there?

2. MIME type issues? / content-type: text/html?

Is the file even there?

3. Custom CSS JavaScript Debugging

Debugging Browser Console Errors[edit]

It is useful to enable MediaWiki (JavaScript) debug mode. To do so...

1. go to

2. click edit

3. the link being opened will be:

4. replace action=edit with debug=true

5. press enter to load the page

5. or skip the previous steps and direclty to to

6. consider FAQ with Testpage16 or so

In result in the browser console the scripts in the Debugger part are no longer minified and easier to read.

Search Suggestions Debugging[edit]

  • Vector legacy uses:
    • curl --head
  • Vector 2022 uses:
    • curl --head
    • This was broken in past due to an nginx configuration issue. rest.php was reachable but rest.php/v1/ etc. was not.

Check if scripts are loaded[edit]

These scripts were used for debugging scripts while es special MediaWiki skin was applied

Using a desktop browser with mobile skin these scripts get loaded:

* https://www.{{project_clearnet}}/w/load.php?debug=false&lang=en&modules=jquery%2Cmediawiki&only=scripts&skin=minerva&version=obJk0fES
* https://www.{{project_clearnet}}/w/load.php?debug=false&lang=en&
* '''https://www.{{project_clearnet}}/w/load.php?debug=false&lang=en&'''
* https://www.{{project_clearnet}}/w/load.php?debug=false&lang=en&modules=mobile.toc%7Cmobile.toc.images%7Cskins.minerva.tablet.scripts&skin=minerva&version=6b1c9eeeb881
* https://www.{{project_clearnet}}/w/load.php?debug=false&lang=en&modules=startup&only=scripts&skin=minerva&target=mobile

But using the emulated mobile device with the same skin only these get loaded:

search for


the error only occurs when a mobile device is used and the mobile theme is active

Test user agents[edit]

Test which different responses the server sends to different user agents

curl > 1

curl --user-agent "" > 2

curl > 3

curl --user-agent "" > 4

curl --user-agent "" > 5

curl > 6

meld 1 2

Caching or not caching[edit]

We send a cookie to the server. If the server sends back the same header for both request then caching is off

curl --head --cookie cookie_name=cookie_content

curl --head

TOR browser testing of Javascript scripts to prevent NoScript bugs[edit]

  • It is strongly suggested to to test all new Javascript scripts and modifications with Tor browser or a browser that has NoScript installed but with lowest / off settings
  • NoScript sometimes influences the execution of scripts even if it's set to "not interfere". This can maybe be considered a NoScript Bug. But it is essential to test for NoScript bugs and optimize our scripts to that effect anyways because NoScript is standard on Tor browser and Tor users are a large target community using Whonix and Kicksecure
  • So every time a new script is written or a script is modified check with Tor browser Standard security setting if everything is still working

EXPORT to new wiki[edit]

If new wiki shall be created which is similar to the current master (Kicksecure) you can use the Export function to export all necessary pages and files (e. g. images) and then import those files in the new clean slate wiki.

CAUTION: This export is different from the export cascade from Kicksecure (master) to the "slave" wikis. All new design and code inventions on the Kicksecure wiki will be mirrored towards the "slave" wikis once they are finalized and tested. See #MultiWiki for more information. But this export here is for creating completely new wikis as a copy of the Kicksecure wiki.

In the last main export event (2022-03-19) the following files were exported. To repeat this process

  1. copy the following files
  2. insert into Special:Export and save the resulting XML-file
  3. go to [new_wiki_domain]/wiki/Special:Import
  4. Use the following Interwiki prefix: en
  5. copy the following list and paste into the import list on the Special:Import page
    CAUTION: This list does not claim to be complete or accurate or up-to-date. If you want to be sure you have to check the complete list and remove old files and add new ones. This list is just meant to save you time. Also be so kind to update the list if you have created a new more accurate up-to-date list.

Show Export List

MediaWiki:Common.js MediaWiki:Common.css MediaWiki:BackToTopButton.js MediaWiki:BackToTopButton.css Template:Download Button Widget:Download Button MediaWiki:Download Button.css MediaWiki:Download Button.js Template:CodeSelect Widget:CodeSelect MediaWiki:CodeSelect.js MediaWiki:CodeSelect.css Template:Archive_link Widget:Archive_link MediaWiki:Archive_link.css MediaWiki:Bootstrap Fixes.css Widget:Subdomain link Template:Subdomain link File:Magnifying-glass.png File:Support-premium.png File:Support-plus.png File:Support-free.png File:Mastodon-logo.png File:Twitter-logo.png File:Reddit-logo.png File:Facebook-logo.png File:Donate-banner.png File:Evolution-host.png MediaWiki:SaveAndContinue.css MediaWiki:SaveAndContinue.js File:Chevron.png File:X.png MediaWiki:Vector.css MediaWiki:EditorFullscreen.js MediaWiki:EditorFullscreen.css MediaWiki:LocalWiki.css MediaWiki:Dev.css MediaWiki:Fonts.css Template:Header Widget:Header MediaWiki:Header.js MediaWiki:Header.css Template:Footer Widget:Footer MediaWiki:Footer.js MediaWiki:Footer.css MediaWiki:ScrollableIndicator.js MediaWiki:Mininav.css MediaWiki:Sitenotice Widget:Sitenotice MediaWiki:Sitenotice_id MediaWiki:Sitenotice.css MediaWiki:Sitenotice.js MediaWiki:Hide siteNotice.css File:Grow-symbol.png File:Qr-logo-v2.png MediaWiki:Donation_Panel.css MediaWiki:Donation_Panel.js Widget:Donation_Panel File:Affiliate 128.png File:CAD 128.png File:CHAPS 128.png File:BACS 128.png File:FasterPay 128.png File:WireTransfer 128.png File:ACH 128.png File:Swift 128.png File:DirectDebit-card-dark 128.png File:Sepa-Last 128.png File:Sepa-card-dark 128.png File:IBAN 128.png File:AUD 128.png File:GBP 128.png File:Discover-card-dark 128.png File:UnionPay-card-dark 128.png File:AmericanExpress-dark 128.png File:Dollar 128.png File:Euro 128.png File:Bank-dark 128.png File:MasterCard-dark 128.png File:Visa-card-dark 128.png MediaWiki:PayViaPaypal.css MediaWiki:PayViaPaypal.js File:Payment-generic-symbol.png File:Crypto-generic-symbol.png File:Credit-card-generic.png File:GiroPay-card-dark-enlarged 128.png Widget:Expand_or_Collapse_All MediaWiki:ExpandAndCollapse.js Widget:FlyInNotification MediaWiki:FlyInNotification.css MediaWiki:FlyInNotification.js MediaWiki:Hide flyInNotification.css Template:Pay bitcoin qr Template:Pay bitcoin qr imgurl Template:Pay monero qr Template:Pay monero qr imgurl Template:Pay ethereum qr Template:Pay ethereum qr imgurl Template:Legal documents Template:Hide all banners Template:Support Choice Donate Template:Payments Donate/Affiliate Link Donate/Bank Wire Donate/Bitcoin Donate/Credit Card Donate/Crypto Donate/EUR Donate/Ethereum Donate/GBP Donate/Monero Donate/PayPal Donate/Tax-Deductible Donate/USD Donate Bitcoin Donate Ethereum Donate Monero Donate by Affiliate Link Template:Donation mininav

USAGE : Module Documentation (Alphabetical order)[edit]

Anchor - manually placed anchors[edit]

  • Template:Anchor is a span element with the class "manually-placed-anchor"
  • It has 1 anonymous parameter which sets the id attribute for the span element
  • CSS: The element has no dimension and is relatively positioned above it's normal position about the amount that the Header is high. That way if the anchor is called the header does not overlap the anchored position. This is especially useful when referencing headlines
  • It is usually used to manually set anchors to make old links work with new headlines
  • Example: {{Anchor|my_id}} creates <span class="manually-placed-anchor" id="my_id"></span>


  1. Archive_link creates a custom absolute link with an auto-created link to web archive and multiple options. It structurally mimics the MediaWiki extension "Link to archive".
  2. Documentation for wiki editors: Dev/wiki#Links
  3. It is realized via the files
    1. Template:Archive_link
    2. Widget:Archive_link
    3. MediaWiki:Archive_link.css
  4. Detailed Documentation
    1. This template is based on the widget Archive_link and uses styles from Archive_Link.css .
    2. It is designed to display an external link in different ways: (A) as link without any additions (B) as a link with small logo links behind it symbolizing alternative addresses (onion or archive)
      1. Caution: As all links are external, the target attribute will be set to "_blank"
    3. Parameters
      1. url | string, default: "" - the url you want to link to
      2. text | string, default: "" - the link text displayed in the main link
      3. archive | string, default: "auto" - if not "none" then there will be a logo link to an archive page of the given url. Options are (A) "auto" - where the archive link is auto-generated from the url (B) "copy" - where the link is exactly copied from the url (useful when url is already from and (C) none - where no logo link is shown
      4. onion | string, default: "none" - if not "none" then there will be a logo link to an onion url. Options are (A) none - no logos is generated (B) "copy" - where the url is copied to the logo link (useful if url is already onion link) and (C) [onion-url] - a real onion url which is an alternative url to the main url. Note: If onion is an url or onion is "copy" then the link will have rel="nofollow" to prevent broken links for search engines. In the case of "copy" the main link will also get "nofollow" because it then is obviously an onion url too

Example Usage

{{Archive_link|text=Whonix Clearnet|url=}}

Box and MBox[edit]

  • These are 2 templates which are used to create special text boxes
  • Template:Box is a container usually for text. Template:Mbox uses Box and integrates an image into it
  • Box uses the design class "info box", see #info-box class
  • Box has the parameters: |text= and |addToClass
    • addToClass can have every legitimate CSS class to style the class
    • text can have every text
    • Box can also have one anonymous parameter instead of text
{{Box|text=Hello World}}
has the same result as
{{Box|Hello World}}
  • MBox has the parameters like Box plus: |image=
  • There is a special class "ib-for-thumb". This can and should be used for info-box elements (Box and MBox) that are next to the thumbnail. If these have the class "ib-for-thumb" then the info-box will not be very thin and unreadable for small devices but will be cleared and moved to its own line
  • examples
| image = [[File:TestImage.png|40px|alt=Test]]
| addToClass = ib-for-thumb
| text = My Text here
| addToClass = ib-for-thumb
| text = My Text here


  1. CodeSelect creates a multiline text area or an inline text field to display code or technical information
    1. It has a button to copy all text to the clipboard
    2. Also all text will be marked if the user clicks into the text area
    3. Is NoJS (no-JavaScript) compatible. In NoJS mode the copying button is not shown but text is markable and copyable. In NoJS CodeSelect in icon mode (data-button-image-src) will completely be hidden.
    4. CodeSelect auto-highlights text which is in specific languages. Supported languages: bash, markup (includes html,xml,svg,mathml,ssml,atom,rss), shell session
  2. These are the files for CodeSelect
    1. MediaWiki:CodeSelect.js
    2. MediaWiki:CodeSelectHighlightList.js
    3. MediaWiki:CodeSelect.css
    4. Template:CodeSelect
    5. Widget:CodeSelect
  3. USAGE: First and most importantly CodeSelect can be called via template and via class. We'll refer to those to options "template-call" and "class-call". Template-call is usually best for usage in normal wiki pages. Class-call is the only option for widgets and sometimes also useful on normal wiki pages.
    1. Examples
      1. Example Template-call {{CodeSelect |code=your code whatever you want except pipe-Symbol |inline=if true then displaying will be in line |buttonImage=specify the url of an image for icon mode |buttonImageEager=makes the image load eagerly instead of lazily (standard) |target=selector of an element for CodeSelect to be added to }}
      2. Example class-call <span class="code-select inline-style insert-mode-html image-eager" data-button-image-src="specify the url of an image for icon mode" data-language="bash" data-target="id of an element for CodeSelect to be added to"> your code whatever you want INCLUDING pipe-Symbol </span>
    2. Features
      1. code (string): This parameter can be text of all kinds. It can even be HTML (in HTML mode)
        1. Example. Template-call {{CodeSelect|code=echo "Hello World"}} renders to echo "Hello World" and class-call <span class="code-select">echo "Hello World"</span> renders to echo "Hello World"
      2. inline (boolean): This parameter makes the CodeSelect box an inline element which flows with the text instead of a block which it usually is
        1. Example. Template-call {{CodeSelect|code=echo "Hello World"|inline=true}} renders to echo "Hello World" and class-call <span class="code-select inline-style">echo "Hello World"</span> renders to echo "Hello World"
      3. lang (string, default: "bash"): When specified this parameter can select a specific language which should be highlighted in the CodeSelect box (for example: bash). A specific keyword is "none" meaning no highlighting will take place
        1. Example. Template-call {{CodeSelect|code=echo "Hello World"|lang=none}} renders to echo "Hello World" and class-call <span class="code-select" data-language="none">echo "Hello World"</span> renders to echo "Hello World"
      4. insertHtmlMode: This parameter is ONLY CLASS-CALL due wiki internal processes with the template and widget. To use it just add the class insert-html-mode. This gives the opportunity to insert structured HTML into the code box, not just text. NOTE: This parameter sets the parameter lang to "none" because it does not work with highlighting
        1. Example. <span class="code-select">More <b>Info</b> here</span> More Info here vs <span class="code-select insert-mode-html">More <b>Info</b> here</span> More Info here
      5. buttonImage: We introduced a mode to now make CodeSelect a simple button to copy code or text to the clipboard.
        1. Note: The image gets an automatic hover effect (= -3% brightness), but all is controllable via CSS
        2. Note: buttonImage is usually loaded lazily, meaning the image has the attributes decoding="async" loading="lazy". If you want to prevent this use the parameter buttonImageEager
        3. Template-call: Add the buttonImage-parameter specifying the image source url. Don't use the [[File:...]] call, just a url, for example a relative url like /w/images/a/bc/def.jpg
        4. Class-call: Simply add the attribute "data-button-image-src" to wrapper element (HTML implementation) with the image url
        5. Example. Template-call {{CodeSelect|code=echo "Hello World"|buttonImage=/w/images/8/8c/Supermenu3.png}} renders to echo "Hello World" and class-call <span class="code-select" data-button-image-src="/w/images/8/8c/Supermenu3.png">echo "Hello World"</span> renders to echo "Hello World"
        6. buttonImage can also be used with an empty String or just as an empty attribute. In this case the usual copy icon will be shown.
          1. Example. Template-call {{CodeSelect|code=echo "Hello World"|buttonImage=}} renders to echo "Hello World" and class-call <span class="code-select" data-button-image-src="">echo "Hello World"</span> renders to echo "Hello World"
      6. buttonImageEager: Normally buttonImages are loaded lazily. Use this parameter to force eager loading (this omits the attributes decoding="async" loading="lazy"
        1. Example. Template-call {{CodeSelect|code=echo "Hello World"|buttonImage=/w/images/8/8c/Supermenu3.png|buttonImageEager=1}} renders to echo "Hello World" and class-call <span class="code-select image-eager" data-button-image-src="/w/images/8/8c/Supermenu3.png">echo "Hello World"</span> renders to echo "Hello World"
      7. target: This parameter takes a selector of an element in the DOM (id, class, complex selector). If the element is found then CodeSelect will become a button to copy this elements content to clipboard. NOTE: Always be sure to select a specific target where the selector only finds 1 element. Otherwise the first element which is found will be chosen by the algorithm.
        1. Detailed functionality
          1. CodeSelect will be MOVED from its current location in the DOM BELOW the target and inside a helper DIV.
          2. CodeSelect will be in button form, which means it will get the attribute data-button-image-src, but with an empty string (except if this parameter is already specified then this will not be overridden).
          3. CodeSelect will be positioned via CSS over the target element on the top right side.
          4. HIGHLIGHT: Usually the code box of CodeSelect is syntax highlighted. With a target the target gets highlighted instead. This can be prevented by setting the "lang" parameter to "none". NOTE If the target gets highlighted the style of the target might change - for example a pre-element will look more like a code box
          5. Clicking CodeSelect will EITHER select the TEXT content of the target. This is only if the parameter code is NOT GIVEN. OR it will ALWAYS select the content of the code-parameter IF GIVEN. The latter option is optimal for the use case IF the target has some formatting going on and it may be not clear if all browsers will select the text correctly despite the formatting. In this case simply put the correct text into the CodeSelect code and give the element as target. The element's actual content will be ignored in this case.
          6. Clicking on the target element will mark all the text in the target element (but not copy automatically). This mimics the normal behavior of the CodeSelect code area
        2. NOTE: If the target-parameter is used the insertHtmlMode will be ignored (because it's always only text) and the inline parameter will be ignored (because it's positioned and not in the text flow).
        3. Example. Template-call {{CodeSelect|target=#my-codeselect-target-example1}} will render to see below and <span class="code-select" data-target="#my-codeselect-target-example2"></span> will render to see below
This is
example 1
$ sudo apt "example1"
This is
example 2
$ sudo apt "example2"
  1. dev note
    1. CodeSelect is now realized as a jQuery extension. This is availabe after CodeSelect.js has been initialized (see build order in Mediawiki:Build.json
      1. You can call $(selection).codeSelect(action) - with action currently only allowed as 'init'. This will initialized all CodeSelect boxes in the selection. Double initializations are prevented
    2. CodeSelect is semi-dependent on For highlighting functionality CodeSelect depends on Prism, but CodeSelect can run without
      1. Currently the default is bash. If you want to change the default go to MediaWiki:CodeSelect.js and change defaultLang at the top of the file
      2. The standard bash language definition by Prism was modified by us using the extension syntax Prism.languages['bash'] = Prism.languages.extend('bash', { ... } );. The ".extend" function creates a deep copy of the grammar and assigning it to "Prism.languages['your-language']" creates a new grammar, that will be used. We copied the grammar pattern for the "function" construct from the prism.js file and extended it by some other keywords, see MediaWiki:CodeSelect.js for our application and for more information. If you just want to add more keywords go to MediaWiki:CodeSelect.js to the line var highlightBashAdditionalFunctionNames = [...] at the top and add more function names to the array. NOTE: Be sure to NOT set the async (second) parameter to true when using the "highlightElement" function as it may cause errors due to a likely bug in the Prism software
      3. For a download of newer version in the future go to and choose the languages we support (see above). Ask admin how to implement those files.


  • This modal is a tool to conveniently generate URLs to debug the page for developers and also to be transparent about script use for page visitors
  • The user can generate a link where scripts are activated and deactivated. You can de/activate selected scripts. But you can also deactivate all (custom) js or all (custom) css or all js and all css
  • These are the relevant files


  • Here you can see the modal
    • (A) is the CodeSelect-Box where you can copy the generated link
    • (B) is a button where you can directly open the generated link
    • (C) is the navigation. Only if you choose "Select JS" you will see (D) the selection of all current scripts. Otherwise you will deactivate all js/css/js+css
    • (D) If you choose "Select JS" you will see all loaded scripts. Click on them to toggle if they should be active or not. You will see that the CodeSelect box will be immediately updated with the new link. Also the button (B) will be immediately updated according to your selection
  • The modal can be conveniently called like any other miniModal, see #Mini_Modal
    • It's dom-id reference is #debug-via-url-modal

The modal also has a toggle button at the top now which de/actives the cookie nocache with the value true. Clicking this button again will delete the cookie again.

  • The cookie communicates to the server that no server cache shall be sent but the fresh current version


  • In this library there are multiple functions which a dev can use as tools.
  • They are saved to the global object mwDev.tool
  • Relevant file: MediaWiki:DevTools.js

fileRefsToLinks( selector, linkAttr, query )[edit]

  • mwDev.tool.fileRefsToLinks(...) can be called in the console or every other js and css file
  • It goes through a set of elements and its children, checks the textnodes and replaces texts of the nature /Media(W|w)iki:[^\.]+.(js|css)/ with actual links to the pages while keeping the rest of the text intact
  • selector | jQueryCollection | default $("#mw-content-text *") : This is a jQueryCollection of DOM elements. Only selected elements will be transformed. That's a great way to for example just transform the elements inside one DIV by selecting the DIV descendants with an asterisk '*'
  • linkAttr | object | default { target: '_blank' } : All key-value pairs will be transformed to HTML attribute strings and added to the file links
  • query | object | default { action: 'edit' } : All key-value pairs will be transformed to URL query key-value pairs and added to the URL

Donation Panel[edit]


  • Kicksecure and Whonix survive on donations and services we provide. To thank our donors we opened the Donor recognition program. It is a voluntary opt-in program only if requested by the donors. For this page we need cards to appropriately thank our donors. Therefore the template DonorCard was developed.
  • The template has 5 levels which are: xs, s, m, l and xl
  • The cards are designed to be responsive meaning they will take as much space as given
  • To see examples look here: Testpage_Donors
  • Relevant files
    • {{DonorCard |logo=Kicksecure-icon-logo.svg |link=Donors |name=John Doe |range=xs |date=2019-01-01 }}
    • The logo is an optional image representing the donor which is implemented using the [[File:...]] Syntax
    • Using link to a url changes the image to a link image. If link is used then a link indicator image is also inserted to let the user know that the image is clickable
    • The name parameter is mandatory and inserts the donor name or name of organization
    • For range there are 6 options: xs, s, m, l, xl and anon. See how each options looks on Testpage_Donors
    • The date parameter simply outputs the date of the donation

Download Button[edit]

  1. The download button template offers a convinient way to show a graphically pleasing download button
  2. The relevant files are
    1. Widget:Download_Button
    2. MediaWiki:Download_Button.css
    3. MediaWiki:Download_Button.js
  3. Usage call the Widget {{#widget:Download_Button...}} with the following parameters
    1. text | string, mandatory - Visible text on the button
    2. url | string, mandatory - The complete url for the download button
    3. os | string/array, mandatory - Will show all the logos of the named operating systems. Options: linux, windows, osx, qubes, kvm, debian, virtualbox, usb. Multiple logos example: |os=linux|os=windows will generate an array
    4. onion | string - The url for the onion download. Will be generated as an extra HTML element behind download button
    5. addToClass | string, optional - Will be added to class attribute of wrapper
    6. fontsize | string, optional - If present will be added to style attribute of wrapper as style="font-size: {{{fontsize}}};"
    7. targetBlank | boolean, optional, default: false - If true will be filling the target attribute with "_blank"
    8. redirectUrl | string, optional - If set then after clicking Download and after redirectDelay the page will be redirected to the given URL
    9. redirectDelay | number, optional, default: 1000 - The delay in milliseconds to wait after download has been clicked to redirect the page. Only takes effect if parameter redirectUrl is set
  4. NOTE: We tried using a template to track all usage of the Download_Button. Unfortunately this is technically very unfavorable for this use case. Read Widget:Download_Button for further information. To find the uses of Download_Button, type into search #widget:Download_Button


  • EditorAutoBackup is an in-wiki modification (augmentation) of the wikitext editor. It creates an "saved icon" in the top right corner of the wikitext editor software toolbar. When clicked there will be the wikitext shown of the last edit right after save was clicked and right before the form was sent to the server
    • The functionality is based on JavaScript and on the localStorage of the browser
    • When "saved icon" is clicked the data from the editing form will be saved to the browser's localStorage via JavaScript. As long as the browser doesn't delete the localStorage (be careful TorBrowser might do that when closing the browser) the edited wikitext from (only!) the last save will be saved in localStorage
  • The relevant files are


  • EditorFullscreen is an in-wiki modification (augmentation) of the wikitext editor. Instead of working in a small window the editor has the option to click on the green fullscreen icon on the upper right in the editing line of the editor and set the wikitext editor to fullscreen. If the wikitext editor is in fullscreen mode at the same position there will be the shrink item which restores the wikitext editor to its original windowed size
  • Relevant files:


  • The EditorMultiwikiNotice is an addition to edit pages. The user on an edit page will be notified if he is on a [[ Category:MultiWiki ]] page.
    • If this page is on the master wiki (currently the Kicksecure wiki). Then he will be warned to act with caution because these changes will affect all wikis.
    • If the user is on a slave wiki he is discourages to edit on the page and go to the master wiki instead
    • A link to the multi wiki info page and a direct link to the master edit page are also provided
    • The links tor compatible, meaning: If the user uses and onion domain he will be redirected to the master wiki onion domains, if he uses clearnet the clearnet domain he will be redirected to the master wiki clearnet domain.
  • Relevant files:

Editor SaveAndContinue[edit]

  • Editor SaveAndContinue an in-wiki modification (augmentation) of the wikitext editor. It adds a new green button "Save continue" to the form which usually just has a "Save Changes" button. But the standard "Save Changes" button reloads the page and disrupts the workflow. The "Save continue" button saves the form via an AJAX request. After that it shows the resulting page for the editor (person) the check if the page really was successfully saved
  • The relevant files are


  • The important headlines (h1,h2,h3) are enhanced to give the user a better usability experience
  • The edit button is changed from a Text button to an optical button while retaining the original dom structure
  • Also an automatic shareTooltip is added for each important headline, see #Share_Tooltip
  • The Headlines
  • EnhanceHeadlines can be prevented in 2 ways
    • by adding the HTML attribute "data-preventEnhanceHeadlines" to an arbitrary HTML element on the page, e. g. <div data-pageMeta-preventEnhanceHeadlines=""></div> - the content of the attribute is not relevant it can be empty like <div data-pageMeta-preventEnhanceHeadlines></div>. This attribute is just used as a meta control mechanism. If present NO headline on the page will be enhanced
    • or by adding the template Template:PreventEnhanceHeadlines like so {{PreventEnhanceHeadlines}} which renders to <div data-pageMeta-preventEnhanceHeadlines></div> as explained in variant 1
  • The relevant files are

Expand Or Collapse All[edit]

  • The Expand Or Collapse All Button is a conveniance feature to deal with page where there are multiple expand/ collapse buttons
    • This only applies to html elements with the class ".mw-collapsible-text", usually divs. Those already have a toggle (expand / collapse) button for each one individually
    • If the Expand Or Collapse All Button is clicked then all ".mw-collapsible-text" elements will be opened
    • If all ".mw-collapsible-text" are already opened then the "Expand All" button will show "Collapse All" and if clicked all ".mw-collapsible-text" elements will be collapsed
  • Relevant files
  • Usage: {{Expand_or_Collapse_All}}

FlyInNotification Module[edit]

  • It is a delayed notification to show a user special information after a period of time of staying on a Kicksecure page.
  • The widget is dismissable and sets a cookie named flyInBannerIdDismissed which is documented in our Cookie_Policy#Preferences.
  • Shown for JavaScript enabled browsers: Yes. ** Shown for NoScript users: No.
    • A dismissable Fly-In-Notification which is also functional for no-JS (NoScript) enabled browsers is too much effort to implement. It would require a MediaWiki extension / PHP.
  • Relevant files
  • The widget is at the moment wiki wide enabled using Template:Header.
    • If this changes in the future and the devs want to implement it on a page by page basis, it can be implemented by simply adding {{#widget:FlyInNotification}} to any page.
    • In the current implementation the fly-in-notification can be disabled using {{#css:Mediawiki:Hide_flyInNotification.css}} or generally (and usually) by using Template:Hide_all_banners, i.e. by using the usual wiki syntax to include a wiki template: {{hide_all_banners}}
    • It is already disabled on some pages such as Donation related pages and legal related pages.
    • Dev note: If you want to change this behaviour in the future read MediaWiki:Hide_all_banners.css to learn how CSS works in tandem with JavaScript to hide the notification
  • Usage: See Template:Header for an example. The general options of currentCookieId and waitInSeconds and the content are set in the JavaScript file. The widget is currently regarded as globally conform, so there are no page specific options.
    • currentCookieId: The id which is stored in the cookie. The currentCookieId will be compared to the id in the cookie, if it matches widget will not be shown. Suggestion: increment the id in integer steps if you want to show the user the next new notification
    • waitInSeconds: The time to wait until the notification pops up (is shown to the user)
    • content: HTML content which is defined as a structured string in the JavaScript file

Icon Bullet List[edit]

  • Usage
    • call #widget:Icon_Bullet_List
    • parameter item: This parameter is separated into two parts, separated by a comma ",". The first part is the content of the <i class="fas..."></i> class parameter for the Fontawesome image. The second part is the text for the bullet points. HTML elements like <b></b> are permitted.
    • parameter addClass: This parameter is added the the class-attribute of the <ul></ul> parent element for the list. You can use the specific keywords "minimal" and "inverse" (minimal = list is as short as its content, inverse = darker list + white bullet point) or other classes of your liking
    • parameter fontSize determines the font-size of the list as a CSS expression like "13px" or "3em". The whole list sizes with the font-size, so it's looks very good in every fontSize
  • Example
|item=fas fa-check,Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points 
|item=fas fa-minus,Negative Points
  • Resulting in

  • Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points Plus Points
  • Negative Points

  • Example using all parameters
    • NOTE: div with white background just for demonstration purposes. Do not use in production.
<div style="background: white; padding: 10px 20px;">
{{#widget:Icon_Bullet_List|addClass=inverse minimal|fontSize=20px
|item=fas fa-star,Standard
|item=fas fa-check cs-green,Plus Points
|item=fas fa-times cs-red,Negative Points
|item=fas fa-minus cs-yellow,Equal Points
|item=fas fa-check cs-blue,Chill Points
  • Resulting in

  • Standard
  • Plus Points
  • Negative Points
  • Equal Points
  • Chill Points

  • NOTE: The colors of the bullet icons is using our color schemes which you can read about here #Color_schemes

Info Tooltip[edit]

  • Info tooltip is a small element to show a tooltip only by using CSS (nojs compatible)
  • Usage
    • give and element the class 'info-tooltip'
    • hide an element inside which will only be shown when user hovers over info button
    • example <span class="into-tooltip"><span>Here's the hidden info</span></span>
    • result Here's the hidden info
  • Relevant files Mediawiki:Utility.css

Intro paragraph[edit]

  • A template to write multiple paragraphs for the styled intro of a page
    • These paragraphs will be styled as if they were a single box
    • This paragraph is needed for the Extension:Popups, also know as Previews, formerly known as Hovercards because this extension uses the which needs some free unstyled paragraphs at the beginning of a page to generate a content preview
    • This template uses a sophisticated CSS styling to accomplish the intro look while keeping the text as plain paragraphs. This styling works about 95% in all browsers. Only in Firefox there's 5% design flaw because Firefox does not yet support the CSS :has-selector which is needed
  • Relevant files
    • Normal usage where the text is shown {{intro|Your intro text with wikitext and newlines}}
    • hidden=true: Hidden usage where the text is not know. NOTE: The named parameter can be used everywhere as named parameters in Mediawiki do not affect the referencing of unnamed parameters. {{intro|hidden=true|Your intro text with wikitext and newlines}}
    • thumb=[wiki-image-name]: thumb is optinal and gets a name from an image file that is uploaded to the wiki. The thumb will always be hidden not matter if intro is hidden or not. This is because thumb (specifically the thumb for Extension:Popups) is never intended for the user to see. If the page needs a thumb that the user can also see, then the author can insert a regular thumb as these will also work with Extension:Popups. {{intro|hidden=true|thumb=Kicksecure-icon-logo.png|Your intro text with wikitext and newlines}}


  • A Template to show an image left and right a text or the other way round for decorative purposes
  • Recommended to be used as template, but also available as a widget because as a template there are too many limitations, especially for the style-attribute.
  • It is responsive. And once the screen is smaller than 500px the 2 parts will go width 100% and be below each other with a margin under the image
  • Below 500px the image will ALWAYS be ABOVE the text, to keep a consistent look
  • If the text is longer than the image or the image is longer than the text, the smaller one will always be in the middle
  • Relevant files
  • Usage
    • Either tempate {{LeftRightImageText|...}} or widget {{#widget:LeftRightImageText|...}}
    • param |image: The image with should be shown next to the text. NOTE: For this parameter there is a difference between template and widget. In template you simply use the file name for image like "Information-275708-640.png". In the widget you have to use real relative link like "w/images/thumb/7/70/Information-275708-640.png/300px-Information-275708-640.png"
    • param |imagelink: If you want the image to function as a link give |imagelink=your-link-to-image and the image will behave as a link with hover effect. NOTE: For this parameter there is a difference between template and widget if it's an wiki internal link. In template you simply use the page name like "About". In the widget you have to use real relative link like "/wiki/About"
    • param |text: The wikitext (template) or html (widget) which should be shown next to the image
    • param |imageright: If you want to image to be right, use the parameter |imageright=1 then the image will be on the right and the text on the left
    • param |addclass: If you want to add classes to the parent element, use the parameter |addClass=your-classes
      • class promo-style: One specific class for the parent element is "promo-style" which will turn all h3 and p elements to bigger stylized text areas
  • Example template
This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it. 
This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it. 
This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it. 
  • Example widget
This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it. 
This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it. 
This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it. 
  • Result for both
This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it.

This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it.

This is an interesting product. You might want to hear more about it. This is an interesting product. You might want to hear more about it.

Mini Modal[edit]

  1. MiniModal is a modal as a quick way to create lightweight modals
  2. Relevant files are
    1. MediaWiki:MiniModal.js
    2. MediaWiki:MiniModal.css
  3. Usage: implement the modal with this minimal structure <div class="mini-modal" id="your-id-recommended-to-use"></div>
    1. init : MiniModal are lazily initialized when they are shown or hidden (see "show" and "hide"). You can also actively initialize them with $('#your-id-recommended-to-use').miniModal('init'); . A sub div will be created with the underlay and a close button. And the direct content under the .mini-modal div will be moved to the sub-div .content
    2. show / hide : You can programmatically (JavaScript) open the modal with $('#your-id-recommended-to-use').miniModal('show'); and close it with $('#your-id-recommended-to-use').miniModal('hide');
      1. Whenever a modal is opened ("show") the URL will be changed. If not specified otherwise (see "data-url-hash") the url will get a hash-symbol # without any text. This enables the browser to use the back-button to close ("hide") the modal. Whenever the modal is closed the hash-symbol will disappear - including the hash-text if there is any
    3. checkForModalsCalledByHash and data-url-hash : This method can be called on any element, because it's global anyways $(window).miniModal('checkForModalsCalledByHash'); - This will check if any modal has the attribute "data-url-hash" and if this attribute matches the current url-hash. Then this modal is shown. This attribute also forces the url to be changed if the modal is called using the hash sign # plus hash-text. If the attribute is not present the url is changed as described above (see "show/hide")
    4. Events: You can listen to the self-explanatory events $('#your-modal').on('shown.miniModal', fn ); and $('#your-modal').on('hidden.miniModal', fn );

Mini Navigation[edit]

  • Mininav: Mini navigation: Mini navigation is used to have multiple buttons in a row linking to other pages. The outer element must be a <div class="mininav"> the inner element must be a list of elements, for example of links. This will automatically be transformed to the navigation
  • Relevant files: MediaWiki:Mininav.css


 <div class="mininav">
 * [[Homepage]]
 * [[Homepage]]
 * [[Homepage]]

leads to

Non-Responsive Thumbnails classes[edit]

PayViaPaypal module[edit]

  • To offer users to donate via PayPal we offer a form to do so
    • The form is a fully functional PayPal form which combines subscription payment and one time payment by switching input elements (as defined in PayPal's API) according to the user's selection
    • This module is based on JavaScript because PayPal also seems at the moment only fully usable with JavaScript activated
  • Relevant files
  • Usage: To integrate the form into a page simply use <div class="pay-via-paypal-module">[nojs text]</div> and write the text or markup for NoJS users in the div
    • This text will be replaced by the form via JavaScript if JavaScript is activated
    • You can also use "smooth" in the class attribute. This makes the form grow smoothly when it's fully loaded instead of popping into position <div class="pay-via-paypal-module smooth">[nojs text]</div>
    • On any page there can be multiple forms which are each independent of each other

Pre : <pre> and <div class="pre">[edit]

<pre> and <div class="pre"> are two ways to show preformatted code. Both look very similar. The difference is: In pre tags mediawiki does not parse newlines, variables etc, in div.pre it does. So according to usage scenario either pre or div.pre are preferrable

sd-start (currently retired)[edit]


Share Tooltip[edit]

  1. A tooltip menu for copying and sharing a url to various social media
  2. You can insert the template and optionally reference an anchor. The hover menu will offer the user different sharing options
  3. Nojs: These sharing tooltips will not be visible for nojs users
  4. JS active: The span element will be used as a wrapper and filled with a complex menu with sharing options for twitter, facebook etc
  5. Relevant files (MultiWiki)
    1. MediaWiki:ShareTooltip.css
    2. MediaWiki:ShareTooltip.js
  6. dev note
    1. ShareTooltip is realized as a jQuery extension. This is availabe after ShareTooltip.js has been initialized (see build order in Mediawiki:Build.json
    2. You can call $(selection).shareTooltip(action) - with action currently only allowed as 'init'. This will initialized all ShareSelect elements in the selection. Double initializations are prevented
    3. URL parts documentation
      1. The url parts for each target platform are all in an object with an array for each platform with the url parts as strings
      2. The array is iterated in order and normal strings are just statically added to the complete share string
      3. Strings that start with "[if-data-...]" are conditionals that are just rendered to the share string if the data part is truthy, e. g. "[if-data-page] page is " is only rendered if data['page'] is truthy
      4. Strings that start with "[data-...]" are not parsed literally but just taken from the data, e. g. "[data-page]" renders the page. If the page is not given then empty string will be rendered
  1. Usage
    1. the data-anchor parameter anchor is optional, without it the sharing link is the whole page
      1. NOTE: if you use an anchor this anchor (or an element with this id="my-anchor-id") should exist somewhere on this page
      2. If the data-anchor parameter is set (only then) you can also use the data-chapter parameter which will explicitly set the title of the chapter for various sharing options. If not the title will be fetched from the target element (e. g. if it's a headline, then the text) or if this also fails then the anchor id will be transformed by replacing "_" with space
    2. The color of the Share-Button (placeholder for the menu) can be altered with CSS. Between "filter: brightness(0)" (equals black) and "filter: brightness(2)" (equals white) you can make it every color
<span class="share-tooltip" data-anchor="my-anchor-id" data-chapter="My chapter title"></span>


/// Example reference element with id="my-anchor-id" ///

SiteNotice Info and Donation Banners[edit]

  1. The sitenotice is used to communicated current infos to the user. It is used in a very versatile way
  1. Relevant elements
    1. MediaWiki:Boilerplate.css
    2. Template:Hide_all_banners
    3. Template:SitenoticeBanner
    4. Widget:SitenoticeBanner
    5. MediaWiki:Sitenotice
    6. MediaWiki:Sitenotice.css
    7. MediaWiki:Sitenotice.js
    8. MediaWiki:Sitenotice_id
  2. Sitenotice is excluded from search engine indexing via #Exclusion_of_text_parts_from_search_engine_indexing
  3. NoJS: For NoJS users there is no option to close the siteNotice
  4. Update info: In the past there were more rules for sitenotice, but this has change due to the new solution. All rules are given below. Also some more files were important back then, not anymore.
  5. History of solution stack
    1. Previously we used the, but this is no longer the case. We have our own solution which enables the sitenotice to be dismissable
    2. The solution needed to be dismissable. Therefore Javascript was involved
    3. But if dismissed banners are closed by Javascript this is too late if the page is loaded because the page will "jump" and have a bad lighthouse content shift score. Therefore the page is hidden by user cookie which is set to the server on request and rendered as a body class which then hides the cookie immediately. This is done by Dev/mediawiki#Extension_CookieToBodyClass Extension:CookieToBodyClass which our SiteNotice solution therefore is dependent on
      1. If the user dismisses a banner he gets a cookie which is active 1 month and then auto-deletes which shows the banner again
    4. We also needed a way to make banners active and non-active. So we introduced a Template. This template in turn uses the widget because widgets can do some things in mediawiki that templates can't
    5. Then we also needed a possibility to not show a banner if it's expired. That is also implemented
    6. And we needed a way to force new banners upon the user - for example if there is an emergency but the user has dismissed the old banner less than a month ago. Therefore we used Sitenotice_id. If this id is changed then the user cookie will not longer hide the banner and he sees the new one which he might dismiss again
  6. USAGE
    1. You usually only touch MediaWiki:Sitenotice, MediaWiki:Sitenotice_id and occasionally MediaWiki:Sitenotice.css. Everything else is maintained by core developers of this wiki
    2. OPEN MediaWiki:Sitenotice and create a new instance of Template:SitenoticeBanner {{SitenoticeBanner |active=true |html=<img class="full-size" decoding="async" loading="lazy" src="/w/images/7/7d/Banner-dev-wanted-slim.jpg" width="960" height="140" alt="Developer wanted for Kicksecure ISO development"> |href=/wiki/Contribute |expires=16776808891 |id=my-banner-id }}
      1. active=true is necessary. If this parameter is omitted then the banner will not even be rendered
      2. html is optional. But the banner in most cases makes no sense without HTML to fill it
      3. href is optional. If it's given then the html is rendered inside of an a-element with href-attribute as href
      4. expires is optional. This is a UNIX timestamp in seconds. If the banner needs to end on a specific date and the creator does not want to check all of the time this happens automatically and the banner will not even be rendered after this date
      5. id is optional and gives the banner and id-attribute for styling. It is recommended to add the individual styles of a banner to MediaWiki:Sitenotice.css or MediaWiki:LocalSkin.css
    3. Banner visibility is global. If the user has dismissed your banner ALL of your banners will be invisible for one month. If you want to reset the banner visibility go to MediaWiki:Sitenotice_id and change the ID to a new string. Then whichever current banner (seen or not seen) will be visible again for ALL users
    4. Additional JS functionality: If you need special functionality for some banners put them in MediaWiki:Sitenotice.js under "B : Custom Banners Functionality"
    5. Deactivate all banners: If you want to deactivate all banners (including the flyinnotification) just put this template somewhere on the page Template:Hide_all_banners

SiteNotice End Of Year Banner[edit]

  1. The SiteNotice End Of Year Banner is a complex banner for the donation drive at the end of the year
  2. The banner fulfills several requirements: (1) Responsive mobile / desktop (2) Predictable height to prevent content jumping (3) Content as a slideshow (4) Payment gadget always present or one click away (5) Dismissable (by cookie for 1 week) (6) Portable, so it can be loaded on other pages, in this case the forums (7) Customizable so there can be different content on different pages (i. e. Whonix and Kicksecure)
  3. Relevant files:
    1. MediaWiki:Sitenotice_EndOfYear.js
    2. MediaWiki:Sitenotice_EndOfYear.css
    3. MediaWiki:Sitenotice_EndOfYear_LocalWiki.js
  4. The main Javascript file is MediaWiki:Sitenotice_EndOfYear.js. There it provides a function initEndOfYearSitenotice( endOfYearDiv, contentForSlides, donatePageUrl = '/wiki/Donate', isLocalFileSystem = false ) that IS NOT directly executed.
    1. endOfYearDiv needs to be a jquery dom element or a valid CSS selector. It's the element where this whole banner gadget will be prepended (added to the front)
    2. contentForSlides needs to be an HTML-String which will then be added to the banner.
      1. Every slide (direct child) should be a div element to contain your slide content. This is individual content fitting the current wiki.
      2. Crypto: You will have to have an element in your string (e. g. div) which (1) has the attribute data-crypto-addresses (2) is a JSON string (3) and has the keys "payBitcoin", "payMonero" and "payEthereum" with the right addresses as string-values.
      3. Title: If you add an h1-element (also a child, use of HTML inside the h1 is allowed) then this will be used as the title of the end of year sitenotice being displayed at the top. If you don't use an h1-element here then there will be a generic title
    3. donatePageUrl, e. g. "", is the URL where the donate button or "More payment options" button lead the user.
    4. isLocalFileSystem (boolean) indicated if this function is run locally for example on the Kicksecure local browser page. If true then localStorage will be used by Javascript to save when the user dismissed the donation banner
  5. In MediaWiki:Sitenotice_EndOfYear.css the styles are defined.
  6. In MediaWiki:Sitenotice_EndOfYear_LocalWiki.js the function initEndOfYearSitenotice(...) is called. This must be done for each wiki individually. This is also usually where the content is stored.
  7. When clicking dismiss a data entry into "localStorage" is written with the current date plus 7 days. Before that time the banner will not be shown again. After that time, the banner will be shown again and the data entry will be deleted
  8. History: This functionality was originally using Ajax Calls to get the content. But this was too slow, so all content is stored in MediaWiki:Sitenotice_EndOfYear_LocalWiki.js now
  9. For more information how our banners work read #SiteNotice_Info_and_Donation_Banners. The end of year banner uses the expiration functionality and dismiss functionality from sitenotice.
  10. NOTE: If this banner is not in use please deactivate the three files MediaWiki:Sitenotice_EndOfYear.js, MediaWiki:Sitenotice_EndOfYear.css, MediaWiki:Sitenotice_EndOfYear_LocalWiki.js in MediaWiki:Build.json by commenting them our using "//" as described in the Build file itself. Then run mw-combine.php. Deactivating these files saves bandwidth for the user.


  1. This template creates a context based link to a subdomain of the wiki project. Works only for the official wiki clearnet and onion domains.
    1. Problem: normally it is optimal to use relative links. This is not possible for subdomains here. But to redirect with an absolute link to a subdomain poses the problem if there are multiple domains for the same website like with whonix where there is also an .onion domain
    2. This template solves the problem by automatically analysing the context (which domain the user is on) and creating the link automatically based on the context
  2. The files which are used, are
    1. Template:Subdomain_link - only this template should be used by editors
    2. Widget:Subdomain_link - this widget should only be edited by devs
  3. Parameters
    1. text | string, default: "" - the text you want to display in your link
    2. sub | string, default: "" - the subdomain without any special character. If you want, use "forums"
    3. append | string, default: "" - an addition to the link after the domain. Always start with slash "/". Example: "/thread/12387" → ""
    4. result | string, standard: "link" - determines what the widget returns. Options (A) link - then an a-hyperlink will be created (B) url - then only the final url will be created (C) parts - then a string will be created. First part protocol "http", the comma, then "doamin", example: "https,"
    5. testingcontext | string, default: "" - give an alternative testing context url to test this template. Parameter remains in production version of this template because there are sophisticated RegExp terms used and for later development and demonstration purposes this is highly useful

Tab Content Controller[edit]

  • Introduces a tab controller to conveniently show content as tabbed content areas
  • Uses #Mini_Navigation as an auto-generated navbar
  • For nojs visitors the content is plainly and fully shown without any navigation
  • Relevant files
  • Usage
    • create a div with the class "tab-content-controller" and the attribute "data-tcc-id"
    • create as many divs (or other elements) with the attribute "data-tcc-id" and the attribute "data-tcc-title" and the attribute "data-tcc-image". Title and image are optional, but if both are missing the tab will be empty confusingly have no indicator.
    • if JS is active then all the elements with the same attribute content of the "data-tcc-id" as the controller will be fetched to the controller and a navigation (Mininav) will be automatically generated with the titles given in "data-tcc-title" and the images given in "data-tcc-image"
    • NOTE Normally images given in "data-tcc-image" will displayed with a height of 25px (if you don't style otherwise). Keep that in mind to load small images to save bandwidth
    • If a content element shall be pre-selected give that element the class "active". If this is not done then the first element will be selected
    • NOTE If you don't have an element pre-selected then a content shift will appear because all elements will be hidden for the users until the JS is loaded. If an element has the class "active" however then it will be always be shown and content shift will not appear
  • Example (class info-box is just used for styling candy)
<div class="tab-content-controller" data-tcc-id="my-test-1"></div>
<div class="info-box" data-tcc-id="my-test-1" data-tcc-title="Number 1">1 Content division number 1</div>
<div class="info-box active" data-tcc-id="my-test-1" data-tcc-title="Number 2">22 Content division number 2</div>
<div class="info-box" data-tcc-id="my-test-1" data-tcc-title="Number 3" data-tcc-image="/w/images/thumb/0/0f/Logo-linux-500x500.png/25px-Logo-linux-500x500.png">333 Content division number 3</div>
1 Content division number 1
22 Content division number 2
333 Content division number 3

Tables with oversize, ScrollableIndicator[edit]

  • Tables with oversize: Tables are sometimes too long for viewing on mobile devices. This makes the whole content scrollable to the right. To prevent this editors can wrap the whole table in <div class="scroll-table"><table>...</table></div> . This makes only the table scrollable, but not the whole document.
  • ScrollableIndicator: This tool is realized by Mediawiki:ScrollableIndicator.js. For mobile devices it is sometimes not clear if a table is too long to short and therefore scrollable. If ScrollableIndicator is active (JavaScript needs to be active) then the tables gets a special class "scroll-overflow-indicator" which gives it a style so mobile users know they can scroll. Caution: This only works on div-elements with the class "scroll-table", but there automatically
  • ScrollableIndicator will not be shown on desktop devices, only those with a mobile userAgent

TOC Level Switcher[edit]

Table of Contents Level Switcher wiki button

Figure: Table of Contents Level Switcher


  1. There is a lot of content on this wiki and there are many headlines on one page. So the table of contents (toc) is sometimes very overwhelming. To improve this experience for the user we created a JavaScript augmentation for the TOC
  2. 3 Buttons are added right of the TOC where you can use the star and show all levels (standard) or click "2" to just show the top 2 levels or click "1" to just show the top level. You can open the levels by using the plus button. And you can see how many children one level has by the number in the brackets on the right. Levels with 0 children will have no plus button to open them
  3. The TOC is not shown at all if there is no level 2 headlines, because then the TOC could do nothing. If there is no level 3 headlines then the "Show level 2" button is not shown for the same reason
  4. TOC level switcher saves your choice to a cookie. But only if you make a choice that is not "all" (wiki default, asterisk symbol)
    1. So if you're someone who always likes to just get the top headlines this will help improve your experience across all pages.
    2. If you want to delete your choice and the whole data point completely from cookie just click the asterisk icon and the cookie will be wiped completely
  5. This feature is #MultiWiki and the relevant files are
    1. MediaWiki:TocLevelSwitcher.css
    2. MediaWiki:TocLevelSwitcher.js
  6. NOTE: This feature is dependent on the #Extension_CookieToBodyClass

USAGE : CSS Design Documentation (Alphabetical order)[edit]

Col Container[edit]

  • The class .col-container is a functional wrapper to have elements equal items in a horizontal list
  • The class .cc-3 (only works in combination with .col-container) defines a horizontal list with 3 columns
  • The used CSS technique is display:flex;
  • Defined in Mediawiki:Utility.css

Color schemes[edit]

  • There are 4 double color schemes available for usage in different contexts to your liking. Classes:
    • cs-red, cs-red-light
    • cs-green, cs-green-light
    • cs-blue, cs-blue-light
    • cs-yellow, cs-yellow-light
  • Usage: Simply add one of the 8 classes to a class-attribute in an html element of your choice
  • They affect background-color and color
  • They are defined in Mediawiki:Boilerplate.css

Columns: use-2-columns, use-3-columns[edit]

  • These classes can be used on any element, which has display:block or something similar. The content of the element will be automatically grouped in 2 or 3 columns, separated by lines between them.
    • Note that under a certain page with the class will produce only 2 columns or 1 column to be responsive for mobile devices
  • additional class "strict-list-columns" : If the parent element with the class "use-2-columns" or "use-3-columns" also gets the class "strict-list-columns" then lists ul/ol will be kept together in 1 column. This can be broken by inserting <div></div> into a list to break it cleanly into two and let those 2 lists be in different columns
  • sub class "keep-together" : This class can only be effectively used under the "use-2-columns" or "use-3-columns" class. Usually without "keep-together" the 3 columns will be automatically reorganized to occupy as little vertical space as possible. Thereby it will separate line which is sometimes not desirable. To keep lines together wrap them in a span with class "keep together". Example
<div class="use-3-columns">
<li>List element 1</li>
<li><span class="keep-together">List element 2</span></li>

Example 2 in a Template with "strict-list-columns"

<div class="use-3-columns strict-list-columns">
* List element 1
* List element 2
* List element 3
* List element 4

General utiliy style classes[edit]

Special classes are generic classes that are applicable to various html elements. Relevant file mostly MediaWiki:Utility.css

  • class "width-100" : an element gets the style width:100%
  • class "text-align-center" : an element gets the style text-align:center
  • class "vertical-align-middle" : an element gets the style vertical-align:middle
  • class "margin-left-5" (margin-right/top/bottom-0/5/10/20) : adds margin 0, 5, 10 or 20 px in any direction to an element
  • class "vspacer-10" (-0/1/2/3/4/5/10/20/30/50) : block element with no float and 100% width and the given height to make a vertical gap (vspacer = vertical spacer)
  • class "pos-1px-up" (pos-1px/2px/3px-up/down) : positions the element relative and moves it up or down 1, 2 or 3 pixels
  • class "fontsize19" (19/21) : Gives the element font-size: 19px

hide-enlarge and thumb-hide-enlarge class[edit]

  • A thumb image will usually have an enlarge Button to show the images in full. This is sometimes not desirable. But thumb is sometimes the only useful image option (see #Images, Files and usage of thumb). Therefore thumb can be augmented with one of 2 classes hide-enlarge and thumb-hide-enlarge.
  • thumb-hide-enlarge is the general purpose solution for all thumbnails. Simple wrap a division with the class "thumb-hide-enlarge" around the thumbnail
    • example: <div class="thumb-hide-enlarge">[[File:Swift 128.png|thumb|100px|link=|SWIFT]]</div>
    • The enlarge button will be hidden. And the image description text will be centered
  • The second option is a shortcut but only works on thumbnails without the link parameter. You can add the class parameter with the value hide-enlarge to the File-tag
    • example: [[File:Swift 128.png|thumb|100px|link=|class=hide-enlarge|SWIFT]]
    • The effect is the same as with the wrapper

info-box class[edit]

  • used for container elements to give them rounded borders, a white background and a shadow
  • it is used in the Template Box, see: #Box_and_MBox
  • There is a special class "ib-for-thumb". Read about it in #Box_and_MBox

intro-p Intro Paragraph class [DEPRECATED][edit]

    • In the past it was used for an intro paragraph at the box of the page, but can also be used elsewhere to highlight text
    • Allowed secondary usage in the past: <div class="intro-p">Here is your intro-text</div>
  • Now you should always use the template #Intro_paragraph

NoJS classes[edit]

  • The site is generally NoJS compatible. However for JavaScript (JS) users we offer some JS features to make the visit more comfortable.
    • The JS enhanced elements work without JS, but with JS they have full functionality.
  • IMPLEMENTATION: For no-JS users we have special styles which are only applied if the user has JS deactivated
    • These styles make use of the Mediawiki classes "client-nojs" and "client-js" in the <html> top element. These classes are not added via Javascript but on the server-side which prevents content shift and makes it a very good solution
    • In Mediawiki:Utility.css there are also some style for NoJS
    1. We introduced new classes to show content specifically for NoJS or JS users. These classes are
      • .show-for-nojs-only: show content only if the user has no JS activated
      • .show-for-js-only: show content only if the user has JS activated
      • .hide-for-nojs-only: hide content only if the user has no JS activated
      • .hide-for-js-only: hide content only if the user has JS activated
      • Example: <div class="show-for-nojs-only">Text is only show when JS is not active</div>
    2. On the CSS side you can use html.client-nojs .your-element {...} to style it for nojs users or html.client-js .your-element {...} to style it for js users

"NoScript" browser extension: Special style fixes[edit]

USAGE : Server Scripts[edit]

Images Export Import[edit]

There are two different scripts on the server.

  • images-download-from-kicksecure
  • images-download-from-whonix

This was last tested in March 2022 and worked great.

Currently broken due to upstream bug: grabFiles.php broken in MediaWiki 1.38 due to MediaWiki API

Images Export Implementation Details[edit]

Not important. Only for interested readers.

Implemented using The following commands would need to be adjusted and executed on the server.

sudo -u www-data php mediawiki-tools-grabbers/grabFiles.php --url
sudo -u www-data php mediawiki-tools-grabbers/grabFiles.php --url

Rejected tasks[edit]

The following tasks have been considered for realization but have been rejected due to the contra arguments.

Minify HTML for wiki.min.js (2023-02-13)[edit]

TODO: discuss


  • Even the main wiki document (, Main_Page, About, FAQ, all pages) has non-minified HTML.
  • Improvement is possible in theory (nginx module pagespeed but currently doesn't seem under active maintenance).
  • JS loads slow, with fetchpriority=low anyhow and is deferred. Therefore file sizes and CPU speed should be neglible.
  • Speed test websites do not suggest to minify HTML.
  • MediaWiki performance team doesn't think it helps:

MediaWiki Special Pages CSS Enhancements[edit]

  • There was an issue that the text logo (vertically long) broke MediaWiki special pages because the logo was too long.
  • There is a solution to create a localWiki CSS file where these types of corrections for wikis are made but not globally (MulitWiki) but locally. This file would have to be referenced in mw-combine.
  • Admin rejected this idea due to complexity and uploads another image instead

MediaWiki Clean vs Unclean Links[edit]

Magic Variables Clearnet/Onion[edit]

  • introduce our own magic variables, especially one to differentiate in templates and widgets between clearnet-request and onion-request
    • This is especially useful in cases where a different link needs to be shown depending if it's onion or clearnet. And if that link is not relative
    • Then give task to dev, so he can fix VirtualBox/XFCE and remove onion extra link
  • Cumbersome to implement and not that important because there are separate onion download links.

Expand Button new[edit]

  • usually expand areas are created with .mw-collapsible and .mw-collapsible-content
    • But this is a JavaScript solution and does not work for nojs users. For them the area is automatically expanded
  • A new solution would be to create a widget which creates and expand container and button and content area
    • This solution uses checkboxes for nojs users and a js solution for JavaScript users
  • A second widget might me "Expand All / Collapse all button, like on page Documentation
    • For nojs users this might also be a checkbox which works in tandem with the other new widget for Expand buttons
      • A challenge might be that the Expand all checkbox always has to be on the same level as all parent elements of the lower level expand buttons
  • An alternative variant to the Expand all button might be to introduce a parameter to the expand button widget like "nojsexpanded" where the behavior is like with the current mw-collapsible solution and all areas are expanded if JavaScript is not active

Sitenotice no-JS Version[edit]

  • The Sitenotice usually is not dismissable by the user
  • We use Extension:DismissableSiteNotice so the user can click away the Sitenotce
  • But the extension has a big flaw. On line 55 to 75 (see [git of the]) you can see the dev delivers the sitenotice via JavaScript
    • This means the sitenotice is not even visible if the user has JavaScript deactivated.
    • This is not desired behaviour. We want every user to see the notice. And JS users just have the additional luxury of being able to dismiss the sitenotice
  • Solution suggestion
    1. We deactivate Extension:DismissableSiteNotice, because the JavaScript way was a deliberate choice of the dev, so even if we can fix the extension the dev very likely won't accept our solution upstream
    2. Without the extension the Sitenotice will be there for every user.
    3. We write a JavaScript file to make Sitenotice dismissable which saves this info into a cookie similar to Extension:DismissableSiteNotice, so only JS users have the comfort to dismiss a Sitenotice

Patrick said:

CodeSelect Show Copy Contents Feature[edit]

  • pro
    • Would it be possible, and make sense to shop a popup what exactly has been copied to clipboard?
    • Maybe useful for the new donation widget?
    • Maybe useful generally, globally?
  • contra
    • In probably 99.9% of cases the user will immediately insert the contents they just copied into another form or programm. Therefore he will see the full copied content immediately afterwards anyways. So this might be superfluous

pay what you can for donate panel[edit]

  • pro
    • does it
  • contra
    • Confusing for users which might wonder:
      • Do I get the same version if I choose 0?
      • Seems like this cannot be downloaded for free.

External Redirections Enhancements[edit]

status: wait

Waiting for new magic words mediawiki extension. improvements

example external redirect:

  • solution?
    • Can we change
    • {{#externalredirect:}}
    • to
    • {{#externalredirect: {{kicksecure_clearnet_or_onion}}/wiki/OpenPGP}}
    • ?
  • goals:
    • protocol handler respecting redirect.
      • redirect Whonix ™ https visitors to Kicksecure ™ https
      • redirect Whonix ™ onion visitors to Kicksecure ™ onion
  • notices:
    • title: Redirection
    • "You are being redirected. Will redirect in 5 seconds to Kicksecure ™ website."
    • "Whonix ™ is based on Kicksecure ™"

mininav CSS Improvement[edit]

  • pro
    • The style for example on A) USB_Installation "table abuse" looks a bit nicer than mininav for example B) Dev/website.
    • "table abuse" is shows all navigation options in the same line on mobile which is great.
    • "table abuse" has a nicer border?
    • "table abuse" has a nicer background color?
    • mininav splits it into multiple lines below each other which is non-ideal.
  • contra
    • mininav is designed with modern standards and especially mobile devices in mind
    • the bottom border indicated like with tabs where the user is at
    • the tabs can be on one line or multiple lines and are therefore responsive
    • the design is subtle and nice and integrates with the rest of the visual language (gray background for code, but white for functional elements of the website)

Maybe Future TODO[edit]

MediaWiki:Page_Homepage.css Question[edit]

Only a question.

Could MediaWiki:Page_Homepage.css be embedded inline into widget:Page_Homepage? Good idea?

Reason: Potential website speed improvement?

Would get rid of (the only call to index.php), would get rid of 1 additional file to download.

Might not be needed if nginx server side PHP caching speeds this up.


  • Yes, Page_Homepage.css could be embedded
    • Pro: That would improve parallel loading (because the CSS is there earlier). Speed COULD therefore improve a little bit
    • Con: But that would inflate the page even more (which would also negatively impact the PageSpeed "Dom is too large" warning
  • Alternative idea: Load the script directly from /mw-autogen/src-copy folder. This needs some small tweaks, probably in Build.json and/or mw-combine, but might be reasonably quick

Whonix Homepage Video[edit]

simplify noJS version[edit]

For the more beautiful, feature-rich implementation related to all of these video tasks, would it help if the noJS version would be further simplified?

Potentially acceptable for the homepage noJS version:

  • just show the illustrative image
  • direct link to the video
  • video download link
  • could offer many different quality / size versions
  • YouTube link
  • no need to play inside the homepage

Separate JS version[edit]

Should we add a more pretty video player if JS is available?

The HTML5 player is nice for noJS but has some probably unfixable issues. When playing the video over a slow connection (slow internet; Tor; onion) it starts, is then stuck, loads, play again. That is not very useful. This leads missing the hear the first few seconds of the video and no bearable video experience. Hence above chapter "simplify noJS version".

If we decide to use a JS based video player... Is there a video player for slow connections that

  • can buffer the first 10-20 seconds or so?
  • lower the video quality?

Streaming Protocols - RTSP RTSPS HLS[edit]

What we want is "VOA" - "video on demand". Only playing simple videos. No live streaming.

For adaptive bitrate streaming (lowering the video resolution and quality over slow connections), the server would need to support RTSP (actually RTSPS for better security) and HLS? Patrick did preliminary research and thinks its doable.

research video players[edit]


  • must be Open Source
  • installed to or so (not fetching from third parties such as jsDelivr)
  • can be JS based
  • with HTML5 only (noJS) features are probably limited and no players available?
  • avoid NPM (seems very pretty much doable, players that Patrick has seen are deployed as a single JS file. Trivial to install on the server.)

feature wish list:

  • remember video playback position after reload
  • see also requested features above

review todo:

lazy load player[edit]

If we use a JS based video player, should it be lazy loaded to avoid increasing load times for normal visits?

CSS restyle html5 video controls[edit]

  • Controls always visible because otherwise just a big black area that looks broken over slow connections
  • add additional buttons


remember video playback position after reload[edit]

video gallery[edit]

Would it make sense to add a video gallery / switcher using arrows so users can watch the other two Whonix explainer videos too?


MediaWiki Logo HTTP2 Server Push Preload[edit]

MediaWiki by upstream default sends a response header which does a HTTP/2 Server Push. Example:

link: </w/images/2/2a/Kicksecure-text-logo.svg?b0edc>;rel=preload;as=image

Not on the main HTML document but for the CSS load.php. Example:

MediaWiki by upstream default uses the $wgLogos configuration variable to determine the link to the logo.

However, the hash ?b0edc is auto generated by MediaWiki and after a cursory look at the source code it seems this cannot be disabled.

This causes the following warning with our custom skin:

The resource was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.

This is because it does not know the hash ?b0edc.

HTTP2 Server Push is being deprecated by upstream browsers:


session cache disable[edit]

In case there are login issues, the following could be attempted:$


Notes by Patrick[edit]


Entry point is always MediaWiki:Common.js?

Dev: Common.js has been transformed into a standalone library and is therefore now marked as Multiwiki. Common.js now imports MediaWiki:ImportScripts.js which is NOT MultiWiki. This is done so Common.js is a true library and ImportScripts is now LocalWiki specific and there can be individual imports. Note: ImportScripts is loaded at the bottom of the file for call order reasons, therefore every loaded file will have the wikiJsLoader already available.

To disable all, remove all from MediaWiki:Common.js?

Dev: To disable all remove the following line at the bottom of Common.js

mw.loader.load( '/w/index.php?title=MediaWiki:ImportScripts.js&action=raw&ctype=text/javascript' );

What if in the future 1 script breaks? Do all scripts break?

Dev: The wikiJsLoader is totally independent and optional to use. You can call scripts the usual way as before. But now you also have the option to call scripts dependent on each other by using wikiJsLoader. If 1 script breaks this will only affect the script itself and all scripts which are made dependent on this script by using wikiJsLoader. But if those scripts are dependent on a broken script you will have to fix this script anyways to get those scripts running again.

Does a unloadable script show an error in the browser console?

Dev: No. This is because all scripts are loaded asynchronously and the loader is specifically built to load a script only when it is ready. However we could use a timer and show all unloaded scripts after 3 seconds, because it should never take this long to load all the scripts. Or we could write an internal log, which can be called to list all actions by the loader.

What is window.?

Dev: Window is a JS Object representing the browser window. It is always available and represents the "global namespace" where all global objects are referenced.

How can I manually debug, execute MediaWiki:MiniModal.js, MediaWiki:Footer.js, MediaWiki:CodeSelect.js?

Dev: You can manually load as usual

mw.loader.load( '/w/index.php?title=MediaWiki:MiniModal.js&action=raw&ctype=text/javascript' );

Dev: Or you can use the wikiJsLoader as follows. This is only needed recommended for scripts which are dependent on others.

window.wikiJsLoader.register( 'MiniModal', [], false, function() { ... });

window.wikiJsLoader.exec( ['MiniModal'] );

How to print a debug message with variable name and content to browser console?

Dev: A convenient way is to use console

var whateverYouWantVariable = "String or Object or Boolean or a system variable whatever"; "whateverYouWantVariable: ", whateverYouWantVariable );


No longer in use.

load.php caching[edit]

load.php debug mode[edit]

?pagespeed has no effect on CSS or JavaScript loads

  • debug=true

49 JS 12 CSS

  • debug=false

26 JS 1 CSS

instead of


we have

  • load.php?[...]modulename.namespace.tool
  • load.php?[...]modulename.namespace.tool2
  • load.php?[...]modulename.namespace.tool3
  • load.php?[...]differentmodule.tool

Old CSS Checklist[edit]

These are actually done but written as if they are not done:

  • On for example FAQ the long title Frequently Asked Questions - Whonix ™ FAQ breaks the layout on mobile. Because the title is too long, one has to scroll to the right side on mobile to read the title in full. Does the title miss some attribute such as "autowrap", "break line if too long"?
  • Images for example on Main_Page and About are not response rendered smaller on mobile.
  • blockquotes don't really look like a quote. example:


  • beautify breadcrumbs (zB < dev on top of this page)

Wiki Js Loader[edit]

  1. As per now our research shows no option of the MediaWiki mw.loader API to load our own scripts and make them dependent on each other. So user script dependency does not seem to be supported
  2. Therefore we created our own resource loader under window.wikiJsLoader, see MediaWiki:Common.js. The challenge is to provide a mechanism to load modules which are yet unknown and which can only be known once they are loaded and registered due to the asynchronous loading by mw.loader.load
    1. Caution: Circular dependencies are not resolved and will be a roadblock for all batches containing these.
  3. The loader offers 4 methods
    1. register( name, dependencies, waitForCallback, fn ) - This method registers a function (fn,type:function) in the registry, including its module name (name,type:string), its dependencies (depedencies,type:array-of-strings, other user module names) and if the whole mechanism should wait for their callback (waitForCallback,type:boolean)
      1. The function fn will get the following parameters: fn(global, callback). global is the getter-setter described below.
      2. If waitForCallback is true then the registration will not be considered complete until the callback (calback,type:function) is called via callback()
    2. config( key, value ) - sets a wiki js loader configuration. Currently there is only debug (boolean), if true then all outputs will be shonw, not only warnings and errors
    3. global( key, value ) - getter-setter. If only key (type:string) is given then the value will be returned. If key and value are given, then key will be set with value
    4. exec( moduleNames ) - sets in motion the loading process. moduleNames (type:array-of-strings) are names of our dev scripts which shall be called and executed.
      1. First all depedencies will be checked, if they are not met then the script will not execute futher. But if another register process is completed then load will automatically be triggered again to check if NOW all dependencies are met and we can execute further
      2. This way scripts will be able to execute exactly when their dependencies are met, not earlier. This is especially necessary as the mw.loader seems to load our scripts asynchronously
  4. This feature is #MultiWiki and the relevant files are
    1. MediaWiki:Common.js

Wiki Js Loader Usage[edit]

1. All JS files which either have dependencies or are dependencies for others should be wrapped into window.wikiJsLoader.register( 'NameOfThisFileWithoutDotJs', ['ModuleDepedency1','ModuleDepedency1'], false, function() { ... });

2. All other files can be implemented as usual

3. All JS files (including with dependencies) can be called via mw.loader.load(...) as usual

4. To actually execute the managed scripts, use the following. This can be used to execute multiple batches of files or just one big batch window.wikiJsLoader.exec( [ 'NameOfThisFileWithoutDotJs1', 'NameOfThisFileWithoutDotJs2' ] );

Wiki Js Loader Debugging[edit]

MediaWiki Gadgets Extension[edit]

It's been decided not to port to MediaWiki Gadgets. The wiki now now extended as per the mechanisms documented above.

Archived notes:

Unfinished: This wiki is a work in progress. Please do not report broken links until this notice is removed, use Search Engines First and contribute improving this wiki.