Module:Languages

function language_subpages( frame, transform, options ) local args, pargs, options = frame.args, ( frame:getParent or {} ).args or {}, options or {}; local title = args.page or args[1] or pargs.page or pargs[1] or ""; local abort = options.abort or {}; local at, clock = type( abort.on ), os.clock; local ac = function if at == 'function' or ( at == 'table' and getmetatable(abort.on).__call ) then abort.on; end end local tt = type( transform ); local page = require( 'Module:Page' ); title = page.clean(title); if tt == 'function' or ( tt == 'table' and getmetatable(transform).__call ) then local fetch, pages, langcode, langname = mw.language.fetchLanguageName, {}; for pg in page.subpages( title, { ignoreNS=true } ) do           if abort.cycles then abort.cycles = abort.cycles - 1 if 0 == abort.cycles then return ac end end if abort.time then if (os.clock - clock) > abort.time then return ac end end if mw.ustring.len( pg ) <= 12 then langcode = string.lower( pg ); langname = fetch( langcode ); if langname ~= '' then table.insert( pages, transform( title, pg, langcode, langname ) ); end end end return pages; end return {}; end

local p = {};

function p.internal(frame) pages = language_subpages( frame, function( title, page, code, name )       return mw.ustring.format( ' %s ', code, code, code, title, page, name );   end); return table.concat( pages, ' · ' ); end

function p.external(frame) pages = language_subpages( frame, function( title, page, code, name )       return mw.ustring.format( ' [%s/%s %s] ', code, code, code, tostring( mw.uri.fullUrl( title ) ), page:gsub( ' ', '_' ), name );   end); return table.concat( pages, ' | ' ); end

--[=[ forEachLanguage This function iterates over all language codes known to MediaWiki based on a maintained list replacing patterns in a pattern-string for each language Usage:

Parameters pattern: A pattern string which is processed for each language and which is concatenated at the end and returned as one string before: A string that is inserted before the concatenated result after: A string that is inserted after the concatenated result sep: A string that is inserted between each line created from the pattern while iterating (like ProcessedPattern_sep_ProcessedPattern_sep_ProcessedPattern) inLang: Langcode to use for $lnTrP and $lnTrUC1 Patterns: $lc - language code such as en or de   $lnP - language name in own language $lnUC1 - language name in own language, first letter upper case $lnTrP - language name translated to the language requested by language code passed to inLang $lnTrUC1 - language name translated to the language requested by language code passed to inLang, first letter upper case Example ]=]

-- =p.forEachLanguage({ args= { pattern = "$lc - $lnTrP\n", inLang = "en" } }) function p.forEachLanguage(frame) local l = require( "Module:Languages/List" ) local ret = {} local lang   = mw.language local contentLangInstance = mw.language.getContentLanguage local langInstance = contentLangInstance --Quota hit here otherwise local fetch  = lang.fetchLanguageName local line local pattern = frame.args.pattern  or frame.args[1] or "" local before = frame.args.before    or frame.args[2] or "" local after  = frame.args.after     or frame.args[3] or "" local sep    = frame.args.separator or frame.args[4] or "" local inLang = frame.args.inLang    or frame.args[5] or nil local langName local langNameUCFirst local langNameTranslated local langNameTranslatedUCFirst local langNameUCFirstReq = not not pattern:find( "$lnUC1", 1, true ) local langNameReq = not not pattern:find( "$lnP", 1, true ) or langNameUCFirstReq local langNameTranslatedUCFirstReq = not not pattern:find( "$lnTrUC1", 1, true ) local langNameTranslatedReq = not not pattern:find( "$lnTrP", 1, true ) or langNameTranslatedUCFirstReq for k, v in pairs( l.list ) do        line = pattern:gsub( "$lc", v ) if langNameReq then langName = fetch( v ) line = line:gsub( "$lnP", langName ) end if langNameUCFirstReq then --langInstance = mw.getLanguage( v ) --Quota hit here langNameUCFirst = langInstance:ucfirst( langName ) line = line:gsub( "$lnUC1", langNameUCFirst ) end if langNameTranslatedReq and inLang then langNameTranslated = fetch( v, inLang ) line = line:gsub( "$lnTrP", langNameTranslated ) end if langNameTranslatedUCFirstReq and inLang then --if not langInstance then langInstance = mw.getLanguage( v ) end --Quota hit here langNameTranslatedUCFirst = langInstance:ucfirst( langNameTranslated ) line = line:gsub( "$lnTrUC1", langNameTranslatedUCFirst ) --langInstance = nil end -- Don't know why ret:insert( line ) throws >>attempt to call method 'insert' (a nil value)<< table.insert(ret, line) end return before .. table.concat( ret, sep ) .. after end

