MediaWiki:Gadget-cards.js
Appearance
Oharra: Gorde ondoren zure nabigatzailearen katxea ekidin beharko duzu aldaketak ikusteko. Mozilla / Firefox / Safari: Shift tekla sakatu birkargatzeko momentuan, edo Ctrl-Shift-R sakatu (Cmd-Shift-R Apple Mac baten); IE: Ctrl tekla sakatu birkargatzeko momentuan, edo Ctrl-F5 sakatu; Konqueror:: Birkargatzeko klik egin, edo F5 sakatu, besterik ez; Opera erabiltzaileek Tresnak-Hobespenak atalera jo eta katxea garbitzeko aukera hautatu.
const { CdxCard, CdxMessage } = require( '@wikimedia/codex' );
const Vue = require( 'vue' );
const CardWidget = {
components: {
CdxCard
},
props: {
titles: {
type: Array
}
},
template: `<div>
<cdx-card v-for="titleObj in titles" :thumbnail="titleObj.thumbnail" :url="titleObj.url"
:force-thumbnail="true">
<template #title>
{{ titleObj.title }}
</template>
<template #description>
{{ titleObj.description }}
</template>
</cdx-card>
</div>`
}
const mwApi = new mw.Api();
/**
* @param {Object} obj
* @return {Card}
*/
function toCard( originalTitleObj ) {
return ( obj ) => Object.assign( {}, originalTitleObj[obj.title.replace(/ /g, '_') ], {
url: mw.util.getUrl( obj.title ),
title: obj.title,
id: obj.title,
description: obj.description,
thumbnail: obj.thumbnail ? Object.assign( {}, obj.thumbnail, {
url: obj.thumbnail.source
} ) : undefined
} );
}
function getPages( titleObjs ) {
const titleMap = {};
titleObjs.forEach((obj) => titleMap[obj.title] = obj);
return mwApi.ajax( {
action: 'query',
format: 'json',
origin: '*',
titles: titleObjs.map( ( titleObj ) => titleObj.title ),
prop: 'coordinates|info|pageimages|description',
inprop: 'url',
formatversion: 2,
pprop: 'displaytitle',
piprop: 'thumbnail',
pithumbsize: 150,
pilimit: 50
} ).then( function ( data ) {
return data.query.pages.map( toCard( titleMap ) ).sort( ( a, b ) => a.rank < b.rank ? -1 : 1 );
} );
}
const titleExpand = ( titles ) => {
return getPages( titles );
};
const ErrorWidget = {
components: {
CdxMessage
},
props: {
message: String
},
template: `<cdx-message type="error">
<p><strong>Orain ezin da atal hau kargatu. Arazoaren azalpena hemen azpian duzu.</strong></p> <p>{{ message }}</p></cdx-message>
</div>`
};
function renderError( target, message ) {
Vue.createApp( ErrorWidget, {
message
} ).mount( target );
}
function loadPageViews( target, url, exclude, limit ) {
$.get( url )
.then((data) => {
titleExpand(
data.items[0].articles.map((a) => ( {
title: a.article,
rank: a.rank
}) )
.filter((a) => !a.title.includes('Berezi') && !exclude.includes(a.title))
.slice(0, limit)
).then( ( titles ) => {
Vue.createApp( CardWidget, {
titles
} ).mount( target )
})
}, ( error ) => {
let message;
try {
const r = JSON.parse( error.responseText );
message = r.detail;
if ( message.indexOf( 'ez dago daturik data horretarako' ) > -1 ) {
// @todo: translate
message = 'Ez dago daturik data horretarako';
}
} catch ( e ) {
message = 'Unknown';
}
renderError( target, message );
} );
}
Array.from(document.querySelectorAll( '[data-component="cards"]' )).forEach((node) => {
const dataset = node.dataset;
const targetId = dataset.target;
const type = dataset.apiType;
const target = targetId ? document.getElementById( targetId ) : node;
const limit = dataset.limit ? parseInt( dataset.limit, 10 ) : 10;
const excludeList = dataset.exclude ? dataset.exclude.split('|') : [];
if ( !target ) {
renderError( node, 'Widget is not setup correctly (missing render target)' );
return;
}
switch ( type ) {
case 'nearby':
if ( targetId === 'mw-nearby-pages' ) {
mw.loader.using( 'ext.nearby.scripts' );
} else {
console.warn( 'Please set targets to "mw-nearby-pages" to use this widget');
}
break;
case 'pageviews':
if ( dataset.url.indexOf( 'https://' ) === 0 ) {
console.warn( 'URL should be relative e.g. begin with /api/rest_v1/metrics/pageviews/' );
} else {
loadPageViews( target, `https://wikimedia.org${dataset.url}`, excludeList, limit );
}
break;
default:
console.warn( 'Type not implemented' );
}
});