Manual:ResourceLoaderImageModule.php
This page is outdated. |
MediaWiki file: ResourceLoaderImageModule.php | |
---|---|
Location: | includes/resourceloader/ |
Source code: | master • 1.42.4 • 1.41.5 • 1.39.11 |
Classes: | ResourceLoaderImageModule |
MediaWiki version: | ≤ 1.38 |
Removed by MW 1.39. See now Manual:ImageModule.php .
Embedded images
[edit]When you reference images in CSS or LESS files, you can indicate that ResourceLoader should automatically create inline data URIs for them.
See @embed
documentation.
Generating icons from SVG files
[edit]SVG (Scalable Vector Graphics) files are preferable to raster images because they are resolution-independent. However, browser support for them varies, so you need to provide a raster image as a fallback.
ResourceLoaderImageModule:
- abstracts the implementation of SVG and fallback images in CSS
- generates the fallback image on-the-fly from the SVG
- intelligently chooses the appropriate image for right-to-left and different languages according to your specification
- generates multiple colored images from a single SVG according to your specification.
To use it, in your module definition (in extension.json
or skin.json
or the old PHP entry point), you specify at a minimum:
class
:"ResourceLoaderImageModule"
images
: a set of"name": "path/to/icon.svg"
file mappings- a specification for the name of the CSS rule for each image, either
- a
prefix
to put in front of each name as.prefix-name
, or selector
, a CSS selector name which includes the placeholder{name}
- a
ResourceLoader generates a CSS class rule for each image that specifies the icon as the background-image
property for a selector and includes a fallback raster image.
For example, the Thanks extension's extension.json
includes
"ext.thanks.images": {
"class": "ResourceLoaderImageModule",
"selector": ".mw-ui-icon-thanks-{name}:before",
"defaultColor": "#fff",
"images": {
"userTalk": {
"file": {
"ltr": "userTalk-ltr.svg",
"rtl": "userTalk-rtl.svg"
}
}
}
},
When you request or depend on the ext.thanks.images
ResourceLoader module, it generates a CSS file that specifies the SVG as the background-image for the selector .mw-ui-icon-thanks-userTalk:before
.
In other words the response to https://en.wikipedia.org/w/load.php?modules=ext.thanks.images&only=styles (reformatted for clarity) is:
.mw-ui-icon-thanks-userTalk:before{
background-image:url(/w/load.php?modules=ext.thanks.images&image=userTalk&format=rasterized&lang=qqx&skin=fallback&version=1bpun);
background-image:linear-gradient(transparent,transparent),url("data:image/svg+xml,%3Csvg […SVG content…] %3C/svg%3E")
}
Recent browsers will use the SVG embedded as a data URI, and others will fall back to requesting the rasterized background image, which ResourceLoader generates on-the-fly by converting the SVG to a PNG.
SVG conversion to raster
[edit]To convert the SVG original to a PNG raster image, ResourceLoader uses the same $wgSVGConverter
that you configure to create raster images of SVG files uploaded to the wiki (as in File:Example.svg). On Wikimedia wikis this is rsvg
, which has some extra optimizations, but any converter will work.
Identifying different icons
[edit]If you need to use a different icon for right-to-left languages,, you can specify different icons in the images
key. Instead of a simple "name": "path/to/icon.svg"
mapping for each icon name, for each name you provide a file
key with different icons for ltr
and rtl
.
ResourceLoader determines the text direction according to the lang
parameter to the load request, and uses the appropriate icon.
For example (in PHP):
'mobile.swipe.images' => array(
'prefix' => 'mw-ui',
'images' => array(
'previous' => array(
'file' => array(
'ltr' => 'images/icons/move-rtl.svg',
'rtl' => 'images/icons/move-ltr.svg',
),
),
...
),
the CSS rule for .mw-ui-previous
will use the appropriate SVG as the background image according to the direction of lang.
Similarly, if the icon is different in different languages (such as 'B' for Bold becomes 'G' in French), you can specify in the file
key a default icon and then icons for particular languages.
For example (in JSON):
"bold": { "file": {
"default": "images/icons/bold-a.svg",
"lang": {
"ar": "images/icons/bold-arab-ain.svg",
"be": "images/icons/bold-cyrl-te.svg",
"cs,en,he,ml,pl": "images/icons/bold-b.svg",
"da,de,hu,ksh,nn,no,sv": "images/icons/bold-f.svg",
"es,gl,pt": "images/icons/bold-n.svg",
"eu,fi": "images/icons/bold-l.svg",
"fa": "images/icons/bold-arab-dad.svg",
"fr,it": "images/icons/bold-g.svg",
...
} },
Variants
[edit]The MediaWiki theme uses color to convey meaning, for example "destructive" operations appear red, and "progressive" operations that are part of a sequence of steps appear blue. See Intention colors in the Living style guide. Or you may want to define a gray variant, or an inverted white-on-black icon.
Instead of creating a set of nearly-identical icons for each color, ResourceLoader can generate these different icons as variants, as both SVG and raster images, from a single source SVG,
The way you indicate what variants to provide is by specifying a variants
key and for each variant, give its color
. Then rather than a simple selector
key, you specify selectorWithVariant
which has a {variant}
placeholder as well as a {name}
placeholder; you can also provide a selectorWithoutVariant
key.
ResourceLoaderImageModule
creates a CSS rule for each variant of each name, and applies the color of the variant to the SVG.
(To do so the ResourceLoaderImage
class wraps the SVG with a new group and sets the fill color.)
In order to make a given image available in a given variant, either the variant must be defined as global
, or the image definition must specify allowed variants. Since each variant requires some additional data to be sent to user's browser, variants shouldn't be made global unless you actually use each of the images in each of the variants.
For example, the MobileFrontend defines the following module, using global variants:
"skins.minerva.icons.images.variants": {
"selectorWithoutVariant": ".mw-ui-icon-{name}:before",
"selectorWithVariant": ".mw-ui-icon-{name}-{variant}:before",
"class": "ResourceLoaderImageModule",
"prefix": "mw-ui",
"variants": {
"gray": {
"color": "#a2a9b1",
"global": true
},
"invert": {
"color": "#fff",
"global": true
}
},
"images": {
"clock": "resources/skins.minerva.icons.images.variants/clock.svg",
"arrow": "resources/skins.minerva.icons.images.variants/arrow.svg"
}
},
The above is equivalent to the following, without global variants:
"skins.minerva.icons.images.variants": {
"selectorWithoutVariant": ".mw-ui-icon-{name}:before",
"selectorWithVariant": ".mw-ui-icon-{name}-{variant}:before",
"class": "ResourceLoaderImageModule",
"prefix": "mw-ui",
"variants": {
"gray": {
"color": "#a2a9b1"
},
"invert": {
"color": "#fff"
}
},
"images": {
"clock": {
"file": "resources/skins.minerva.icons.images.variants/clock.svg",
"variants": [ "gray", "invert" ]
},
"arrow": {
"file": "resources/skins.minerva.icons.images.variants/arrow.svg",
"variants": [ "gray", "invert" ]
},
}
},
Note: if you only need one color of an icon that is different from the variant you can use the defaultColor.
"skins.minerva.icons.images.variants": {
"selector": ".mw-ui-icon-{name}:before",
"class": "ResourceLoaderImageModule",
"defaultColor": "#fff",
"images": {
"clock": "resources/skins.minerva.icons.images.variants/clock.svg"
}
},
Loading data from separate JSON file
[edit]ResourceLoaderImageModule can also load the module definition (all options except the required "class": "ResourceLoaderImageModule"
) from a separate JSON file, which can be convenient if the list gets too long. Any options in the module definition override options from the JSON file.
extension.json
|
icons/badgeicons.json
|
---|---|
"ext.echo.badgeicons": {
"class": "ResourceLoaderImageModule",
"data": "icons/badgeicons.json",
"selector": ".mw-echo-icon-{name}"
}
|
{
"images": {
"bell": {
"file": "icons/bell.svg"
},
"tray": {
"file": "icons/tray.svg"
}
}
}
|
Note that the paths to images in the separate JSON file must be the same as if they were in extension.json – they are not relative to that file.
SVG coding conventions and best practices
[edit]- SVGs need to be optimized to reduce their size and thus the size of ResourceLoader responses, just as you optimize raster images.
- Wikimedia products follow SVG coding conventions, relying on SVGO optimizer tool and manual optimization.
- In order for ResourceLoader variant color generation to work, the SVG should not set the color explicitly (f.e. via
fill
orstyle
for any shape, otherwise that color won't change.
OOUI images
[edit]The MediaWiki theme of OOUI defines dozens of icons: see icons in the OOUI Demos and icon guidelines in the Wikimedia Design Style Guide.
When clients request OOUI support with $out->enableOOUI()
, it adds ResourceLoader resources such as 'oojs-ui.styles.icons' to the page.
Since phab:T92551 MediaWiki generates the CSS definition of these icons from SVG.
To further reduce boilerplate code, it generates sets of icons from JSON files containing the icon information, using a specialized class ResourceLoaderOOUIImageModule
.
Using OOUI images
[edit]If you want to use one of these icons in your own code,
- find the icon you want in the demos or style guide above, e.g. the "block" icon
- see if it has a variant with the intention color you want, if any, e.g. destructive block. (If the icon is not available in the color you want, you have to access the SVGs and create your own ResourceLoaderImageModule.)
- find the image set that contains it; in this case it's in the "moderation" set.
- express a dependency on the ResourceLoader module for the image set 'oojs-ui.styles.icons-setname'; in this case it's 'oojs-ui.styles.icons-moderation'
Now that the necessary styles will be loaded, you can use the icon:
- apply the classes
mw-ui-icon
and one ofmw-ui-icon-element
ormw-ui-icon-before
to the div or span where you want icons - apply the class
mw-ui-icon-name
ormw-ui-icon-name-variant
to choose the icon to use; in this case it'smw-ui-icon-block-destructive
.
The icons can also be shown using OOUI widgets:
- load OOUI: see OOUI/Using OOUI in MediaWiki
- display an IconWidget:
- JavaScript:
$( document.body ).append( new OO.ui.IconWidget( { icon: 'block', flags: 'destructive' } ).$element );
- PHP:
$this->getOutput()->addHTML( new OOUI\IconWidget( [ 'icon' => 'block', 'flags' => 'destructive', ] ) );
- JavaScript:
See also
[edit]- Design/WikiFont packages similar icons as a font. This is used by the Android and iOS Wikipedia applications, which can rely on well-defined operating system support for per-application fonts.