Extension:PhotoSwipe
![]() Release status: beta |
|
---|---|
Implementation | Tag |
Description | Provides a front-endf JavaScript image gallery and lightbox using PhotoSwipe |
Author(s) | Jason Khanlar (Jasonkhanlartalk) |
Latest version | 1.0.0 |
MediaWiki | >= 1.37.2 |
PHP | 7.4.x |
Database changes | No |
Composer | mediawiki/photoswipe |
License | GNU General Public License 3.0 or later |
Download | |
|
|
Quarterly downloads | 2 (Ranked 138th) |
Translate the PhotoSwipe extension if it is available at translatewiki.net | |
Issues | Open tasks · Report a bug |
The PhotoSwipe extension provides a front-end JavaScript image gallery and lightbox using Photoswipe.
Installation
edit- Download and move the extracted
PhotoSwipe
folder to yourextensions/
directory.
Developers and code contributors should install the extension from Git instead, using:cd extensions/
git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/PhotoSwipe - Only when installing from Git, run Composer to install PHP dependencies, by issuing
composer install --no-dev
in the extension directory. (See task T173141 for potential complications.) - Add the following code at the bottom of your LocalSettings.php file:
wfLoadExtension( 'PhotoSwipe' );
- run
./bin/build.sh
ornpm run build-lib
to prepopulate the JS libraries. - Configure as required.
- Done – Navigate to Special:Version on your wiki to verify that the extension is successfully installed.
Configuration
edit$wgPhotoSwipeConfig
edit
This defines values for each section of configuration. $wgPhotoSwipeConfig
</tvar> is an associative array of mixed values, with each sub-value having zero or more of the following parameters.
parameter | type | description |
mode | string | Adjusts the usage of PhotoSwipe library. Possible values: ['recommended'](https://photoswipe.com/getting-started/#initialization), ['withoutDynamicImport'](https://photoswipe.com/getting-started/#without-dynamic-import), ['withoutLightbox'](https://photoswipe.com/data-sources/#without-lightbox-module) |
options | object | The options object passed into the PhotoSwipeLightbox instance.
|
addBeginning | string | Additional JavaScript to add in the beginning. |
array of strings | An array of strings of JavaScript to add. | |
addEventables | string | Additional JavaScript to add in the middle. |
array of strings | An array of strings of JavaScript to add. | |
addEnd | string | Additional JavaScript to add in the end. |
array of strings | An array of strings of JavaScript to add. | |
plugins | array of strings | An array of strings of names of plugins to enable with default options. See PhotoSwipeVendorList .
|
object of options | An object of keys of plugins to enable with custom options. The values are the options object passed to the plugin library.
|
For example, in your LocalSettings.php: (note: make sure to \ escape all $ in string values containing JavaScript)
all-in-one associative array
edit$wgPhotoSwipeConfig = [
"mode" => "recommended",
"options" => [
"gallery" => "table.gallery",
"children" => "a.img",
"thumbSelector" => "a.img",
"pswpModule" => "() => require( 'js.photoswipe' )",
// Recommended PhotoSwipe options for this plugin
"allowPanToNext" => false, // prevent swiping to the next slide when image is zoomed
"allowMouseDrag" => true, // display dragging cursor at max zoom level
"wheelToZoom" => true, // enable wheel-based zoom
"zoom" => false // disable default zoom button
],
"addBeginning" => [
"document.querySelectorAll( 'table.gallery img' ).forEach( ( e, i ) => {
if ( e.parentElement.tagName !== 'A' ) {
document.querySelectorAll( 'img' )[ i ].outerHTML = `<a class='img' href='\${e.src}'; data-my-size='\${e.naturalWidth}x\${e.naturalHeight}'>\${e.outerHTML}</a>`;
}
} );"
],
"addEventables" => [
"const backEasing = {
in: 'cubic-bezier(0.6, -0.28, 0.7, 1)',
out: 'cubic-bezier(0.3, 0, 0.32, 1.275)',
inOut: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)'
}",
"lightbox.on( 'firstUpdate', () => { lightbox.pswp.options.easing = backEasing.out; } );",
"lightbox.on( 'initialZoomInEnd', () => { lightbox.pswp.options.easing = backEasing.inOut; } );",
"lightbox.on( 'close', () => { lightbox.pswp.options.easing = backEasing.in; } );",
"lightbox.addFilter( 'domItemData', ( itemData, element, linkEl ) => {
if ( linkEl ) {
const sizeAttr = linkEl.dataset.mySize;
itemData.src = linkEl.href;
itemData.w = Number( sizeAttr.split( 'x' )[ 0 ] );
itemData.h = Number( sizeAttr.split( 'x' )[ 1 ] );
itemData.msrc = linkEl.dataset.thumbSrc;
itemData.thumbCropped = true;
}
return itemData;
} );"
],
"addEnd" => [],
"plugins" => [
"DeepZoomPlugin" => [
"enabled" => true,
"options" => [
"tileSize" => 256
]
],
"DynamicCaption" => [
"enabled" => true,
"options" => [
"captionContent" => ".pswp-caption-content",
"horizontalEdgeThreshold" => 20,
"mobileCaptionOverlapRatio" => 0.3,
"mobileLayoutBreakpoint" => 600,
"type" => "auto"
]
],
"VideoPlugin" => [
"enabled" => true,
"options" => []
]
]
];
individual key values of associative array
edit$wgPhotoSwipeConfig["mode"] = "recommended";
$wgPhotoSwipeConfig["options"]["gallery"] = "table.gallery";
$wgPhotoSwipeConfig["options"]["children"] = "a.img";
$wgPhotoSwipeConfig["options"]["thumbSelector"] = "a.img";
$wgPhotoSwipeConfig["options"]["pswpModule"] = "() => require( 'js.photoswipe' )";
// Recommended PhotoSwipe options for this plugin
$wgPhotoSwipeConfig["options"]["allowPanToNext"] = false; // prevent swiping to the next slide when image is zoomed
$wgPhotoSwipeConfig["options"]["allowMouseDrag"] = true; // display dragging cursor at max zoom level
$wgPhotoSwipeConfig["options"]["wheelToZoom"] = true; // enable wheel-based zoom
$wgPhotoSwipeConfig["options"]["zoom"] = false; // disable default zoom button
$wgPhotoSwipeConfig["addBeginning"] = [
"document.querySelectorAll( 'table.gallery img' ).forEach( ( e, i ) => {
if ( e.parentElement.tagName !== 'A' ) {
document.querySelectorAll( 'img' )[ i ].outerHTML = `<a class='img' href='\${e.src}'; data-my-size='\${e.naturalWidth}x\${e.naturalHeight}'>\${e.outerHTML}</a>`;
}
} );"
];
$wgPhotoSwipeConfig["addEventables"] = [
"const backEasing = {
in: 'cubic-bezier(0.6, -0.28, 0.7, 1)',
out: 'cubic-bezier(0.3, 0, 0.32, 1.275)',
inOut: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)'
}",
"lightbox.on( 'firstUpdate', () => { lightbox.pswp.options.easing = backEasing.out; } );",
"lightbox.on( 'initialZoomInEnd', () => { lightbox.pswp.options.easing = backEasing.inOut; } );",
"lightbox.on( 'close', () => { lightbox.pswp.options.easing = backEasing.in; } );",
"lightbox.addFilter( 'domItemData', ( itemData, element, linkEl ) => {
if ( linkEl ) {
const sizeAttr = linkEl.dataset.mySize;
itemData.src = linkEl.href;
itemData.w = Number( sizeAttr.split( 'x' )[ 0 ] );
itemData.h = Number( sizeAttr.split( 'x' )[ 1 ] );
itemData.msrc = linkEl.dataset.thumbSrc;
itemData.thumbCropped = true;
}
return itemData;
} );"
];
$wgPhotoSwipeConfig["addEnd"] = [];
$wgPhotoSwipeConfig["plugins"]["DeepZoomPlugin"]["enabled"] = true;
$wgPhotoSwipeConfig["plugins"]["DeepZoomPlugin"]["options"]["tileSize"] = 256;
$wgPhotoSwipeConfig["plugins"]["DynamicCaption"]["enabled"] = true;
$wgPhotoSwipeConfig["plugins"]["DynamicCaption"]["options"]["captionContent"] = ".pswp-caption-content";
$wgPhotoSwipeConfig["plugins"]["DynamicCaption"]["options"]["horizontalEdgeThreshold"] = 20;
$wgPhotoSwipeConfig["plugins"]["DynamicCaption"]["options"]["mobileCaptionOverlapRatio"] = 0.3;
$wgPhotoSwipeConfig["plugins"]["DynamicCaption"]["options"]["mobileLayoutBreakpoint"] = 600;
$wgPhotoSwipeConfig["plugins"]["DynamicCaption"]["options"]["type"] = "auto";
$wgPhotoSwipeConfig["plugins"]["VideoPlugin"]["enabled"] = true;
$wgPhotoSwipeConfig["plugins"]["VideoPlugin"]["options"] = [];
Usage
editNote: Images and gallery content not included.
Use extension configuration by default
edit<photoswipe/>
Use argument configuration (overrides extension configuration)
edit<photoswipe
mode=recommended
options="{
"gallery": "table.gallery",
"children": "a.img",
"thumbSelector": "a.img",
"pswpModule": "() => require('js.photoswipe')",
"allowPanToNext": false,
"allowMouseDrag": true,
"wheelToZoom": true,
"zoom": false
}"
addBeginning="document.querySelectorAll( 'table.gallery img' ).forEach( ( e, i ) => {
if ( e.parentElement.tagName !== 'A' ) {
document.querySelectorAll( 'img' )[ i ].outerHTML = `<a class='img' href="${e.src}" data-my-size="${e.naturalWidth}x${e.naturalHeight}">${e.outerHTML}</a>`;
}
} );"
addEventables="[
"const backEasing = { in: 'cubic-bezier(0.6, -0.28, 0.7, 1)', out: 'cubic-bezier(0.3, 0, 0.32, 1.275)', inOut: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)' }",
"lightbox.on( 'firstUpdate', () => { lightbox.pswp.options.easing = backEasing.out; } );",
"lightbox.on( 'initialZoomInEnd', () => { lightbox.pswp.options.easing = backEasing.inOut; } );",
"lightbox.on( 'close', () => { lightbox.pswp.options.easing = backEasing.in; } );",
"lightbox.addFilter( 'domItemData', ( itemData, element, linkEl ) => { if ( linkEl ) { const sizeAttr = linkEl.dataset.mySize; itemData.src = linkEl.href; itemData.w = Number( sizeAttr.split( 'x' )[ 0 ] ); itemData.h = Number( sizeAttr.split( 'x' )[ 1 ] ); itemData.msrc = linkEl.dataset.thumbSrc; itemData.thumbCropped = true; } return itemData; } );"
]"
addEnd="[]"
plugins="{
"DeepZoomPlugin": {
"enabled": true,
"options": {
"tileSize": 256
}
},
"DynamicCaption": {
"enabled": true,
"options": {
"captionContent": ".pswp-caption-content",
"horizontalEdgeThreshold": 20,
"mobileCaptionOverlapRatio": 0.3,
"mobileLayoutBreakpoint": 600,
"type": "auto"
}
},
"VideoPlugin": {
"enabled": true,
"options": {}
}
}"
/>
Use content configuration (overrides extension configuration and argument configuration)
editNote: Comments and multi-line strings are permitted here
<photoswipe>
{
"mode": "recommended",
"options": {
"gallery": "table.gallery",
"children": "a.img",
"thumbSelector": "a.img",
"pswpModule": "() => require( 'js.photoswipe' )",
// Recommended PhotoSwipe options for this plugin
"allowPanToNext": false, // prevent swiping to the next slide when image is zoomed
"allowMouseDrag": true, // display dragging cursor at max zoom level
"wheelToZoom": true, // enable wheel-based zoom
"zoom": false // disable default zoom button
},
"addBeginning": [
"document.querySelectorAll( 'table.gallery img' ).forEach( ( e, i ) => {
if ( e.parentElement.tagName !== 'A' ) {
document.querySelectorAll( 'img' )[ i ].outerHTML = `<a class='img' href='${e.src}'; data-my-size='${e.naturalWidth}x${e.naturalHeight}'>${e.outerHTML}</a>`;
}
} );"
],
"addEventables": [
"const backEasing = {
in: 'cubic-bezier(0.6, -0.28, 0.7, 1)',
out: 'cubic-bezier(0.3, 0, 0.32, 1.275)',
inOut: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)'
}",
"lightbox.on( 'firstUpdate', () => { lightbox.pswp.options.easing = backEasing.out; } );",
"lightbox.on( 'initialZoomInEnd', () => { lightbox.pswp.options.easing = backEasing.inOut; } );",
"lightbox.on( 'close', () => { lightbox.pswp.options.easing = backEasing.in; } );",
"lightbox.addFilter( 'domItemData', ( itemData, element, linkEl ) => {
if ( linkEl ) {
const sizeAttr = linkEl.dataset.mySize;
itemData.src = linkEl.href;
itemData.w = Number( sizeAttr.split( 'x' )[ 0 ] );
itemData.h = Number( sizeAttr.split( 'x' )[ 1 ] );
itemData.msrc = linkEl.dataset.thumbSrc;
itemData.thumbCropped = true;
}
return itemData;
} );"
],
"addEnd": [],
"plugins": {
"DeepZoomPlugin": {
"enabled": true,
"options": {
"tileSize": 256
}
},
"DynamicCaption": {
"enabled": true,
"options": {
"captionContent": ".pswp-caption-content",
"horizontalEdgeThreshold": 20,
"mobileCaptionOverlapRatio": 0.3,
"mobileLayoutBreakpoint": 600,
"type": "auto"
}
},
"VideoPlugin": {
"enabled": true,
"options": {}
}
}
}
</photoswipe>