메뉴얼:미디어위키 스킨 만드는 방법
스킨 만들기는 미디어위키의 내부 작업에 익숙해지고 위키미디어 운동에 기여를 시작하는 좋은 방법입니다! CSS, JavaScript, JSON 등의 프런트엔트에 익숙하다면 미디어위키 스킨을 만들 수 있습니다! PHP에 대해 알 필요는 없지만 고급 작업을 하고싶다면 도움이 될 수 있습니다. PHP를 알 필요는 없지만 고급 작업을 수행하고 싶다면 도움이 될 수 있습니다.
필수는 아니지만, LESS CSS에 익숙하다면 도움이 될 것입니다. 이 튜토리얼에서는 미디어위키의 작동 버전이 설치되어 있고, 현재 개발 릴리스를 실행하고 있다고 가정합니다.
If you having an existing skin using the PHP BaseTemplate, this guide is not for you. Please see Manual:How to make a MediaWiki skin/Migrating SkinTemplate based skins to SkinMustache instead.
Preparation
Skin development will be a lot easier with a familiarity with Mustache templates.
At minimum, you should be familiar with the following Mustache basics described in the example below:
{{ str }} <!-- renders escaped string -->
{{{ html-str }}} <!-- renders RAW HTML -->
<!-- accesses data inside an associative array of the form { 'key' => 'hello' } -->
{{#array-data}}
{{ key }} <!-- renders hello -->
{{/array-data}}
<!-- for boolean values -->
{{#is-talk-page}}
<!-- conditional rendering if is-talk-page is true -->
{{/is-talk-page}}
A skin is responsible for the rendering of user-visible content - the HTML inside the BODY tag. It is restricted from editing anything inside the HEAD. Code will be automatically generated for the skin, so that the skin can focus on presentation. If you need to modify the HEAD this is considered outside the scope of the skin, please use Hooks, extensions or configuration to do that see the FAQ for best practices on how to do that.
시작해 봅시다!
첫번째 스킨 제작을 시작하기 위한 두가지 옵션을 권장합니다.
옵션 1 - 스킨 예제를 포크
예제 스킨 https://github.com/wikimedia/mediawiki-skins-Example 은 스킨 구현의 뼈대를 제공합니다. 스킨 폴더의 리포지토리를 포크하여 폴더가 "Example"인지 확인한 후 LocalSettings.php에 다음을 추가하십시오.
wfLoadSkin( 'Example' );
만약에 당신의 위키에 당신의 스킨을 계획하기 위해 당신의 위키의 Special:Preferences 페이지에서 사용할 수 있게 되었습니다.
옵션 2 스킨 랩을 사용하기
The skins lab tool allows you to setup a skin with basic CSS and templates. 마음이 편안해지면 'ZIP으로 다운로드'를 클릭하면 스킨에 필요한 보일러 플레이트가 정리됩니다. 레포지토리 탐색이 쉬워집니다. 당신이 ZIP place 를 다운로드하면 MediaWiki 스킨 폴더에서 LocalSettings.php을 업데이트하십시오.
wfLoadSkin( 'FolderName' );
제대로 진행되었다면 위키의 Special:Preferences 페이지에서 스킨을 이용할 수 있어야 합니다.
Option 3 - From the command line
cd mediawiki/skins
npm install mediawiki-skins-cli
npx create-mw-skin SkinName
cd SkinName
When you have downloaded the ZIP place it in your MediaWiki skins folder and update LocalSettings.php with the following:
wfLoadSkin( 'SkinName' );
After installing navigate to MediaWiki with ?useskin=skinname on the URL to see your skin.
To explore the data available to the Mustache template add ?useskin=json (example).
사람들에게 알려줍니다!
스킨을 만드는겄은 다른 사람들과 함께 하는 것이 더 재미있을 것이고 훨씬 더 쉬워질 것입니다! 사용 가능한 항목이 있으면 GitHub 또는 게릿 에 게시하는 것을 고려하십시오. Once the code is publicly available, you should create a skin page (make sure you change the title!) to let people know you are open for collaboration!
위키 페이지를 설정하면 다른 많은 좋은 점이 있습니다. You'll be able to handle bug reports in Phabricator or GitHub issues and receive patches from other volunteers in the MediaWiki community. 누군가 번역을 도와줄 수 있어야 합니다.
Mustache
미디어위키 1.35에서 Mustache 지원이 추가되었습니다. We found using Mustache to be very helpful in the development of the Skin:Minerva and 스킨:벡터 skins as it allows you to separate data from presentation. Mustache를 사용하여 템플릿을 재사용할 수 있습니다. To use a partial Partial.mustache in MediaWiki, simply add them to the folder you are working in and reference them using {{>Partial}} in the master template skin.mustache.
Mustache 템플릿으로 전송되는 데이터는 비교적 유연합니다. If something is missing, you can use PHP to add data by extending the SkinMustache ::getTemplateData function.
The SkinJson skin can be added to a MediaWiki development instance, to inspect the data available to skins. Note that arrays are prefixed "array-", booleans are prefixed with "is-" and objects are prefixed "data-" to help you conceptualize the data you are working with.
The data available, and in which MediaWiki versions it is available is documented on SkinMustache.php.
스킨 번역 가능(i18n)
In skin.json under ValidSkinNames, you can use the `messages` option to define translatable message keys.
These keys should correspond to entries inside the i18n/en.json folder.
Once registered for the skin, these will be available in your template with a prefix msg-
.
"example": {
"class": "SkinMustache",
"args": [ {
"name": "example",
"messages": [
"sitetitle",
"search",
"tagline",
"navigation-heading"
]
} ]
}
For example in the example below, the message "sitetitle" can be rendered in a Mustache template using:
<p>{{msg-sitetitle}}</p>
See Localisation for more information on why this is important.
Rendering template partials
Template partials can be used to render different parts of the skin and to avoid the problem with having a large unmaintainable skin.mustache file. In the following example, the skin renders the contents of the templates in the 3 files with the filenames Logo.mustache, Content.mustache and Footer.mustache. These files must exist in the same folder as the skin.mustache file or a subfolder of the directory containing skin.mustache.
{{>subfolder/Logo}}
{{>Content}}
{{>Footer}}
Template partials are a great way to break up your skin to make it more readable. No template partials are predefined and available by default, however you can look at existing skins using SkinMustache for inspiration.
Read more about Mustache template partials.
Logo.mustache
Following code block is being used to show the site logo in the Example skin and you will also see the same if you create the skin from the SkinLabs.
<!-- Logo.mustache -->
<div id="p-logo" class="mw-portlet" role="banner">
<a href="{{link-mainpage}}">
{{#data-logos}}
{{#icon}}<img src="{{.}}" width="40" height="40">{{/icon}}
{{#wordmark}}<img src="{{src}}" width="{{width}}" height="{{height}}">{{/wordmark}}
{{^wordmark}}<h1>{{msg-sitetitle}}</h1>{{/wordmark}}
{{/data-logos}}
</a>
</div>
From the code block mentioned above, the following line is responsible to show the logo `icon`:
{{#icon}}<img src="{{.}}" width="40" height="40">{{/icon}}
This line assumes that, there is a key icon
in the array $wgLogos .
So in your LocalSettings.php file, if there is a line similar as $wgLogos = [ 'icon' => "$wgResourceBasePath/resources/assets/wiki.png" ];
, then the logo/icon image will be displayed.
The default MediaWiki LocalSettings.php
exports a 1x
key in the $wgLogos
array.
So to show the logo you need to update the LocalSettings.php and add a key icon
.
resources/assets/wiki.png
path. Because it will be changed to default, when you update the MediaWiki. The recommended way to change the logo is to add a new logo image file and add that path to the LocalSettings.php.Rendering menus with Mustache
All menus are structured in the same format (PortletData). A generic Menu.mustache template partial, added to the same folder as skin.mustache can therefore be used to generate a menu.
<nav id="{{id}}" class="{{class}}" title="{{html-tooltip}}"
aria-labelledby="{{id}}-label">
<input type="checkbox" aria-labelledby="{{id}}-label" />
<h3 id="{{id}}-label" {{{html-user-language-attributes}}}>{{label}}</h3>
<div class="mw-portlet-body">
<ul {{{html-user-language-attributes}}}>
{{{html-items}}}
</ul>
{{{html-after-portal}}}
</div>
</nav>
However, when using this partial you'll need to tell it which menu to generate HTML for.
Inside skin.mustache the following would render the languages and views menu.
{{! Switch template context to data for all menus }}
{{#data-portlets}}
{{! Access the menu called "languages" }}
{{#data-languages}}
{{>Menu}}
{{/data-languages}}
{{! Access the menu called "views" }}
{{#data-views}}
{{>Menu}}
{{/data-views}}
{{/data-portlets}}
Rendering dropdown or sub-menus
Skin designers can also use the Mustache syntax to create dropdown menus from the elements previously found in the sidebar of the Vector and MonoBook skins. This is a little trickier, however, but understanding the way the elements are stored can help.
The first sidebar element — typically containing the main page link and other MediaWiki links, is rendered via the {{#data-portlets-sidebar.data-portlets-first}}
call.
Subsequent menus, however, are stored in the {{#data-portlets-sidebar.array-portlets-rest}}
array, and can be rendered by calling this.
For example, one may use the following syntax:
{{#data-portlets-sidebar.array-portlets-rest}}
<div class="mw-dropdown-title"><span>{{label}}</span>
<div class="dropdown-content">{{>Portlet}}</div></div>
{{/data-portlets-sidebar.array-portlets-rest}}
Which, when CSS is applied to hide "dropdown-content" until "mw-dropdown-title" is hovered over, thus creating a dropdown menu.
Disabling the table of contents
In MW 1.38, you can remove the table of contents from the article body and position it outside the content area. To disable the table of contents generation, add the following to skin.json:
{
"ValidSkinNames": {
"notocskin": {
"class": "SkinMustache",
"args": [
{
"name": "notocskin",
"toc": false
}
]
}
}
}
The array-sections template key can be used for rendering the table of contents.
More examples
To see examples of template partials that can be used in your project, you can look through the examples in the Wikimedia skins labs.
스크립트와 스타일
기본값
스킨에는 최소한 단일 스타일 리소스 로더 모듈이 필요합니다. 이렇게 보일 것입니다.: 기능 키를 사용하면 i18n을 비롯한 다양한 작업에 유용한 보일러 플레이트 기본값을 사용할 수 있으며 MediaWiki core php 설명서에 나와 있는 표준화를 수행할 수 있습니다. 기능은 키 목록(opt-in 정책)이거나 1.36의 개체(opt-out 정책)일 수 있습니다. 잘 모를 경우 기능 키를 생략하여 권장 기본값을 사용하십시오. A skin at minimum requires a single style ResourceLoader module defined in your skin's skin.json file. It will look a bit like this:
"ResourceModules": {
"skins.example": {
"class": "ResourceLoaderSkinModule",
"features": { "normalize": true },
"styles": [ "resources/skins.example.less" ]
}
},
The features key allows you to use useful boiler plate defaults for a variety of things including i18n and normalize which are documented in the MediaWiki core php documentation. Features can be an array of keys (opt-in policy) or in MW 1.36 an associative array (opt-out policy, recommended). If you are not sure, please omit the features key to use the recommended defaults.
CSS / LESS
The skin.json is a manifest of all the assets your skin uses.
Under the `ResourceModules` key you should find the style module for your skin listed under `skins.example`.
Here, under the "styles" key you can add LESS or CSS files.
They will be loaded in the order they are listed.
With LESS you can use @import
statements in the same folder.
More information about what's possible can be found in Developing with ResourceLoader.
When using images you should be able to use relative URIs to access the image assets.
MediaWiki Skin Variables
MediaWiki skin variables originally introduced in MW 1.35, were enabled for wide use since MW 1.41.
The list of values available is in sync with latest Codex design tokens (demo site).
- Quickly implement design – For skin designers skin variables offer a way to quickly implement design choices by setting values in a flat list. Through them designers can change fundamental properties like typography (font family, font size, etc.), colors, breakpoints, borders, sizing, spacing or z-indexes. This easy to use list is grouped by CSS properties. It must be located in folder and file 'resources/mediawiki.less/mediawiki.skin.variables.less' for ResourceLoader to pick it up. The naming scheme follows the MediaWiki variables naming convention .
- Neutral defaults – If a skin doesn't specify certain values, the system will fall back to use the defaults from MediaWiki's own 'mediawiki.skin.defaults.less'. Those values are representing a basic HTML look.
- Customize – While you can't modify the variable names, you could define additional ones in separate skin specific files. In every Less file, you can import the skin's values by only
@import 'mediawiki.skin.variables.less';
- Centralization benefits – All the variables definition for the Wikimedia default theme and all the naming is centralized in order to
- Establish a consistent naming convention for clarity and uniformity
- Ensure compatibility across various skins and extensions
- Provide insights into potential gaps or areas of improvement based on common usage patterns
Skin authors are encouraged to familiarize themselves with these updates to maximize the potential of their skins.
Use in core, skins and extensions Less files
In order to use mediawiki.skin.variables.less variables aka design tokens you must include an import statement on top of your Less file.
Example usage:
@import 'mediawiki.skin.variables.less';
/* Links */
a {
color: @color-link;
}
a:visited {
color: @color-link--visited;
}
a:active {
color: @color-link--active;
}
An important detail is, that only variables specified in mediawiki.skin.defaults.less
can be reassigned with skin specific values in the skin's mediawiki.skin.variables.less
file.
Note that, Vector 2022, Vector legacy and MinervaNeue skins are using the two default Codex themes for Wikimedia user-interfaces, which are also represented on the Codex documentation site.
Over 45 different skins and extensions use the skin variables in MW 1.41 already.
Using CSS variables for supporting different themes e.g. dark mode
MediaWiki skin variables support both fixed and CSS variable based output. You can opt into CSS variables by adding the following line to your mediawiki.skin.variables.less
file.
@import 'mediawiki.skin.codex-design-tokens/theme-wikimedia-ui.less';
Using the default Wikimedia dark mode palette
When using CSS variables, you can make use of the mixin-night-mode-palette mixin to define a night mode palette as in this example:
@import 'mediawiki.skin.variables.less';
@import 'mediawiki.skin.codex-design-tokens/theme-wikimedia-ui-mixin-dark.less';
@import 'mediawiki.skin.codex-design-tokens/theme-wikimedia-ui-reset.less';
@media screen and ( prefers-color-scheme: dark ) {
html {
color-scheme: light dark;
.mixin-night-mode-palette();
}
}
Responsive skins / adding a meta viewport
If you are building a responsive skin, make sure to use the responsive skin option when declaring your skin in skin.json.
{
"ValidSkinNames": {
"my-responsive-skin": {
"class": "SkinMustache",
"args": [
{
"name": "my-responsive-skin",
"responsive": true
}
]
}
}
}
Making skins compatible with languages that are right-to-left (RTL)
The scripts of certain languages e.g. Hebrew are in right to left rather than left to right. This presents a problem for skin developers, where interfaces are flipped e.g. in Vector the sidebar is on the left rather than the right.
In MediaWiki it's also possible to use a different language for the skin and the content. For example, in Special:Preferences you can set your language to Hebrew while retaining the content in English.
Writing skins that work well in RTL is a large topic out of scope for this document, but if you need to test your skin in RTL you should update LocalSettings.php to change your content language:
$wgLanguageCode = "he";
As a skin developer you should keep in mind two things:
- Any CSS written for your skin will be flipped automatically via the CSSJanus tool without any work required from you, however you may need to disable some of those transformations (see Flipping).
- Any HTML you render that can be translated should be marked up with the dir HTML attribute. For your convenience SkinMustache provides the html-user-language-attributes template variable which can be used like so:
<div
{{{html-user-language-attributes}}}
>
</div>
for a user who has set their language to Hebrew in preferences, produces the following HTML:
<div
dir="rtl" lang="he"
>
</div>
Images
You can extend Manual:$wgLogos with any data you choose to. This will allow site admins to configure images as they choose, but you must always conditionally render them.
In cases where images must be hardcoded for some reason, and cannot use a CSS background-image or wgLogos, you will need to extend the data sent to the template
JavaScript
JavaScript code in skins, runs in an environment where you can rely on the `mw` and `jQuery` objects having been loaded. We recommend using ResourceLoader/Package_files which will allow you to require file assets.
For information on the available API and libraries see core JS documentation.
고급 사용
스킨에는 최소한 단일 스타일 리소스 로더 모듈이 필요합니다. 이렇게 보일 것입니다. More advanced information will provided on an as requested basis. Please ask a question on the talk page to accelerate the addition of documentation!
i18n
Messages defined in i18n/en.json can be passed directly to your Mustache template by inclusion in skin.json. Note, that you can use any messages defined inside MediaWiki core.
skin.json | i18n/en.json | skin.mustache |
---|---|---|
{
"ValidSkinNames": {
"mymustacheskin": {
"class": "SkinMustache",
"args": [
{
"name": "mymustacheskin",
"messages": [
"createaccount"
]
}
]
}
}
}
|
{
"@metadata": {
"authors": []
},
"skinname-mymustacheskin": "My Mustache Skin",
"mymustacheskin-hello": "Hello"
}
|
<div>
{{msg-mymustacheskin-hello}} <!-- prints hello in the current language -->
</div>
|
Extending data
The data available is documented on SkinMustache.php .
If you need to add additional data for rendering inside your skin's template that cannot be served by messages (as in the i18n section) e.g. raw HTML or complex data structures you must use a dedicated PHP class and extend the SkinMustache::getTemplateData method.
<?php
class MySkin extends SkinMustache {
/**
* Extends the getTemplateData function to add a template key 'html-myskin-hello-world'
* which can be rendered in skin.mustache using {{{html-myskin-hello-world}}}
*/
public function getTemplateData() {
$data = parent::getTemplateData();
$data['html-myskin-hello-world'] = '<strong>Hello world!</strong>'; // or $this->msg('msg-key')->parse();
return $data;
}
}
SkinModule 클래스를 통한 기본 스타일링
All skins should define a single style module with the class SkinModule . The module defines various default styles to take care of MediaWiki internals. If you want, you can disable these features and provide your own styles. Define features as an empty object to tie yourself into the recommended MediaWiki defaults. A list of support features is provided in our docs.
Example MediaWiki\\ResourceLoader\\SkinModule that disables the logo feature but enables several others:
{
"skins.vector.styles": {
"class": "MediaWiki\\ResourceLoader\\SkinModule",
"features": {
"normalize": true,
"elements": true,
"content": true,
"logo": false,
"interface": true,
"legacy": true
},
"targets": [
"desktop",
"mobile"
],
"styles": [ "resources/skins.vector.styles/skin.less" ]
}
}
다른 확장과 통합
Extensions should integrate with you, not the other way round! Try to forget about extensions when writing your skin. Skins for extension developers is provided for extension developers to ensure they get the best compatibility. The starter templates in Getting_started will render all possible UI elements. If you omit certain pieces of data you may break support with extensions.
For certain extensions you may want to tweak the styles of the default UI elements, notably 확장기능:Echo . To do this you will need to read Manual:$wgResourceModuleSkinStyles .
체인징 메뉴 컨탠츠
후크를 사용하여 메뉴 구성을 변경할 수 있습니다. 예를 들어, 벡터에서는 SkinTemplateNavigation 후크를 사용하여 시계 모양 아이콘을 재배치합니다. 이렇게 할 때, 다른 스킨에 부작용이 생기지 않도록 수술 중인 피부를 확인하는 것을 잊지 마세요. The composition of menus can be changed by using hooks. For example in Vector, the SkinTemplateNavigation hook is used to relocate the watch star icon. When doing this, remember to check the skin being operated on, to avoid side effects in other skins.
I want to change elements in the head of the HTML page
Skin developers should not concern themselves with modifying anything in the HEAD of a document. Modifications of the HEAD are better served via extensions and configuration inside LocalSettings.php.
The following links may be helpful:
- 메뉴얼:$wgAppleTouchIcon
- Manual:$wgFavicon
- Manual:Hooks/OutputPageBodyAttributes
- Manual:$wgSkinMetaTags
I am writing an extension that needs to style itself differently depending on the skin
Extensions can make use of skin styles to ship skin-specific styles using the skinStyles key. See Manual:$wgResourceModuleSkinStyles .
VisualEditor compatibility
To ensure compatibility with VisualEditor please see these guidelines.
Building skins for 1.35
In 1.35 support for building skins was not as straightforward as in 1.36. If you wish to build a skin for 1.35, using template data provided in 1.36, you will need to extend the SkinMustache PHP class. A polyfill for the Example skin is provided.
당신의 피드백은 중요합니다
쉽지 않은 점이 있다면 좀 더 쉽게 해드리고 싶기 때문에 여러분의 피드백이 중요합니다. 문제가 발생하면 Phabricator의 미디어위키 코어 스킨 아키텍처 프로젝트에 버그 보고서를 제출해 주십시오. 그러면 멋진 솔루션을 찾아보겠습니다.
토크 페이지에 자유롭게 질문해 주세요. 바보 같은 질문은 없습니다. If something is not easy, we'd like to make it easier, so your feedback is important. If you run into problems, then please file a bug report in the MediaWiki core skin architecture project in Phabricator, and we'll try and find an elegant solution.
Please feel free to ask a question on the talk page. There is no such thing as a stupid question.