Manual:Cómo hacer una apariencia (skin) de MediaWiki
¡Crear una apariencia es una excelente manera de familiarizarse con el funcionamiento interno de MediaWiki y de iniciar sus contribuciones al proyecto Wikimedia! Si estás familiarizado con las tecnologías front-end de CSS, JavaScript y JSON, ¡puedes crear una apariencia de MediaWiki! No es necesario saber PHP, pero puede ser útil si deseas hacer algo avanzado.
Aunque no es esencial, te ayudará si estás familiarizado con LESS CSS. Este tutorial asume que has instalado una versión funcional de MediaWiki y estás ejecutando la versión de desarrollo actual, si no es así, se recomienda que lo haga primero.
Si usted tiene una apariencia existente utilizando PHP BaseTemplate, esta guía no es para ti. Por favor, consulta Manual:Cómo hacer un skin para MediaWiki/Migrar skins basadas en SkinTemplate a SkinMustache en su lugar.
Preparación
El desarrollo de skins será mucho más fácil si se está familiarizado con las plantillas Mustache.
Como mínimo, debe estar familiarizado con los siguientes conceptos básicos de Mustache que se describen en el siguiente ejemplo:
{{ 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}}
Un skin es responsable de la representación del contenido visible para el usuario: el HTML dentro de la etiqueta BODY. Está restringido para editar cualquier cosa dentro del HEAD. El código se generará automáticamente para el skin, de modo que éste pueda centrarse en la presentación. Si necesita modificar el HEAD esto se considera fuera del alcance de la skin, por favor use Hooks, extensiones o configuración para hacerlo, vea las Preguntas Frecuentes para las mejores prácticas sobre cómo hacerlo.
Primeros pasos
Para comenzar a crear tu primera apariencia, te recomendamos dos opciones.
Opción 1 - Bifurca la apariencia de ejemplo
La apariencia de ejemplo https://github.com/wikimedia/mediawiki-skins-Example proporciona los elementos esenciales para la implementación de una apariencia. Clona el repositorio en tu carpeta de apariencias asegurándote de que la carpeta se llame "Example" y agrega lo siguiente a tu LocalSettings.php:
wfLoadSkin( 'Example' );
Si todo va de acuerdo al plan, tu apariencia debería estar disponible en la página Special:Preferences de tu wiki.
Opción 2 - Usa el laboratorio de apariencias
La herramienta de Laboratorio de Apariencias te permite configurar una apariencia con CSS y plantillas básicas. Una vez que te sientas cómodo, puede hacer clic en "download as ZIP" (descargar como ZIP), que compilará el código repetitivo necesario para tu apariencia. Ojalá que el repositorio resultante sea fácil de navegar. Cuando hayas descargado el ZIP, colócalo en tu carpeta de apariencias de MediaWiki y actualiza LocalSettings.php con lo siguiente:
wfLoadSkin( 'FolderName' );
Si todo va de acuerdo al plan, tu apariencia debería estar disponible en la página Special:Preferences de tu wiki.
Opción 3 - Desde la línea de comandos
cd mediawiki/skins
npm install mediawiki-skins-cli
npx create-mw-skin SkinName
cd SkinName
Cuando hayas descargado el ZIP colócalo en tu carpeta de skins de MediaWiki y actualiza LocalSettings.php con lo siguiente:
wfLoadSkin( 'SkinName' );
¡Que la gente lo sepa!
Hacer una apariencia con otras personas será más divertido y también mucho más fácil. Una vez que tengas algo utilizable, considera publicarlo en GitHub o Gerrit . Una vez que el código esté a disposición del público, deberías crear una página de apariencia (¡asegúrate de cambiar el título!) para que la gente sepa que estás abierto a la colaboración.
Configurar una página wiki tiene muchos otros beneficios. Podrás gestionar informes de errores en Phabricator o desde GitHub y recibir parches de otros voluntarios de la comunidad de MediaWiki. Alguien también debería poder ayudarte a configurar la traducción.
Mustache
En la versión 1.35 añadimos soporte para Mustache en las Apariencias. El uso de Mustache nos resultó muy útil en el desarrollo de las apariencia de Skin:Minerva y Skin:Vector , ya que permite separar los datos de la presentación. Los parciales de Mustache pueden utilizarse para reutilizar plantillas. Para usar un Partial.mustache parcial en MediaWiki, simplemente añádelos a la carpeta en la que estás trabajando y haz referencia a ellos usando {{>Partial}} en la plantilla maestra 'skin.mustache'.
Los datos enviados a las plantillas de Mustache son relativamente flexibles. Si falta algo, puede utilizar PHP para añadir datos ampliando la función SkinMustache ::getTemplateData.
La apariencia SkinJson puede ser añadida a una instancia de desarrollo de MediaWiki, para inspeccionar los datos disponibles para las apariencias. Tenga en cuenta que las matrices llevan el prefijo "array-", los booleanos el prefijo "is-" y los objetos el prefijo "data-" para ayudarle a conceptualizar los datos con los que está trabajando.
Los datos disponibles y en qué versiones de MediaWiki están disponibles están documentados en SkinMustache.php.
Haz tu apariencia traducible (i18n)
En skin.json bajo ValidSkinNames, puede utilizar la opción `messages` para definir claves de mensaje traducibles.
Estas claves deben corresponder a entradas dentro de la carpeta i18n/en.json.
Una vez registrado para la apariencia, estos estarán disponibles en su plantilla con un prefijo msg-
.
"example": {
"class": "SkinMustache",
"args": [ {
"name": "example",
"messages": [
"sitetitle",
"search",
"tagline",
"navigation-heading"
]
} ]
}
Por ejemplo, en el siguiente ejemplo, el mensaje "sitetitle" puede ser renderizado en una plantilla de Mustache usando:
<p>{{msg-sitetitle}}</p>
Consulta Localización para más información sobre por qué esto es importante.
Renderizado de plantillas parciales
Las plantillas parciales (o divididas) se pueden utilizar para representar diferentes partes de la apariencia y evitar el problema de tener un archivo skin.mustache grande e imposible de mantener. En el siguiente ejemplo, la apariencia muestra el contenido de las plantillas en los 3 archivos con los nombres Logo.mustache, Content.mustache y Footer.mustache. Estos archivos deben existir en la misma carpeta que el archivo skin.mustache o en una subcarpeta del directorio que contiene skin.mustache.
{{>subfolder/Logo}}
{{>Content}}
{{>Footer}}
Las plantillas parciales son una buena forma de dividir la apariencia para hacerla más legible. No hay plantillas parciales predefinidas y disponibles por defecto, sin embargo puedes mirar las apariencias existentes usando SkinMustache para inspirarte.
Leer más sobre Plantillas Mustache parciales.
Logo.mustache
El siguiente bloque de código se utiliza para mostrar el logotipo del sitio en la apariencia de Example y también verá lo mismo si crea la apariencia de 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>
Del bloque de código mencionado anteriormente, la siguiente línea es la responsable de mostrar el logo `icon`:
{{#icon}}<img src="{{.}}" width="40" height="40">{{/icon}}
Esta línea asume que, hay una clave icon
en el array $wgLogos .
Así que en su archivo LocalSettings.php, si hay una línea similar a $wgLogos = [ 'icon' => "$wgResourceBasePath/resources/assets/wiki.png" ];
, entonces se mostrará la imagen del logo/icono.
Por defecto MediaWiki LocalSettings.php
exporta una clave 1x
en el array $wgLogos
.
Así que para mostrar el logotipo que necesita para actualizar el LocalSettings.php y añadir una clave de icon
.
resources/assets/wiki.png
. Ya que se cambiará al que estaba por defecto, cuando se actualice MediaWiki. La forma recomendada de cambiar el logotipo es añadir un nuevo archivo de imagen del logotipo y añadir esa ruta al LocalSettings.php.
Renderización de menús con Mustache
Todos los menús están estructurados en el mismo formato (PortletData). Una plantilla genérica Menu.mustache parcial, añadida a la misma carpeta que skin.mustache puede ser utilizada para generar un menú.
<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>
Sin embargo, al utilizar este parcial tendrá que decirle para qué menú generar HTML.
Dentro de skin.mustache lo siguiente mostraría el menú de idiomas y vistas.
{{! 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.
Desactivar el índice
En MW 1.38, puedes eliminar el índice del cuerpo del artículo y colocarlo fuera del área de contenido. Para desactivar la generación del índice, añada lo siguiente a skin.json:
{
"ValidSkinNames": {
"notocskin": {
"class": "SkinMustache",
"args": [
{
"name": "notocskin",
"toc": false
}
]
}
}
}
La clave de plantilla array-sections puede utilizarse para representar el índice.
Más ejemplos
Para ver ejemplos de plantillas parciales que puedes utilizar en tu proyecto, puedes consultar los ejemplos en el Laboratorio de Apariencias de Wikimedia.
Scripts y estilos
Valores predeterminados
Una apariencia requiere como mínimo un único módulo ResourceLoader de estilo definido en el archivo skin.json de la apariencia. Se parecerá un poco a esto:
"ResourceModules": {
"skins.example": {
"class": "ResourceLoaderSkinModule",
"features": { "normalize": true },
"styles": [ "resources/skins.example.less" ]
}
},
La tecla features te permite usar útiles valores por defecto para una variedad de cosas incluyendo i18n y normalize que están documentados en la MediaWiki core php documentation. Las características pueden ser un array de claves (política opt-in) o en MW 1.36 un array asociativo (política opt-out, recomendada). Si no está seguro, omita la tecla de características para utilizar los valores predeterminados recomendados.
CSS y LESS
El skin.json es un manifiesto de todos los activos que utiliza tu apariencia.
Bajo la clave `ResourceModules` deberías encontrar el módulo de estilo para tu apariencia listado bajo `skins.example`.
Aquí, bajo la key "styles" puedes añadir archivos LESS o CSS.
Se cargarán en el orden en que aparecen en la lista.
Con LESS puede utilizar sentencias @import
en la misma carpeta.
Puede encontrar más información sobre las posibilidades en Desarrollando con ResourceLoader.
Cuando utilice imágenes, debería poder utilizar URI relativas para acceder a los activos de imagen.
= Variables de Apariencia en MediaWiki
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 .
- Valores predeterminados neutros – 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.
- Personalización – Aunque no puedes modificar los nombres de las variables, podrías definir otras adicionales en archivos específicos para cada apariencia. In every Less file, you can import the skin's values by only
@import 'mediawiki.skin.variables.less';
- Beneficios de la centralización – Toda la definición de variables para el tema por defecto de Wikimedia y toda la nomenclatura está centralizada con el fin de
- Establecer una nomenclatura coherente para mayor claridad y uniformidad.
- Compatibilidad entre distintas apariencias y extensiones
- Proporcionar información sobre las posibles deficiencias o áreas de mejora en función de los patrones de uso habituales.
Se recomienda a los autores de apariencias que se familiaricen con estas actualizaciones para maximizar el potencial de sus apariencias.
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.
Tenga en cuenta que las apariencias Vector 2022, Vector legacy y MinervaNeue utilizan los dos temas predeterminados de Codex para las interfaces de usuario de Wikimedia, que también están representados en el sitio de documentación del Codex.
Más de 45 apariencias y extensiones diferentes ya utilizan las variables de apariencia en MW 1.41.
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();
}
}
Apariencias responsivas / añadiendo meta viewport
Si estás creando una apariencia responsiva, asegúrate de utilizar la opción de apariencia responsive cuando declares tu apariencia en 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>
Imágenes
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.
Más avanzado
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;
}
}
Default styling via the SkinModule class
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" ]
}
}
Integración con otras extensiones
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 Extensión:Echo . To do this you will need to read Manual:$wgResourceModuleSkinStyles .
Cambios del contenido del menú
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:
- Manual:$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.
Tus comentarios son importantes
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.