Widget:CardGallery: Difference between revisions

From Makerpedia

No edit summary
No edit summary
 
(61 intermediate revisions by 2 users not shown)
Line 29: Line 29:
         });
         });


         function hideSpinner(){ $('#card-gallery .loadDial').hide();}
         function hideSpinner(){ $('#card-gallery .loadDial').hide()};
 
        function loadCategory(category,offset){
            new mw.Api().get({
                action: 'query',
                list: 'categorymembers',
                cmtitle: 'Category:' + category.name,
                cmlimit: 5,
                cmcontinue: offset,
                format: 'json'
            }).done(function (data) {
                var pages = data.query.categorymembers;
                var galleryHtml = '';
                //console.log(data);
                if(data.continue) loadCategory(category, data.continue.cmcontinue);
                pages.forEach(function (page) {
                    var pageUrl = mw.util.getUrl(page.title);
                    var imgUrl = '';
                    $('.gallery-container').append(generateGalleryItem(pageUrl, page.title, imgUrl, category));
                    //pageTitles.push(page.title);
                    hideSpinner();
                    let card = µ('.gallery-container .gallery-item:last-child img')[0];
                    new mw.Api().get({
                        action: 'parse',
                        page: page.title
                    }).done(function (pageData) {
                        //const parser = new DOMParser();
                        //const htmlDoc = parser.parseFromString(pageData.parse.text['*'], 'text/xml');
                        console.log(pageData.parse.text['*']);
                        let src = /<(?:img|figure).*?src=(?:'|")([^"'<>]*?)(?<!null)(?:'|").*?>/.exec(pageData.parse.text['*'])
                        console.log(src);
                        if(src != null){
                                if(src[1] != 'null' && card.src.includes("No-Image")) return card.src = src[1];
                        }
                        //card.src = µ('figure img',htmlDoc)[0].getAttribute('src');
                    });
                });
            });
        }


         // load gallery based on category
         // load gallery based on category
Line 35: Line 73:
              
              
             let pageTitles = [];
             let pageTitles = [];
             galleryContainer.html("<div class='loadDial'><p>Retrieving Data...</p><div class='loadSpinner'></div></div>");
             galleryContainer.html("<div class='loadDial'><p>Retrieving Data...</p><div class='loadSpinner'></div></div>");
             // insert projects corresponding to each skill under broader category filter selected
             // insert projects corresponding to each skill under broader category filter selected
Line 40: Line 79:
             if(category == "<!--{$type|escape:'url'}-->") filterCats = [{name:"<!--{$type|escape:'url'}-->"}];
             if(category == "<!--{$type|escape:'url'}-->") filterCats = [{name:"<!--{$type|escape:'url'}-->"}];
             filterCats.forEach(function(cat) {
             filterCats.forEach(function(cat) {
                 new mw.Api().get({
                 loadCategory(cat,0);
                    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 = '';
                        $('.gallery-container').append(generateGalleryItem(pageUrl, page.title, imgUrl, category));
                        pageTitles.push(page.title);
                        let card = µ('.gallery-container .gallery-item:last-child img')[0];
                        return new mw.Api().get({
                            action: 'parse',
                            page: page.title
                            //action: 'query',
                            //rvprop: 'content',
                            //prop: 'revisions',
                            //titles: page.title,
                            //format: 'json'
                        }).done(function (pageData) {
console.log(pageData);
                            //var pageId = Object.keys(pageData.query.pages)[0];
                            //var content = pageData.query.pages[pageId].revisions[0]['*'];
                            var content = pageData;
 
                            // 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.src = imgUrl;
                                    //$('.gallery-container').append(generateGalleryItem(pageUrl, page.title, imgUrl, category));
                                    //galleryHtml += generateGalleryItem(pageUrl, page.title, imgUrl, category);
                                });
                            }
                        });
                    });
 
                Promise.all(requests).then(function () {
                    //$('.gallery-container').append(galleryHtml);
                });
                });
             });
             });
         }
         }

Latest revision as of 16:18, 21 June 2025

<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()};
       function loadCategory(category,offset){
           new mw.Api().get({
               action: 'query',
               list: 'categorymembers',
               cmtitle: 'Category:' + category.name,
               cmlimit: 5,
               cmcontinue: offset,
               format: 'json'
           }).done(function (data) {
               var pages = data.query.categorymembers;
               var galleryHtml = ;
               //console.log(data);
               if(data.continue) loadCategory(category, data.continue.cmcontinue);
               pages.forEach(function (page) {
                   var pageUrl = mw.util.getUrl(page.title);
                   var imgUrl = ;
                   $('.gallery-container').append(generateGalleryItem(pageUrl, page.title, imgUrl, category));
                   //pageTitles.push(page.title);
                   hideSpinner();
                   let card = µ('.gallery-container .gallery-item:last-child img')[0];
                   new mw.Api().get({
                       action: 'parse',
                       page: page.title
                   }).done(function (pageData) {
                       //const parser = new DOMParser();
                       //const htmlDoc = parser.parseFromString(pageData.parse.text['*'], 'text/xml');
                       console.log(pageData.parse.text['*']);
                       let src = /<(?:img|figure).*?src=(?:'|")([^"'<>]*?)(?<!null)(?:'|").*?>/.exec(pageData.parse.text['*'])
                       console.log(src);
                       if(src != null){ 
                               if(src[1] != 'null' && card.src.includes("No-Image")) return card.src = src[1];
                       }
                       //card.src = µ('figure img',htmlDoc)[0].getAttribute('src');
                   });
               });
           });
       }
       // 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) {
               loadCategory(cat,0);
           });
       }
       // generate a gallery
       function generateGalleryItem(pageUrl, title, imgUrl, category) {
           return `
           `;
       }
       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>