Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions Lua banner/main.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
-- This module implements the {{lua}} template.
local yesno = require('Module:Yesno')
local mList = require('Module:List')
local mTableTools = require('Module:TableTools')
local mMessageBox = require('Module:Message box')

local p = {}

function p.main(frame)
local origArgs = frame:getParent().args
local args = {}
for k, v in pairs(origArgs) do
v = v:match('^%s*(.-)%s*$')
if v ~= '' then
args[k] = v
end
end
return p._main(args)
end

function p._main(args)
local modules = mTableTools.compressSparseArray(args)
local box = p.renderBox(modules)
local trackingCategories = p.renderTrackingCategories(args, modules)
return box .. trackingCategories
end

function p.renderBox(modules)
local boxArgs = {}
if #modules < 1 then
boxArgs.text = '<strong class="error">Error: no modules specified</strong>'
else
local moduleLinks = {}
for i, module in ipairs(modules) do
moduleLinks[i] = string.format('[[:%s]]', module)
local maybeSandbox = mw.title.new(module .. '/sandbox')
if maybeSandbox.exists then
moduleLinks[i] = moduleLinks[i] .. string.format(' ([[:%s|sandbox]])', maybeSandbox.fullText)
end
end
local moduleList = mList.makeList('bulleted', moduleLinks)
local title = mw.title.getCurrentTitle()
if title.subpageText == "doc" then
title = title.basePageTitle
end
if title.contentModel == "Scribunto" then
boxArgs.text = 'This module depends on the following other modules:' .. moduleList
else
boxArgs.text = 'This template uses [[BKDatabase:Lua|Lua]]:\n' .. moduleList
end
end
boxArgs.type = 'notice'
boxArgs.small = true
boxArgs.image = '[[File:Lua-Logo.svg|30px|alt=|link=]]'
return mMessageBox.main('mbox', boxArgs)
end

function p.renderTrackingCategories(args, modules, titleObj)
if yesno(args.nocat) then
return ''
end

local cats = {}

