Module documentation
This module allows article excerpt (from Module:Excerpt) to be put into a slideshow (using Module:Random slideshow). It is intended to be used in portals.
The following templates use this module:
- {{Transclude excerpts as random slideshow}}
- {{Transclude linked excerpts as random slideshow}}
- {{Transclude list item excerpts as random slideshow}}
Tracking categories
The following categories track use where the "Selected general articles" list is built solely from templates:
- Category:Automated portals with article list built solely from one template (population: 0)
- Category:Automated portals with article list built solely from two templates (population: 0)
- Category:Automated portals with article list built solely from three templates (population: 0)
- Usages with more than three templates are not currently tracked
Pages where the "Selected general articles" list is built from a list embeded in the portal:
- Category:Automated portals with embedded list (population: 0)
Note that the Category:Automated portals with embedded list was enabled on 19 April 2019, and it will probably take a few days for all the portal pages to update
Testcases
The following testcase pages are available for testing changes made to this module's sandbox:
- Template:Transclude excerpts as random slideshow/testcases
- Template:Transclude linked excerpts as random slideshow/testcases
- Template:Transclude list item excerpts as random slideshow/testcases
See also
local p = {}local excerptModule = require('Module:Excerpt/portals')local slideshowModule = require('Module:Random slideshow')local randomModule = require('Module:Random')local DEFAULT_LIMIT = 25 -- max number of excerpts to be shown in the slideshowlocal SOURCE_PAGES_LIMIT = 10 -- max number of pages to check for links / list items-- begin BHG addition for tracking source pageslocal sourcepgagesused = {};local sourcepgagesusedcounter = 0;local articlelistcount = -1;local usesEmbeddedList = false;-- end BHG addition for tracking source pagesfunction cleanupArgs(argsTable)local cleanArgs = {}for key, val in pairs(argsTable) doif type(val) == 'string' thenval = val:match('^%s*(.-)%s*$')if val ~= '' thencleanArgs[key] = valendelsecleanArgs[key] = valendendreturn cleanArgsendfunction isDeclined(val)if not val then return false endlocal declinedWords = " decline declined exclude excluded false none not no n off omit omitted remove removed "return string.find(declinedWords , ' '..val..' ', 1, true ) and true or falseend--[[@param {String} wikitext: Wikitext of just the list (i.e. each line is a list item)@param {String} symbol: Special character used in the wikitext markup for the list, e.g. '*' or '#'@param {String} outerTag: Text portion of the tag for each list or sublist, e.g. 'ul' or 'ol'@param {String} innerTag: Text portion of the tag for each list item, e.g. 'li']]local wikitextToHtmlList = function(wikitext, symbol, outerTag, innerTag)local listParts = {}for level, item in mw.ustring.gmatch('\n'..wikitext..'\n', '\n(%'..symbol..'+)(.-)%f[\n]') do table.insert(listParts, {level=level, item=item})endtable.insert(listParts, {level='', item=''})local htmlList = {}for i, this in ipairs( listParts ) dolocal isFirstItem = (i == 1)local isLastItem = (i == #listParts) local lastLevel = isFirstItem and '' or listParts[i-1]['level'] local tags if #lastLevel == #this.level then tags = '</'..innerTag..'><'..innerTag..'>' elseif #this.level > #lastLevel then tags = string.rep('<'..outerTag..'><'..innerTag..'>', #this.level - #lastLevel) elseif isLastItem then tags = string.rep('</'..innerTag..'></'..outerTag..'>', #lastLevel) else -- ( #this.level < #lastLevel ) and not last item tags = string.rep('</'..innerTag..'></'..outerTag..'>', #lastLevel - #this.level ) .. '</'..innerTag..'><'..innerTag..'>' end table.insert(htmlList, tags .. this.item)endreturn table.concat(htmlList)end--[[@param {String} wikitext: Wikitext excertp containg zero or more lists@param {String} symbol: Special character used in the wikitext markup for the list, e.g. '*' or '#'@param {String} outerTag: Text portion of the tag for each list or sublist, e.g. 'ul' or 'ol'@param {String} innerTag: Text portion of the tag for each list item, e.g. 'li']]local gsubWikitextLists = function(wikitext, symbol, outerTag, innerTag)-- temporarily remove list linebreaks... wikitext = mw.ustring.gsub(wikitext..'\n', '\n%'..symbol, '¿¿¿'..symbol) -- ...so we can grab the whole list (and just the list)...return mw.ustring.gsub(wikitext,'¿¿¿%'..symbol..'[^\n]+', function(listWikitext)-- ...and then reinstate linebreaks...listWikitext = mw.ustring.gsub(listWikitext, '¿¿¿%'..symbol, '\n'..symbol)-- ...and finally do the conversionreturn wikitextToHtmlList(listWikitext, symbol, outerTag, innerTag)end)end--[[ help gsub strip tables and templates that aren't part of the prose, and remove linebreaks from within other templates, and preprocess parser functions ]]local processBraces = function(t)local isTable = mw.ustring.sub(mw.text.trim(t), 2, 2) == '|'if isTable thenreturn ''end-- else it's a template or parser functionlocal first = mw.ustring.sub(t, 1, 1)local last = mw.ustring.sub(t, -1)local isNotPartOfProse = first == '\n' and last == '\n'if isNotPartOfProse thenreturn ''endlocal isParserFunction = mw.ustring.sub(mw.text.trim(t), 3, 3) == '#'if isParserFunction thenlocal frame = mw.getCurrentFrame()return frame:preprocess(t)end-- else remove internal linebreaksreturn mw.ustring.gsub(t, '\n*', '')endlocal cleanUpExcerpt = function(excerpt)-- strip galleriesexcerpt = mw.ustring.gsub(excerpt, "<%s*[Gg]allery.->.-<%s*/%s*[Gg]allery%s*>", "")-- strip tables and block templates; strip newlinesexcerpt = mw.ustring.gsub(excerpt..'\n', '\n?%b{}\n?', processBraces)-- replace wikitext bulleted lists with html bulleted listsexcerpt = gsubWikitextLists(excerpt, '*', 'ul', 'li')-- replace wikitext numbered lists with html numbered listsexcerpt = gsubWikitextLists(excerpt, '#', 'ol', 'li')excerpt = mw.text.trim(excerpt)return excerptendfunction makeGalleryArgs(titles, options, limit, nonRandom)local galleryArgs = {}local titlesSequence = {}local i = 1while titles[i] dotitlesSequence[i] = titles[i]i = i + 1endlocal sortedTitles = nonRandom and titlesSequence or randomModule.main('array', {t=titlesSequence, limit=limit})for _i, title in ipairs(sortedTitles) doif (#galleryArgs / 2) < limit thenlocal success, excerpt = pcall(excerptModule.get, title, options)if not success thenmw.log("require('Module:Excerpt').get failed: " .. excerpt) -- probably got a redlinkexcerpt = nilendif excerpt and excerpt ~= '' and #excerpt > 10 then -- check again in case we had a few characters plus (Full article...)excerpt = cleanUpExcerpt(excerpt)if options.more thenexcerpt = excerpt .. " ('''[[" .. title .. "|" .. options.more .. "]]''')"endlocal text = '<div style="text-align:left;">' .. mw.ustring.gsub(excerpt, '%c', '<br>') .. '</div>'table.insert(galleryArgs, 'File:Blank.png')table.insert(galleryArgs, text)endendendif nonRandom thengalleryArgs.random = 'false'endif #galleryArgs == 0 and options.nostubs then-- try again, this time including stubsoptions.nostubs = falsereturn makeGalleryArgs(titles, options, limit, nonRandom)elsereturn galleryArgsendendlocal makeOptions = function(args)local options = args -- pick up miscellaneous options: more, errors, fileargsoptions.paraflags = excerptModule.numberFlags(args.paragraphs or "") -- parse paragraphs, e.g. "1,3-5" → {"1","3-5"}options.fileflags = excerptModule.numberFlags(args.files or "") -- parse file numbersif args.nostubs and isDeclined(args.nostubs) thenoptions.nostubs = falseelse options.nostubs = trueendreturn optionsendlocal isArticle = function(pagetitle)local titleObject = mw.title.new(pagetitle)return ( titleObject and titleObject.namespace == 0 ) and true or falseendlocal getLinkedTitles = function(args, method, limit)local pagenames = {}local ii = 1local isNotCategorywhile args[ii] and ii < limit dolocal pageContent = excerptModule.getContent(args[ii])if pageContent thenlocal pageSection = args["section"..ii] or args["section"]local sectionOnly = args["sectiononly"..ii] or args["sectiononly"]local text = pageContentif pageSection then -- check relevant section onlylocal success, result = pcall(excerptModule.getSection, pageContent, pageSection, sectionOnly)if not success thenmw.log("require('Module:Excerpt').getSection failed on the content of " .. args[ii] .. ": " .. result)result = nilendtext = result or pageContentend-- begin BHG addition for tracking source pageslocal thisPage = mw.title.getCurrentTitle().nsText .. ":" .. mw.title.getCurrentTitle().textlocal thisBareParam = mw.ustring.gsub(args[ii], "^([^#]+).*$", "%1", 1) -- strip any section anchor from the parameter's page nameif (thisPage == thisBareParam) thenusesEmbeddedList = true;end-- end BHG addition for tracking source pages-- replace annotated links with real linkstext = mw.ustring.gsub(text, "{{%s*[Aa]nnotated[ _]link%s*|%s*(.-)%s*}}", "[[%1]]")if method == "linked" thenfor p in mw.ustring.gmatch(text, "%[%[%s*([^%]|\n]*)") doif isArticle(p) thentable.insert(pagenames, p)endendelse-- listitem: first wikilink on a line beginning *, :#, etc. except in "See also" or later sectiontext = mw.ustring.gsub(text, "\n== *See also.*", "")for p in mw.ustring.gmatch(text, "\n:*[%*#][^\n]-%[%[%s*([^%]|\n]*)") doif isArticle(p) thentable.insert(pagenames, p)endendend-- begin BHG addition for tracking source pagesif ((method == "listitem") or (method == "linked")) thentable.insert(sourcepgagesused, args[ii])sourcepgagesusedcounter = sourcepgagesusedcounter + 1end-- end BHG addition for tracking source pagesendii = ii + 1end-- begin BHG addition for trackingarticlelistcount = #pagenames-- end BHG addition for trackingreturn pagenamesend-- Template entry points:-- randomExcerpt: Titles specified in template parameters (equivalent to {{Transclude random excerpt}})p.randomExcerpt = function(frame)local parent = frame.getParent(frame)local output = p._excerpt(parent.args, 'random')return frame:extensionTag{ name='templatestyles', args = { src='Module:Random slideshow/styles.css'} } .. frame:preprocess(output)end-- linkedExcerpt: Titles from links on one or more pages (similar to {{Transclude linked excerpt}})p.linkedExcerpt = function(frame)local parent = frame.getParent(frame)local output = p._excerpt(parent.args, 'linked')return frame:extensionTag{ name='templatestyles', args = { src='Module:Random slideshow/styles.css'} } .. frame:preprocess(output)end-- listItemExcerpt: Titles from linked list items one one or more pages (similar to {{Transclude list item excerpt}})p.listItemExcerpt = function(frame)local parent = frame.getParent(frame)local output = p._excerpt(parent.args, 'listitem')return frame:extensionTag{ name='templatestyles', args = { src='Module:Random slideshow/styles.css'} } .. frame:preprocess(output)end-- Module entry point:p._excerpt = function(_args, method)local args = cleanupArgs(_args)args.more = excerptModule.getMoreLinkText(_args.more)local options = makeOptions(args)local limit = args.limit and tonumber(args.limit) or DEFAULT_LIMITlocal titlesif method == 'linked' or method == 'listitem' thentitles = getLinkedTitles(args, method, SOURCE_PAGES_LIMIT)elsetitles = argsendlocal galleryArgs = makeGalleryArgs(titles, options, limit, isDeclined(_args.random))return slideshowModule._main(galleryArgs, false, 'excerptSlideshow-container') .. checksourcepages()endp._cleanUpExcerpt = cleanUpExcerpt-- begin BHG addition for tracking source pagesfunction checksourcepages()-- no tracking unless we are in Portal namespaceif (mw.title.getCurrentTitle().nsText ~= "Portal") thenreturn ""endlocal pagecounter = 0;local templatecount = 0;local outlinecount = 0;local retval ="";local usesEponymousArticle = false;local debugging = false;local thisPageBareName = mw.title.getCurrentTitle().text;if debugging thenretval = '<div style="display:block; border:10px solid green; background-color:#efe; padding:1em; margin:1em">\n----\n'retval = retval .. "sourcepgagesusedcounter: " .. sourcepgagesusedcounter .. "\n----\n"retval = retval .. "pages used:"endlocal apagefor apage in arrayvalues(sourcepgagesused) doif debugging then retval = retval .. "\n# [[:" .. apage .. "]]"retval = retval .. " — " .. "First 999 = /" .. string.sub(apage, 1, 999) .. "/"endif (string.find(apage, "^[tT]emplate ?:") == 1) thentemplatecount = templatecount + 1;endif (string.find(apage, "^[oO]utline +of ") == 1) thenoutlinecount = outlinecount + 1;endif (apage == thisPageBareName) thenusesEponymousArticle = true;endpagecounter = pagecounter + 1endif debugging thenretval = retval .. "\nTotal pages: " .. pagecounterretval = retval .. "\ntemplatecount: " .. templatecountretval = retval .. "</div>"end-- first do a sanity check that both counting methods have produced the same resultif (sourcepgagesusedcounter == pagecounter) then-- if all pages are templates, then populate tracking categoriesif (pagecounter == templatecount) thenif (templatecount == 1) thenretval = retval .. "[[Category:Automated article-slideshow portals with article list built solely from one template]]"elseif (templatecount == 2) thenretval = retval .. "[[Category:Automated article-slideshow portals with article list built solely from two templates]]"elseif (templatecount == 3) thenretval = retval .. "[[Category:Automated article-slideshow portals with article list built solely from three templates]]"elseif (templatecount > 3) thenretval = retval .. "[[Category:Automated article-slideshow portals with article list built solely from four or more templates]]"endelseif (templatecount > 0) thenretval = retval .. "[[Category:Automated article-slideshow portals with article list built using one or more templates, and other sources]]"endendif (outlinecount >= 1) thenretval = retval .. "[[Category:Automated article-slideshow portals with article list built using one or more outline pages]]"endif (articlelistcount < 2) thenretval = retval .. "[[Category:Automated article-slideshow portals with less than 2 articles in article list]]"elseif (articlelistcount <= 5) thenretval = retval .. "[[Category:Automated article-slideshow portals with 2–5 articles in article list]]"elseif (articlelistcount <= 10) thenretval = retval .. "[[Category:Automated article-slideshow portals with 6–10 articles in article list]]"elseif (articlelistcount <= 15) thenretval = retval .. "[[Category:Automated article-slideshow portals with 11–15 articles in article list]]"elseif (articlelistcount <= 20) thenretval = retval .. "[[Category:Automated article-slideshow portals with 16–20 articles in article list]]"elseif (articlelistcount <= 25) thenretval = retval .. "[[Category:Automated article-slideshow portals with 21–25 articles in article list]]"elseif (articlelistcount <= 30) thenretval = retval .. "[[Category:Automated article-slideshow portals with 26–30 articles in article list]]"elseif (articlelistcount <= 40) thenretval = retval .. "[[Category:Automated article-slideshow portals with 31–40 articles in article list]]"elseif (articlelistcount <= 50) thenretval = retval .. "[[Category:Automated article-slideshow portals with 41–50 articles in article list]]"elseif (articlelistcount <= 100) thenretval = retval .. "[[Category:Automated article-slideshow portals with 51–100 articles in article list]]"elseif (articlelistcount <= 200) thenretval = retval .. "[[Category:Automated article-slideshow portals with 101–200 articles in article list]]"elseif (articlelistcount <= 500) thenretval = retval .. "[[Category:Automated article-slideshow portals with 201–500 articles in article list]]"elseif (articlelistcount <= 1000) thenretval = retval .. "[[Category:Automated article-slideshow portals with 501–1000 articles in article list]]"elseif (articlelistcount > 1000) thenretval = retval .. "[[Category:Automated article-slideshow portals with over 1000 articles in article list]]"endif usesEmbeddedList thenretval = retval .. "[[Category:Automated article-slideshow portals with embedded list]]"endif usesEponymousArticle thenretval = retval .. "[[Category:Automated article-slideshow portals with article list built using eponymous article]]"endreturn retvalendfunction arrayvalues(t)local i = 0return function() i = i + 1; return t[i] endend-- end BHG addition for tracking source pagesreturn p
🔥 Top keywords: Main PageSpecial:SearchIndian Premier LeagueWikipedia:Featured picturesPornhubUEFA Champions League2024 Indian Premier LeagueFallout (American TV series)Jontay PorterXXXTentacionAmar Singh ChamkilaFallout (series)Cloud seedingReal Madrid CFCleopatraRama NavamiRichard GaddDeaths in 2024Civil War (film)Shōgun (2024 miniseries)2024 Indian general electionJennifer PanO. J. SimpsonElla PurnellBaby ReindeerCaitlin ClarkLaverne CoxXXX (film series)Facebook2023–24 UEFA Champions LeagueYouTubeCandidates Tournament 2024InstagramList of European Cup and UEFA Champions League finalsJude BellinghamMichael Porter Jr.Andriy LuninCarlo AncelottiBade Miyan Chote Miyan (2024 film)