--[=[ Provide logic for Template:Lle (Language Links external, to be substituted) ]=] function p.lle(frame) local ret local pattern = "[ $lnUC1]" ret = p.forEachLanguage({ args= { pattern = pattern } }) ret = frame:preprocess(ret) return ret end

--[=[ Provide logic for Template:Ll (Language Links, to be substituted) ]=] function p.ll(frame) local ret local pattern = "/$lc$lnUC1" ret = p.forEachLanguage({ args= { pattern = pattern } }) ret = frame:preprocess(ret) return ret end

--- Different approaches for Template:Lang links ---

--[=[ Provide logic for Template:Lang links Using a cute Hybrid-Method: First check the subpages which is quite fast; if there are too many fall back to checking for each language page individually ]=]

-- =p.langLinksNonExpensive({ args= { page='Commons:Picture of the Year/2010' }, getParent=function end }) -- =p.langLinksNonExpensive({ args= { page='Main Page' }, getParent=function end }) -- =p.langLinksNonExpensive({ args= { page='Template:No_source_since' }, getParent=function end }) -- =p.langLinksNonExpensive({ args= { page='MediaWiki:Gadget-HotCat' }, getParent=function end }) function p.langLinksNonExpensive(frame) local contentLangInstance = mw.language.getContentLanguage; local pages2 local options = { abort= { time=1, on=function pages2 = p.langLinksUsingLinks( frame ) end } } local pages = language_subpages( frame, function( basepagename, subpagename, code, langname )       return mw.ustring.format( ' %s | ', code, code, code, basepagename, subpagename, contentLangInstance:ucfirst( langname ) )   end, options ); return table.concat( pages2 or pages, '' ); end

--[=[ Provide logic for Template:Lang links (Language Links,    creating wikilinks and parsing them to find out whether pages exist for Expensive-Parser-Function-Quota reasons      is not used and LUA page objects are not created) ]=] -- =p.langLinksUsingLinks({ args= { page='Template:No_source_since' }, getParent=function end }) function p.langLinksUsingLinks(frame) local contentLangInstance = mw.language.getContentLanguage -- Get the current page or the supplied one local args, pargs = frame.args, ( frame:getParent or {} ).args or {} local title = args.page or args[1] or pargs.page or pargs[1] or "" -- Load required modules local M_page = require( 'Module:Page' ); local M_link = require( 'Module:Link' ); title = M_page.clean(title); if not title then return "" end -- Generate the Wikitext we will parse as links (to bypass the expensive parser function limit) local pattern = '$lc' local wikitext = p.forEachLanguage( { args= { pattern = pattern } } ) local fetch   = mw.language.fetchLanguageName -- Iterate over all links we created and return the concatenated result local ret = M_link.forEachLink( wikitext,        function(linkInfo)            if linkInfo.red then return '' end            return mw.ustring.format( ' %s | ', linkInfo.text, linkInfo.text, linkInfo.text, title, linkInfo.text, contentLangInstance:ucfirst( fetch( linkInfo.text ) ))       end     ); return ret end return p;