-- Error category
if #modules < 1 then
cats[#cats + 1] = 'Lua templates with errors'
end

-- Lua templates category
titleObj = titleObj or mw.title.getCurrentTitle()
local subpageBlacklist = {
doc = true,
sandbox = true,
sandbox2 = true,
testcases = true
}
if not subpageBlacklist[titleObj.subpageText] then
local protCatName
if titleObj.namespace == 10 then
local category = args.category
if not category then
local categories = {
['Module:String'] = 'Templates based on the String Lua module',
['Module:Math'] = 'Templates based on the Math Lua module',
['Module:BaseConvert'] = 'Templates based on the BaseConvert Lua module',
['Module:Citation/CS1'] = 'Templates based on the Citation/CS1 Lua module'
}
category = modules[1] and categories[modules[1]]
category = category or 'Lua-based templates'
end
cats[#cats + 1] = category
protCatName = "Templates using under-protected Lua modules"
elseif titleObj.namespace == 828 then
protCatName = "Modules depending on under-protected modules"
end
if not args.noprotcat and protCatName then
local protLevels = {
autoconfirmed = 1,
extendedconfirmed = 2,
templateeditor = 3,
sysop = 4
}
local currentProt
if titleObj.id ~= 0 then
-- id is 0 (page does not exist) if am previewing before creating a template.
currentProt = titleObj.protectionLevels["edit"][1]
end
if currentProt == nil then currentProt = 0 else currentProt = protLevels[currentProt] end
for i, module in ipairs(modules) do
if module ~= "WP:libraryUtil" then
local moduleProt = mw.title.new(module).protectionLevels["edit"][1]
if moduleProt == nil then moduleProt = 0 else moduleProt = protLevels[moduleProt] end
if moduleProt < currentProt then
cats[#cats + 1] = protCatName
break
end
end
end
end
end
for i, cat in ipairs(cats) do
cats[i] = string.format('[[Category:%s]]', cat)
end
return table.concat(cats)
end

return p
30 changes: 30 additions & 0 deletions Testcases/Includes.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
-- Unit tests for [[Module:{{ROOTPAGENAME}}]]. Click talk page to run tests.
local p = require('Module:UnitTests')

-- Example unit test.
function p:test_hello()
local includes = require('Module:Includes')

-- These will return true
self:equals('includes({"a", "b", "c", "d"}, "b")', includes({"a", "b", "c", "d"}, "b"), true)
self:equals('includes({"a", "b", "c", "d"}, "b", 0)', includes({"a", "b", "c", "d"}, "b", 0), true)
self:equals('includes({"a", "b", "c", "d"}, "b", 1)', includes({"a", "b", "c", "d"}, "b", 1), true)
self:equals('includes({"a", "b", "c", "d"}, "b", 2)', includes({"a", "b", "c", "d"}, "b", 2), true)
self:equals('includes({"a", "b", "c", "d"}, "b", -3)', includes({"a", "b", "c", "d"}, "b", -3), true)
self:equals('includes({"a", "b", "c", "d"}, "b", -5)', includes({"a", "b", "c", "d"}, "b", -5), true)
self:equals('includes({[1] = "a",[100] = "b",[101] = "c"}, "b")', includes({[1] = "a",[100] = "b",[101] = "c"}, "b"), true)
self:equals('includes({[1] = "a",[2] = "b",[3] = "c"}, "b", 0)', includes({[1] = "a",[2] = "b",[3] = "c"}, "b", 0), true)
self:equals('includes({first = "a", second = "b", third = "c"}, "b")', includes({first = "a", second = "b", third = "c"}, "b"), true)

--these will return false
self:equals('includes("b","b")', includes("b","b"), false) -- array is not a table
self:equals('includes({"a", "b", "c", "d"})', includes({"a", "b", "c", "d"}), false) -- value missing
self:equals('includes({"a", "b", "c", "d"}, "e")', includes({"a", "b", "c", "d"}, "e"), false) -- "e" is not in array
self:equals('includes({"a", "b", "c", "d"}, "b", 3)', includes({"a", "b", "c", "d"}, "b", 3), false) -- "b" is before position 3
self:equals('includes({"a", "b", "c", "d"}, "b", 5)', includes({"a", "b", "c", "d"}, "b", 5), false) -- 5 is larger than #array
self:equals('includes({"a", "b", "c", "d"}, "b", -2)', includes({"a", "b", "c", "d"}, "b", -2), false) -- "b" is not in the last two positions
self:equals('includes({[1] = "a", [100] = "b", [101] = "c"}, "b", 0)', includes({[1] = "a", [100] = "b", [101] = "c"}, "b", 0), false) -- key 100 is non-consecutive
self:equals('includes({first = "a", second = "b", third = "c"}, "b", 0)', includes({first = "a", second = "b", third = "c"}, "b", 0), false) -- key "second" is not an integer
end

return p
43 changes: 43 additions & 0 deletions Testcases/Infobox.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
-- Ví dụ các trường hợp kiểm thử đơn vị cho [[Mô đun:Infobox]]. Nhấn vào trang thảo luận để
-- chạy các trường hợp kiểm thử.
local p = require('Mô đun:UnitTests')

function p:test_hello()
self:preprocess_equals_preprocess_many('{{infobox/sandbox', '}}', '{{Infobox', '}}', {
{[=[
|label1 = Nhãn 1
|data1 = Dữ liệu 1
]=]},
}, {nowiki = 'yes'})
end

function p:test_ids()
self:preprocess_equals_preprocess_many('{{infobox/sandbox', '}}', '{{Infobox', '}}', {
{[=[
|label2 = Nhãn 2
|labelid2 = lable
|data2 = Dữ liệu 2
|dataid2 = data
|rowid1 = row
|header1 = Đầu đề 1
|headerid1 = header
]=]},
}, {nowiki = 'yes'})
end

function p:test_ids_name()
self:preprocess_equals_preprocess_many('{{infobox/sandbox', '}}', '{{Infobox', '}}', {
{[=[
|name = qw er tz
|label2 = Nhãn 2
|labelid2 = lable
|data2 = Dữ liệu 2
|dataid2 = data
|rowid1 = row
|header1 = Đầu đề 1
|headerid1 = header
]=]},
}, {nowiki = 'yes'})
end

return p
109 changes: 109 additions & 0 deletions Testcases/InfoboxImage.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
-- Unit tests for [[Module:InfoboxImage]]. Click talk page to run tests.

local p = require('Module:UnitTests')

function p:test1_parameters_output()
self:preprocess_equals_preprocess_many('{{#invoke:InfoboxImage/sandbox |InfoboxImage |image=', '}}', '{{#invoke:InfoboxImage |InfoboxImage |image=', '}}', {
{'Small Sailboat Image.jpg |alt=Alt'},
{'Small Sailboat Image.jpg |border=yes'},
{'Small Sailboat Image.jpg |center=yes'},
{'Small Sailboat Image.jpg |link=Link'},
{'Small Sailboat Image.jpg |thumbtime=Thumbtime'},
{'Small Sailboat Image.jpg |title=Title'},
{'Small Sailboat Image.jpg |size=75'},
{'Small Sailboat Image.jpg |size=200'},
{'Small Sailboat Image.jpg |size=200|sizedefault=260|maxsize=275'},
{'Small Sailboat Image.jpg |size=400|sizedefault=260|maxsize=275'},
{'Small Sailboat Image.jpg |sizedefault=260|maxsize=275'},
{'Small Sailboat Image.jpg |maxsize=275'},
{'Small Sailboat Image.jpg |maxsize=275|sizedefault=frameless'},
{'[[File:Small Sailboat Image.jpg]]'},
{'Mustela erminea upright.jpg'},
{'Mustela erminea upright.jpg |upright=1'},
{'Mustela erminea upright.jpg |upright=yes'},
{'Mustela erminea upright.jpg |upright=0.75'},
{'Mustela erminea upright.jpg |upright=1.2'},
{'Mustela erminea upright.jpg |upright=1|maxsize=275'},
{'Mustela erminea upright.jpg |upright=1|maxsize=275|sizedefault=frameless'},
{'Mustela erminea upright.jpg |upright=1|sizedefault=260|maxsize=275'},
{'Mustela erminea upright.jpg |upright=1.5|sizedefault=260|maxsize=275'},
{'Mustela erminea upright.jpg |upright=1|size=200|sizedefault=260|maxsize=275'},
{'Mustela erminea upright.jpg |upright=1|size=|sizedefault=|maxsize='},
{'Replace this image.svg |suppressplaceholder=no'},
{'Replace this image.svg'},
{'The Universal Magazine, Vol. XCV (July 1794).djvu |page=8'},
{'[[File:Abbey Rd Studios.jpg|200px]]'},
{'[[File:Abbey Rd Studios.jpg|thumb]]'},
{'[[File:Abbey Rd Studios.jpg|thumb|caption]]'},
{'Http-fakezarathustra.blogspot.com-2010-10-12 31.html http-fakezarathustra.blogspot.com-2010-10-22 31.html - panoramio.jpg'},
{'Abbey Rd Studios.jpg|alt=http:test.com'},
{'Abbey Rd Studios.jpg|alt=[http:test.com]'},
{'Abbey Rd Studios.jpg|class=notpageimage'},
})
end

function p:test2_parameters_nowiki()
self:preprocess_equals_preprocess_many('{{#invoke:InfoboxImage/sandbox |InfoboxImage |image=', '}}', '{{#invoke:InfoboxImage|InfoboxImage |image=', '}}', {
{'Small Sailboat Image.jpg |alt=Alt'},
{'Small Sailboat Image.jpg |border=yes'},
{'Small Sailboat Image.jpg |center=yes'},
{'Small Sailboat Image.jpg |link=Link'},
{'Small Sailboat Image.jpg |thumbtime=Thumbtime'},
{'Small Sailboat Image.jpg |title=Title'},
{'Small Sailboat Image.jpg |size=75'},
{'Small Sailboat Image.jpg |size=200'},
{'Small Sailboat Image.jpg |size=200|sizedefault=260|maxsize=275'},
{'Small Sailboat Image.jpg |size=400|sizedefault=260|maxsize=275'},
{'Small Sailboat Image.jpg |sizedefault=260|maxsize=275'},
{'Small Sailboat Image.jpg |maxsize=275'},
{'Small Sailboat Image.jpg |maxsize=275|sizedefault=frameless'},
{'Small Sailboat Image.jpg |size=20%|sizedefault=10em'},
{'[[File:Small Sailboat Image.jpg]]'},
{'Mustela erminea upright.jpg'},
{'Mustela erminea upright.jpg |upright=1'},
{'Mustela erminea upright.jpg |upright=yes'},
{'Mustela erminea upright.jpg |upright=0.75'},
{'Mustela erminea upright.jpg |upright=1.2'},
{'Mustela erminea upright.jpg |upright=1|maxsize=275'},
{'Mustela erminea upright.jpg |upright=1|maxsize=275|sizedefault=frameless'},
{'Mustela erminea upright.jpg |upright=1|sizedefault=260|maxsize=275'},
{'Mustela erminea upright.jpg |upright=1.5|sizedefault=260|maxsize=275'},
{'Mustela erminea upright.jpg |upright=1|size=200|sizedefault=260|maxsize=275'},
{'Mustela erminea upright.jpg |upright=1|size=|sizedefault=|maxsize='},
{'Replace this image.svg |suppressplaceholder=no'},
{'Replace this image.svg'},
{'The Universal Magazine, Vol. XCV (July 1794).djvu |page=8'},
{'Http-fakezarathustra.blogspot.com-2010-10-12 31.html http-fakezarathustra.blogspot.com-2010-10-22 31.html - panoramio.jpg'},
{'Abbey Rd Studios.jpg|alt=http:test.com'},
{'Abbey Rd Studios.jpg|alt=[http:test.com]'},
{'Abbey Rd Studios.jpg|class=notpageimage'},
{'[[File:Abbey Rd Studios.jpg|200px]]'},
{'[[File:Abbey Rd Studios.jpg|thumb]]'},
{'[[File:Abbey Rd Studios.jpg|thumb|caption]]'},
},{nowiki=1})
end

function p:test3_errors()
self:preprocess_equals_preprocess_many('{{#invoke:InfoboxImage/sandbox |InfoboxImage |image=', '}}', '{{#invoke:InfoboxImage|InfoboxImage |image=', '}}', {
{'Mustela erminea upright.jpg |size=1.2'},
{'Mustela erminea upright.jpg |size=300x'},
{'Mustela erminea upright.jpg |sizedefault=300x | maxsize=200'},
{'Mustela erminea upright.jpg |size=300 | maxsize=200x'},
{'Mustela erminea upright.jpg |sizedefault=145 | maxsize=300x'},
{'http:test.com'},
{'[http:test.com]'},
{'[[http:test.com]]'},
{'https:test.com'},
{'[https:test.com]'},
{'[[https:test.com]]'},
},{nowiki=1})
end

function p:test4_stripmarkers()
self:preprocess_equals_preprocess(
'{{#invoke:InfoboxImage/sandbox |InfoboxImage |image={{multiple image | width = 60 | image1 = Yellow card.svg | image2 = Red card.svg}}}}',
'{{#invoke:InfoboxImage |InfoboxImage |image={{multiple image | width = 60 | image1 = Yellow card.svg | image2 = Red card.svg}}}}',
{stripmarker=1})
end

return p
58 changes: 58 additions & 0 deletions Uses TemplateStyles/config.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
local cfg = {} -- Don’t touch this line.

-- Subpage blacklist: these subpages will not be categorized (except for the
-- error category, which is always added if there is an error).
-- For example “Template:Foo/doc” matches the `doc = true` rule, so it will have
-- no categories. “Template:Foo” and “Template:Foo/documentation” match no rules,
-- so they *will* have categories. All rules should be in the
-- ['<subpage name>'] = true,
-- format.
cfg['subpage_blacklist'] = {
['doc'] = true,
['sandbox'] = true,
['sandbox2'] = true,
['testcases'] = true,
}

-- Sandbox title: if the stylesheet’s title is <template>/<stylesheet>.css, the
-- stylesheet’s sandbox is expected to be at <template>/<sandbox_title>/<stylesheet>.css
-- Set to nil to disable sandbox links.
cfg['sandbox_title'] = 'sandbox'

-- Error category: this category is added if the module call contains errors
-- (e.g. no stylesheet listed). A category name without namespace, or nil
-- to disable categorization (not recommended).
cfg['error_category'] = 'Bản mẫu Uses TemplateStyles có lỗi'

-- Default category: this category is added if no custom category is specified
-- in module/template call. A category name without namespace, or nil
-- to disable categorization.
cfg['default_category'] = 'Bản mẫu sử dụng TemplateStyles'

-- Protection conflict category: this category is added if the protection level
-- of any stylesheet is lower than the protection level of the template. A category name
-- without namespace, or nil to disable categorization (not recommended).
cfg['protection_conflict_category'] = 'Bản mẫu sử dụng TemplateStyles có mức khóa khác nhau'

-- Hierarchy of protection levels, used to determine whether one protection level is lower
-- than another and thus should populate protection_conflict_category. No protection is treated as zero
cfg['protection_hierarchy'] = {
autoconfirmed = 1,
extendedconfirmed = 2,
templateeditor = 3,
sysop = 4
}

-- Padlock pattern: Lua pattern to search on protected stylesheets for, or nil
-- to disable padlock check.
cfg['padlock_pattern'] = '{{pp-'

-- Missing padlock category: this category is added if a protected stylesheet
-- doesn’t contain any padlock template (specified by the above Lua pattern).
-- A category name without namespace (no nil allowed) if the pattern is not nil,
-- unused (and thus may be nil) otherwise.
cfg['missing_padlock_category'] = 'Bản mẫu sử dụng TemplateStyles không khoá'

-- Default subpage for the stylesheet if none is given
cfg['default_subpage_name'] = 'styles.css'
return cfg -- Don’t touch this line.
Loading
Loading