{{Header}} __NOINDEX__
{{title|
title=Documentation for {{project_name_long}} Wiki Devs
}}
{{#seo:may
|description=Layout, Skin, CSS, JavaScript, Links, Header, Footer, CodeSelect, Mobile Frontend, Miscellaneous
}}
{{devwiki}}
{{intro|
Layout, Skin, CSS, JavaScript, Links, Header, Footer, CodeSelect, Mobile Frontend, Miscellaneous
}}
= Getting Started - MediaWiki Setup (meta) =
* This documentation is meant for developers helping with the maintenance and improvement of this wiki. Editors please read [[Dev/wiki]] instead.
* This Wiki is a MediaWiki instance. We use a MediaWiki standard, stable installation, which is held up-to-date.
** Why did we choose MediaWiki: [[Dev/About_Infrastructure#MediaWiki]]
* Icons: We use Font-Awesome, locally hosted https://www.{{project_clearnet}}/libs/Font-Awesome/
* Font: We use Roboto, locally hosted https://www.{{project_clearnet}}/libs/Roboto/
== Extension CSS Fork ==
* We use the MediaWiki [https://www.mediawiki.org/wiki/Extension:CSS Extension:CSS], but a [https://github.com/adrelanos/mediawiki-extensions-CSS fork] 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
. 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 - locally hosted''': You can reference locally hosted files, e. g.
. '''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
actually (relatively) references the local file /mw-autogen/src-copy/Page_Homepage.min.css
*** '''NOTE''': Please ALWAYS use the postfix
. This ensures that files are always loaded in their currect up-to-date version
** '''Usage option 2 - from the DB''': You can reference files hosted in the DB, e.g.
. 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
** '''[Generally deprecated] Usage option 3 - inline''': ''[This option should only be used for testing or specific use cases where an interaction with wiki content like templates is strictly necessary]'' You can write inline code, e.g.
. Our fork implements this as a style-tag (instead of a link tag with base64 like the original extension, see above)
* MediaWiki upstream: [https://phabricator.wikimedia.org/tag/mediawiki-extensions-css/ mediawiki-extension-css] feature requests and patches:
** feature request: [https://phabricator.wikimedia.org/T300704 Enable unsanitized CSS namespaces]
** patch / pull request: [https://phabricator.wikimedia.org/T37820 Some CSS stripped by MediaWiki parser CSS sanitizer]
** feature request: [https://phabricator.wikimedia.org/T329615 MediaWiki-extensions-CSS: minify CSS]
== Extension HeadScript ==
* We use the MediaWiki [https://www.mediawiki.org/wiki/Extension:HeadScript Extension:HeadScript] 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
* See the bottom of this chapter for a current snapshot of the content that we include via Headscript
* '''Solved by this'''
*# Font-Awesome is included that way
*# Other libraries are included
*# Our general minified css included
*# Our general minified JavaScript included
*# Our favicon is included
*# MediaWiki Common.js dependent and core JS dependent scripts and libraries are triggered
* '''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
** Wiki page
: The actual url page name for the wiki page. This variable can be used in the script
** 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
{{Collapsible
|title=Current snapshot of the content that we include via Headscript
|smallTitle=true
|content=
}} === Fonts === * 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: https://www.debugbear.com/blog/rel-preload-problems
** 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.
* '''No hsversion''': All files called in Headscript usually have a headscript version number (exact parameter hsversion_from_server_replacement_unixtime
) added to the URL so it can be controlled when the user browser has should fetch the files again so the user is up-to-date with the most recent file versions.
** However FontAwesome loads its webfonts via the CSS file already. So if the URL for the font-preloading that we're doing is not the same URL as in the CSS then the webfont file is loaded twice which negatively impacts performance. This was the case previously as we were using the headscript version number, because the CSS file references the webfont without a headscript version number. And this cannot be changed.
** So now we '''removed the headscript version number from all fonts''' and the double loading bug is fixed.
** We also '''changed the FontAwesome folder name and the other font folder names to include the a date when we added them'''. This way when a new version is available the folder can be changed reflecting the then-current date and the user browser will fetch the newest version
== BUILD: File auto-generation, Combine, Minify, Host Locally, mw-autogen, src-copy ==
# We use [[#Extension HeadScript]] to include our own auto-generated files in the wiki page
# These files are generated from our repository files, through a specific process using our own scripts
## We created the file {{CustomRepo|alt=/tree/master/mediawiki-shared/build config-build-(shared and specific).json}}. In this file we describe a build order for all JavaScript files. And also for 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 "//"
## Then we created a php build script which has to be executed and combines all files which are mentioned in {{CustomRepo|alt=/tree/master/mediawiki-shared/build config-build-(shared and specific).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.
## 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
## 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]
# specific locations
#* Kicksecure autogen folder : https://www.kicksecure.com/mw-autogen
#* Whonix autogen folder : https://www.whonix.org/mw-autogen
#* Kicksecure combine script : {{CodeSelect|inline=true|code=https://admin.kicksecure.com/mw-combine.php}} (Admin access needed)
#* Whonix combine script : {{CodeSelect|inline=true|code=https://admin.whonix.org/mw-combine.php}} (Admin access needed)
# 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
# '''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
=== build.sh, build-mw-combine.php, deploy-to-servers-or-locally.sh ===
* '''The build process explained'''
** '''On the server'''
**# First the server pulls the current state of the mediawiki-customized-dist
repository.
**# build.sh
is called. This script determines on which server it is executed and calls build-mw-combine.php with this information as its first parameter (currently: kicksecure
or whonix
)
**# build-mw-combine.php
reads all source files and renders them into the autogen-src-copy-folder
and combines them into minified files and writes them to the autogen-folder
. Furthermore a log file is written
** '''For the local dev'''
**# Local dev calls deploy-to-servers-or-locally.sh
**## This script first prompt if he wants to use a local path. If so then the build.sh
is called with the local path and renders the files (like described above) for every keyword available currently: kicksecure
or whonix
). The script ends then. No git or server actions are performed.
**## If dev does not give a local path then git actions are performed (checking if up-to-date etc). Then dev is prompted for a commit message (empty=exit) and current changes are committed and pushed.
**# Finally request-servers-to-fetch-and-deploy.sh
is called with user credentials for kicksecure and whonix to trigger both servers to update. All urls, paths and credentials are secret to protect server security and are located in a file called secrets-for-request-servers-to-fetch-and-deploy.sh
.
**## On the server the process is as described above.
* '''Files specifically'''
** Build files to study: {{CustomRepo|alt=/tree/master/mediawiki-shared/build}}
** build.sh
is a wrapper for build-mw-combine.php that tests the needed commands, checks or constructs paths and calls mw-combine for all needed keywords. It is used by the servers to render the combined production files and by the local dev for the same purpose locally as well
*** '''Parameter 1 (basePath), optional''': This parameter represents a base path for where the rendered combined productions files are written
** build-mw-combine.php
is called by build.sh to perform its core purpose while doing the heavy lifting in more feature rich PHP
*** '''Parameter 1 (server keyword), optional, default:'kicksecure'''': This parameter represents they keyword for which server this script is executed on to fetch the correct source files for this specific server
*** '''Parameter 2 (basePath), optional, default:[emptyString]''': This parameter represents a base path for where the rendered combined productions files are written. This path is used as a prefix to all rendering paths
** config-build-kicksecure.json
and config-build-shared.json
and config-build-whonix.json
are the config files for the build process. They have an equal structure. More info on these files here [[Dev/mediawiki#BUILD:_File_auto-generation.2C_Combine.2C_Minify.2C_Host_Locally.2C_mw-autogen.2C_src-copy|BUILD:_File_auto-generation...]]
** deploy-to-servers-or-locally.sh
is a script only used by the local dev either to locally build from his current local state or to git push and trigger the servers to update
** request-servers-to-fetch-and-deploy.sh
is a script that calls secrets-for-request-servers-to-fetch-and-deploy.sh for credentials, urls and paths. It then triggers all servers to fetch the current git data and update via build.sh
** secrets-for-request-servers-to-fetch-and-deploy.sh
(NOT part of the repo) has all the credentials, paths and urls for request-servers-to-fetch-and-deploy.sh as variables.
=== Javascript specific ===
* 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
** [https://en.wikipedia.org/wiki/MediaWiki:Common.js Even Wikipedia states in their MediaWiki:Common.js
]:
* 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 {{CustomRepo|alt=/tree/master/mediawiki-shared/build config-build-(shared and specific).json}} under "generaljswrapper". This file is currently {{CustomRepo|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 mwDev.info * 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 === * In order to be very transparent and debug more easily we decided to use a source map for our combined wiki js file ** Here is the documentation for source maps https://firefox-source-docs.mozilla.org/devtools-user/debugger/how_to/use_a_source_map/index.html ** Our wiki-JS is combined and rendered into {{SERVER}}/mw-autogen/mw-combined-wikijs.js and minified to {{SERVER}}/mw-autogen/mw-combined-wikijs.min.js ** For all other purposes we use
minify
, but for Javascript we use uglifyjs
for its source map capabilities
** In addition to the minified JS file uglify creates a source map {{SERVER}}/mw-autogen/mw-combined-wikijs.min.js.map that references the combined source file (from which the minified file is created)
** Also the comment //# sourceMappingURL=/mw-autogen/mw-combined-wikijs.js
is automatically added to the minified 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 https://www.npmjs.com/package/uglify-js . 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/mw-combined-wikijs.min.js.map'"
*** 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 https://stackoverflow.com/questions/54119790/prevent-gulp-uglify-from-stripping-out-es6
*** [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
=== Exceptions ===
* '''Header CSS files''' : This is also done for general CSS files. The header CSS files however are not included via [[#Extension_HeadScript]] but in the [[Template:Header]] via our [[#Extension_CSS_Fork]]
=== For contributors: editor setup ===
* All repository files can be edited using every professional editor on the market
* However contributors are asked to follow specific rules
* '''Especially you are asked to configure your editor to adhere to these specific style requirements when saving a file'''
*# Remove trailing whitespaces
*# Remove multiple trailing newlines
*# Add exactly one final newline at the end of a file
* With VSCode for example you can insert these three lines into your settings.json
{{CodeSelect|code="files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
"files.trimFinalNewlines": true,
}}
=== jQuery dependent and other wiki core dependent libraries and scripts ===
* Normally all project scripts are executed DIRECTLY AFTER the mediawiki core is ready as described above
* Sometimes we need to use libraries which are dependent on the wiki core. And then we have project scripts dependent on these (core dependent) libraries
* These dependencies can be securly guaranteed via a functionality in headscript, done via a script tag with the id core-dependent-libs which is triggered when the core (including jquery) is ready. After loading the libraries an event is triggered that can be used by scripts dependent on these libraries
* '''For Devs'''
*# '''To add wiki core (and jquery) dependent libraries''' devs can add the library as a url in headscript in the $coreDependentLibs
array
*# '''To add core-dependent-library-dependent scripts''' devs can use mwDev.tools.wikiCoreDependentLibsReady( function() {...});
as a wrapper around project files instead of the usual (function(){...})();
wrapper
*#* And example can be found in {{CustomRepo|CustomScrollbar.js}}
== Extension CookieToBodyClass ==
* We created our own Mediawiki extension [https://github.com/{{project_name_short}}/mediawiki-extensions-CookieToBodyClass CookieToBodyClass].
* 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.ctbc_mycookie_2 .my-class{...}
. JS if( Cookies.get('ctbc_mycookie') == '2' ) {...}
== Extension BodyScript2 - not in use ==
* We created an extension based on the outdated BodyScript-extension and the still active HeadScript extension [https://github.com/adrelanos/mediawiki-extensions-BodyScript2 BodyScript2]
* 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 ==
* We use the [https://www.mediawiki.org/wiki/Extension:FlaggedRevs Extension Flagged Revisions] 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
** The bottom bar is optically modified via CSS due to our usage of the footer. See [[#MediaWiki_limitations]]
== Extension Dark Mode ==
* We use the extension https://www.mediawiki.org/wiki/Extension:DarkMode 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.
=== '''Retired Extension Dark Mode fork (until 2024-09)''' ===
* In the past we forked the extension because we needed an anon-user mode which was not provided. This has been fixed now, so we reverted to using the up-to-date upstream version with quality of life fixes and especially with the now added anon-user mode
* '''Past documentation for the fork'''
** 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: https://gerrit.wikimedia.org/r/c/mediawiki/extensions/DarkMode/+/849628
== MultiWiki ==
* 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 a separate GIT repository
* As there is no practical import option for pages, templates and widgets in MediaWiki for our purpose we use a '''"cascading multi-wiki"''' approach with the assistance of automated scripting.
=== JS and CSS files - GIT repo and server deploy ===
* Javascript and CSS files are managed in a GIT repository. These files are called source files and are in differen source folders. The shared folder and one folder for each wiki - at the moment Whonix and Kicksecure
* Note: One single JS file and one CSS files are not managed in this GIT repository: [[Mediawiki:Common.js]] and [[Mediawiki:Common.css]]. These files are MediaWiki specific files that cannot be managed outside. Their usage is described in the chapter [[Dev/mediawiki#Structure_of_our_wikis_.28How_to_build.29]]
* The '''development and deployment cycle''' work as follows
*# The GIT repository is locally pulled
*# The files are edited locally
*# If there are new files or file dependencies change then the local config build json files are edited to reflect the changes
*# The changes are pushed to the online GIT repository
*# On the online GIT repo files a build script is executed on the server which does the following for each wiki
*## Reads the shared config build file and loads the mentioned source files seperated by categories in their given order
*## Reads the wiki specific config build file and loads the mentioned source files seperated by categories in their given order and adds them after the shared source files
*## Renders combined Javascript and combined CSS files for each category and then also a minified version for each
*## All source files are also copied into a src-copy folder
*## Finally for each wiki the "distribution" files (combined files and src-copy folder files) are then deployed onto the corresponding wiki server
*## '''Build logs''' : Note, you can check the automatically generated build log files after deployment
*##* https://www.kicksecure.com/mw-autogen/build-log.htm
*##* https://www.whonix.org/mw-autogen/build-log.htm
* The '''GIT repo folder structure''' is as follows
** build/
*** build.sh
*** build-and-deploy-to-servers.sh
*** build-mw-combine.php
*** config-build-kicksecure.json
*** config-build-shared.json
*** config-build-whonix.json
** src/
*** kicksecure/
*** shared/
*** whonix/
** README.md
* The '''autogen folder''' for the rendered files on each server have the following folder structure
** [wiki-autogen-folder]
*** src-copy/* -- copied source files
*** build-log.htm
*** * // combined files
* Our main scripts are in the '''src/shared/''' source files. These will always be loaded first and come first in the combined files which are generated by the build script
** Every wiki also has their own source files which will be loaded and combined later than the shared files by the build script
** Every wiki source folder and shared folder also has a build config file which determins which file is rendered into which combined file and at which position
=== Pages, Templates and Widgets - publisher subscriber mechanism ===
* Content pages and wiki internal functionality like templates and widgets cannot be stored outside of the wiki.
* For this reason we use another strategy and another deployment methode utilizing the category [[:Category:MultiWiki]].
* Specifically we use a deploy script that '''cascades changes from multiwiki files from the publisher wiki (Kicksecure) to all other subscriber wikis'''.
* The whole life cycle
*# Multiwiki pages are given the category multiwiki (how this is done read below)
*# Multiwiki pages are added, deleted and edited only on the publisher wiki
*# To avoid confusion and losses due to edits in the subscriber wikis which are later overwritten by "multi wiki deploy cascade" from the publisher wiki there is [[Dev/mediawiki#EditorMultiwikiNotice]] which is an indicator for all editors warning if edits of a multiwiki file are not done in the publisher wiki.
*# The deployment from the publisher wiki to all the other wikis is done by running mw-multi-wiki
(ask admin for directions). This copies all pages, templates and widgets in the [[:Category:MultiWiki]] from the publisher wiki to all the subscriber wikis and overwrites their previous files
[[Category:MultiWiki]]
[[Category:MultiWiki]]
Category
MultiWiki
: [[Contact#Footnotes|Contact
, chapter Footnotes
]]
** wiki templates that have been added to Category
MultiWiki
: [[Template:Gpg_key]]
** The full list of wiki pages, templates and widgets currently in Category
MultiWiki
can be found on the category page: [[:Category:MultiWiki]]
mw-multi-wiki
{{Header}}
will have the special look of our local skin augmentation
# '''Entry points / categories'''
## The relevant files are all found in the wiki build files in the git repository. These files have multiple sections. So these files is a great way to see the application structure. Sections:
### '''wikijs''' : These files will be combined into one file whose methods will be available on the whole wiki even without the skin applied
### '''wikicss''' : These files will be combined into one file whose styles will be available on the whole wiki even without the skin applied
### '''skincss''' : These files will be combined into one file whose styles will only be available of the 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 [https://www.mediawiki.org/wiki/Reading/Web/Desktop_Improvements project page].*
$wgHiddenPrefs = array( "skin-responsive", );
# Under https://www.kicksecure.com/wiki/Special:Preferences#mw-prefsection-rendering:
## remove "Vector legacy (2010) (Preview)"
## hide 'Vector legacy (2010)'
## keep 'Vector 2022'
$wgSkipSkins = [ 'vector', ];=== For the admin regarding MediaWiki updates === * MediaWiki updates sometimes come with changes in HTML. Legacy Vector is not protected against this as these changes are not directly in the skin but in the core HTML rendering * This documented here https://m.mediawiki.org/wiki/Stable_interface_policy/Frontend * And this was indirectly confirmed by our rejected ticket https://phabricator.wikimedia.org/T344681 * This means for us '''for every MediaWiki update''' *# Check for HTML updates with every MediaWiki update *# Reserve Dev time for possible changes *# Change our skin augmentation to address HTML changed if needed === Layout on top of Legacy Vector - skin augmentation === * We use '''MediaWiki's "Legacy 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. https://github.com/jthingelstad/foreground/issues/392 * 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:/mw-combined-skincss.min.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.
=== Vector Legacy Maintenance by MediaWiki ===
* '''Open investigation''': We try to determine if bug reporting for Legacy Vector is off limits and that pull requests would be rejected. The name "legacy" indicates that further development might be rejected but it is unclear.
* Our probe is this bug report [https://phabricator.wikimedia.org/T373045 Legacy Vector TOC Lighthouse bugs due to toggle collapse] (duplicate), which describes a real bug that we have found in Legacy Vector.
* At the moment there is no reaction from the MediaWiki team yet.
== Pages.js ==
* Sometimes Javascript is only needed on specific pages for specific tasks. This happens very rarely.
* So we created {{CustomRepo|Pages.js}} - a LocalWiki file where the page specific JS functions are combined
== jscookie ==
Within headscript we use:
*
jscookie
is a simple small cookie library for all our cookie control needs and is only 2kb in size. So it's very practical and we couldn't program it ourselves any smaller.
* We use it for DebugViaUrlModal
, FlyinNotification
, SiteNotice
and TocLevelSwitcher
.
== FontAwesome ==
* 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 ===
* 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.
=== Development details ===
==== Versioning in Headscript ====
All files called in Headscript usually have a headscript version number, but not our fonts including FontAwesome. [[Dev/mediawiki#Fonts|Read here about our Fonts]]
==== Subsetting ====
* We tried using '''subsetting''' to only serve the needed icons and there saving bandwidth and improving performance on 2024-08-15
** But subsetting is now a FontAwesome service only available to Premium members which collides with our freedom software approach
** Therefore subsetting is rejected until it's free again in the future maybe
** Below are all the FontAwesome icons currently in use in our wikis
fa-solid fa-1 fa-solid fa-2 fa-solid fa-3 fa-solid fa-4 fa-solid fa-5 fa-solid fa-6 fa-solid fa-7 fa-solid fa-8 fa-solid fa-9 fa-solid fa-arrow-right-arrow-left fa-solid fa-asterisk fa-solid fa-ban fa-solid fa-binoculars fa-solid fa-bolt fa-solid fa-book fa-solid fa-bullhorn fa-solid fa-chart-line fa-solid fa-check fa-solid fa-check-circle fa-solid fa-check-double fa-solid fa-chevron-down fa-solid fa-chevron-up fa-solid fa-clock-rotate-left fa-solid fa-code fa-solid fa-compact-disc fa-solid fa-compress-alt fa-solid fa-crown fa-solid fa-cube fa-solid fa-display fa-solid fa-dollar-sign fa-solid fa-download fa-solid fa-droplet fa-solid fa-dumbbell fa-solid fa-envelope fa-solid fa-exclamation fa-solid fa-exclamation-circle fa-solid fa-expand fa-solid fa-external-link-alt fa-solid fa-feather fa-solid fa-fire-flame-curved fa-solid fa-flask fa-solid fa-gears fa-solid fa-gift fa-solid fa-hand fa-solid fa-hand-holding-medical fa-solid fa-hdd fa-solid fa-house fa-solid fa-info fa-solid fa-info-circle fa-solid fa-key fa-solid fa-keyboard fa-solid fa-laptop fa-solid fa-laptop-code fa-solid fa-lightbulb fa-solid fa-link fa-solid fa-list-ol fa-solid fa-lock fa-solid fa-mask fa-solid fa-medal fa-solid fa-minus fa-solid fa-mountain-sun fa-solid fa-mouse-pointer fa-solid fa-pause fa-solid fa-pen fa-solid fa-pen fa-solid fa-pen-nib fa-solid fa-people-group fa-solid fa-person-digging fa-solid fa-phone-slash fa-solid fa-play fa-solid fa-plus fa-solid fa-print fa-solid fa-question fa-solid fa-right-to-bracket fa-solid fa-rocket fa-solid fa-rotate fa-solid fa-seedling fa-solid fa-share fa-solid fa-share-alt fa-solid fa-share-nodes fa-solid fa-shield fa-solid fa-shield-alt fa-solid fa-shield-halved fa-solid fa-smile fa-solid fa-star fa-solid fa-sun fa-solid fa-thumbs-up fa-solid fa-times fa-solid fa-tint fa-solid fa-toggle-off fa-solid fa-toolbox fa-solid fa-trash-can fa-solid fa-triangle-exclamation fa-solid fa-unlock fa-solid fa-unlock-keyhole fa-solid fa-upload fa-solid fa-user fa-solid fa-user-secret fa-solid fa-user-shield fa-solid fa-virus fa-solid fa-wand-magic-sparkles fa-solid fa-water fa-solid fa-window-restore fa-brands fa-apple fa-brands fa-debian fa-brands fa-linux fa-brands fa-osi fa-brands fa-usb fa-brands fa-windows fa-regular fa-clock fa-regular fa-comments fa-regular fa-envelope-open fa-regular fa-hand fa-regular fa-save fa-regular fa-star Also the additional functional classes fa-fw
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: swapWhat we currently have:
There are two different ways we currently add fonts. * 1) link rel="stylesheet" for font awesome * 2)