Widget:CardGallery
From Makerpedia
<script> var cardWidget = {};
cardWidgetStart = function () {
$(document).ready(function () {
var sortCats = window[""];
var superCats = Array.from(new Set(sortCats.map(x=>x.super)));
var Category = pageParams['filter'] ? pageParams['filter'] : ""; // If no filter query in url, use default category type
var galleryContainer = $('#card-gallery');
galleryContainer.before('
');
var addFilterButton = (cat) => {
var nextBut = µ('+button',µ('#category-filter'));
nextBut.id = cat+'-filter-btn';
nextBut.textContent = cat;
nextBut.className = 'filter-btn';
nextBut.setAttribute('data-filter',cat);
sortCats.forEach((el,ind)=>{
if(el.super == cat && el.image) µ('+img', nextBut).src = el.image;
});
return nextBut;
}
var allBut = addFilterButton("");
allBut.textContent = 'Show All';
superCats.forEach(el=>{
addFilterButton(el);
});
function hideSpinner(){ $('#card-gallery .loadDial').hide();}
// load gallery based on category
function loadGallery(category) {
let pageTitles = [];
galleryContainer.html("
Retrieving Data...
");
// insert projects corresponding to each skill under broader category filter selected
var filterCats = sortCats.filter(el=>el.super == category);
if(category == "") filterCats = [{name:""}];
filterCats.forEach(function(cat) {
new mw.Api().get({
action: 'query',
list: 'categorymembers',
cmtitle: 'Category:' + cat.name,
cmlimit: 50,
format: 'json'
}).done(function (data) {
var pages = data.query.categorymembers;
var galleryHtml = ;
var requests = pages.map(function (page) {
var pageUrl = mw.util.getUrl(page.title);
var imgUrl = 'https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg" alt="No Image Available"';
let card = $('.gallery-container').append(generateGalleryItem(pageUrl, page.title, imgUrl, category)).find('.gallery-item:last');
return new mw.Api().get({
action: 'query',
prop: 'revisions',
rvprop: 'content',
titles: page.title,
format: 'json'
}).done(function (pageData) {
var pageId = Object.keys(pageData.query.pages)[0];
var content = pageData.query.pages[pageId].revisions[0]['*'];
// Try to find a direct image URL (img1=https://...)
var directMatch = content.match(/img1=(https:\/\/[^\s|}%]+)/);
if (directMatch) {
imgUrl = directMatch[1];
}
// If no direct URL, try to find a File:... entry
var fileMatch = content.match(/\[\[File:([^|\]]+)/);
if (!imgUrl && fileMatch) {
var fileName = fileMatch[1].trim();
// Fetch full image URL from MediaWiki API
return new mw.Api().get({
action: 'query',
titles: 'File:' + fileName,
prop: 'imageinfo',
iiprop: 'url',
format: 'json'
}).then(function (imageData) {
var imagePageId = Object.keys(imageData.query.pages)[0];
if (imageData.query.pages[imagePageId].imageinfo) {
imgUrl = imageData.query.pages[imagePageId].imageinfo[0].url;
}
hideSpinner();
card.find('.thumbs').attr('src',imgUrl);
//$('.gallery-container').append(generateGalleryItem(pageUrl, page.title, imgUrl, category));
//galleryHtml += generateGalleryItem(pageUrl, page.title, imgUrl, category);
});
} else {
// Add the gallery item if the image was found and is not already being shown
if(!pageTitles.includes(page.title)) {
//galleryHtml += generateGalleryItem(pageUrl, page.title, imgUrl, category);
hideSpinner();
//$('.gallery-container').append(generateGalleryItem(pageUrl, page.title, imgUrl, category));
pageTitles.push(page.title);
card.find('.thumbs').attr('src',imgUrl);
}
}
});
});
Promise.all(requests).then(function () {
//$('.gallery-container').append(galleryHtml);
});
});
});
}
// generate a gallery
function generateGalleryItem(pageUrl, title, imgUrl, category) {
return `
<a href="${pageUrl}">
${imgUrl ? `<img class="thumbs" src="${imgUrl}" alt="${title}">` : `<img src="https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg" alt="No Image Available">`}
</a>
<a href="${pageUrl}">${title}</a>
`;
}
loadGallery(Category);
// find filter button corresponding to selected category and add css class 'selected-filter'
$(".filter-btn").each(function () { $(this).data("filter") === Category ? $(this).addClass('selected-filter') : null});
// when filter button is clicked, load projects for that category, deselect current filtered button, and select newly clicked filter button
$(".filter-btn").click(function () {
var selectedCategory = $(this).data("filter");
loadGallery(selectedCategory);
$('.filter-btn.selected-filter').each((i, elem) => $(elem).removeClass('selected-filter'));
$(this).addClass('selected-filter');
});
});
};
if(!window.widgets) window.widgets = []; window.widgets.push(cardWidgetStart); </script> <style>
.filter-btn img{
height:1.5em;
padding-left:.4em;
}
.gallery-item {
width: 20%; min-width:200px; max-width: 30vw; margin: 10px; flex-grow: 2;
}
.loadDial {
width: 100%;
text-align: center;
p {
font-weight: bolder;
font-size: x-large;
color: #666;
}
}
</style>