Mô đun:Autocat
Mô đun này có thể phù hợp với tiêu chí xóa nhanh của Wikipedia vì nó là bản mẫu/mô đun không liên kết hoặc không sử dụng ở bất kỳ trang nào. Lưu ý các bản mẫu/mô đun quan trọng nhiều người xem hoặc được nhúng ở nhiều trang khác thì không thuộc diện xóa nhanh. Xem XN BM3.
Nếu mô đun này không nằm trong các tiêu chí xóa nhanh, hãy dời thông báo này đi. Bảo quản viên, Điều phối viên chú ý: Hãy kiểm tra liên kết, lịch sử (sửa đổi cuối) và nhật trình trước khi xóa trang. Kiểm tra Google: web, tin tức. Người đặt thông báo chú ý: cần thận trọng khi đánh giá bài viết của người mới đến; trong nhiều trường hợp cần giúp đỡ người mới hoàn thiện bài viết thay vì yêu cầu xóa nhanh; hành động yêu cầu xóa nhanh chỉ là ý kiến của cá nhân bạn nhưng có thể gây hiểu lầm là yêu cầu của cộng đồng Wikipedia. |
require('Module:Module wikitext')._addText([[{{db-banmaukhonglienket}}]]);
--by HastaLaVi2
---*---*---*---*---*---*---*---*---*---*---*---*---
-- CATEGORY OBJECT
---*---*---*---*---*---*---*---*---*---*---*---*---
local Category = {}
function Category:getName()
return self._name
end
function Category:getCategoryName()
local year = self._year
local name = self:getName()
local function check(year, name)
return mw.title.new('Thể loại:' .. fixBC(year) .. " " .. name).exists and fixBC(year) .. " " .. name
end
if self._type == "năm" then
return fixBC(year) .. " " .. name
elseif self._type == "thập niên" then
return fixBC("TN"..year) .. " " .. name
elseif self._type == "thế kỷ" then
return check("thế kỷ "..suffixToYear(year), name) or fixBC("thế kỷ"..suffixToYear(year)) .. " " .. name
elseif self._type == "thiên niên kỷ" then
return check("thiên niên kỷ "..suffixToYear(year), name) or fixBC("thiên niên kỷ"..suffixToYear(year)) .. " " .. name
else
return name
end
end
function Category:getBarName()
return self._type == "năm" and fixBC(self._year)
or (self._type == "thập niên" and fixBC(self._year..""))
or (self._type == "thế kỷ" and fixBC(suffixToYear(self._year)))
or (self._type == "thiên niên kỷ" and fixBC(suffixToYear(self._year)))
end
function Category:getYear()
return self._year
end
function Category:byCat()
return self._rawData.byCat
end
function Category:stage()
return self._rawData.stage
end
function Category:getUpYear()
return self._type == "năm" and getDecade(self._year) or
(self._type == "thập niên" and getCentury(self._year) or
(self._type == "thế kỷ" and getMillennium(self._year) ))
end
function Category:getWikidata()
return mw.wikibase.getEntity(mw.wikibase.getEntityIdForCurrentPage())
end
function Category:getParents()
local parents = {}
--[[
if there is already a specified "by category" in parents table,
we do not need to add a new one, but by default this boolean should always be true
--]]
local byCat = true
--list of the parents
local chain = self._rawData.parents or {}
local _type = self._type
--call objects for each parent
for _,parent in ipairs(chain) do
if parent == "thể loại" and _type ~= "byCat" then parent = "" end
if parent == "năm" or parent == "thập niên" or parent == "thế kỷ" or parent == "thiên niên kỷ" then _type = "up" end
parent = mw.ustring.gsub(parent, "{{{type}}}", _type)
table.insert(parents, getByName(parent, self._year, _type))
--and here we detect if one of the parents is a "by category"
if mw.ustring.find(parent, "%stheo%s") then
byCat = nil
end
end
--time to call the upper parent
if self:getUpType() then
table.insert(parents, getByName(self:getName(), self:getUpYear(), self:getUpType()))
end
--[[
when we call the parents table, we should also call each of them as objects of their owns,
but, other than normal parent listings on the data, each category has an "upper" category,
which means for "2010 in art", the upper category is "2010s in art", and for "2010s in art"
the upper category is "21st century in art", and so on
but to detect the upper category we need to find which decade, century or millennium
in the year we are currently (current for the page) in for the category
--]]
if self._name ~= "" and self._type ~= "byCat" and byCat then
local name = mw.ustring.gsub(self._name, "^", "")
name = mw.ustring.gsub(name, "^", "")
table.insert(parents, getByName(name.." theo "..self._type, self._year, self._type))
end
--export the objects
return parents or {}
end
function Category:getPortals()
return self._rawData.portals or {}
end
function Category:getSeeCat()
local see = self._rawData.see or {}
local last = {}
if self._type == "byCat" then
for _,b in ipairs(see) do
table.insert(last, mw.getContentLanguage():ucfirst(b).." "..self._year)
end
else
for _,b in ipairs(see) do
table.insert(last, getByName(b, self._year, self._type):getCategoryName())
end
end
return last
end
function Category:getDescription()
if self._rawData.description then
return mw.getContentLanguage():ucfirst(handleParams(self._rawData.description, self._year, self:getType())) .. "."
else
return "Thể loại này chứa "..mw.getContentLanguage():lcfirst(mw.title.getCurrentTitle().text).."."
end
end
function Category:getType()
return self._type
end
function Category:getUpType()
if self._type == "năm" and self._rawData.stage and self._rawData.stage > 1 then
return "thập niên"
elseif self._type == "thập niên" and self._rawData.stage and self._rawData.stage > 2 then
return "thế kỷ"
elseif self._type == "thế kỷ" and self._rawData.stage and self._rawData.stage > 3 then
return "thiên niên kỷ"
end
end
function Category:getDataModule()
return self._module
end
function Category:getSortKeys()
local chain = {}
local sortKeys = {}
--years and their equivalent sort keys
local keys = {["năm"]="YLAST", ["thập niên"]="YLASTTWO", ["thế kỷ"]="FOUR", ["thiên niên kỷ"]="FOUR"}
for _,a in ipairs(self._rawData.sort_keys or {}) do table.insert(chain, a) end
if self:getUpType() then
table.insert(chain, keys[self._type])
end
table.insert(chain, "DORTLU")
for _,key in ipairs(chain) do
if key == "YLAST" then key = mw.ustring.sub( self._year, -1 )
elseif key == "YLASTTWO" then key = mw.ustring.sub( self._year, -2 )
elseif key == "FOUR" then key = mw.ustring.find(self._year, "-") and "-"..tostring(9999+tonumber(self._year))
or (string.len(self._year) == 1 and "000"..self._year
or (string.len(self._year) == 2 and "00"..self._year
or (string.len(self._year) == 3 and "0"..self._year
or (string.len(self._year) == 4 and self._year)))) end
table.insert(sortKeys, key)
end
return sortKeys or {}
end
function Category:toJSON()
local ret = {
parents = self:getParents(),
description = self:getDescription(),
name = self:getName(),
year = _year,
type = _type,
sort_keys = self:getSortKeys(),
}
return require("Modül:JSON").toJSON(ret)
end
function Category:getRawData()
return self._rawData
end
Category.__index = Category
function createObject(name, data, year, type, module)
return data and
setmetatable({ _rawData = data, _name = name, _year = year, _type = type, _module = module }
, Category)or nil
end
function getByName(name, year, _type)
local data_pages = {
"data",
"data/people",
"data/arts",
}
local data_module
for _, page in ipairs(data_pages) do
data_module = "Mô đun:Autocat/" .. page
if require(data_module)[name] then
name = type(require(data_module)[name]) == "string" and require(data_module)[name] or name
break
elseif require(data_module)[" "..name] then
name = " "..name
break
elseif require(data_module)[" "..name] then
name = " "..name
break
end
end
local data = mw.loadData(data_module)
if not data[name] then
data = {[name] = {}}
if name == "" then
local sp = {["thế kỷ"]="thế kỷ", ["thiên niên kỷ"]="thiên niên kỷ"}
data[""] = {
parents = {(sp[_type] or _type)..""},
sort_keys = {"FOUR"},
stage = 4,
}
end
end
if mw.ustring.find(name, "%stheo%s") then _type = "byCat" end
return createObject(name, data[name], year, _type, data_module)
end
---*---*---*---*---*---*---*---*---*---*---*---*---
-- REFLECTING FUNCTIONS
---*---*---*---*---*---*---*---*---*---*---*---*---
--find and replace function
local function findandrep(text, one, two)
return mw.ustring.sub( mw.ustring.gsub(text, one, two), 1, -1 )
end
--find function
local findIn = mw.ustring.find
local function editLink(category)
--her kategoride "veriyi düzenle" bağlantısını eklemeye yarayan fonksiyon
return "<div class=\"toccolours hlist plainlinks\" style=\"float: right; margin: 0.5em 0 0.5em 1em; font-weight: bold;\">[" ..
mw.getCurrentFrame():callParserFunction{name = "fullurl", args = {category, action = "edit"}} ..
" Sửa dữ liệu thể loại]</div>"
end
--function to find the decade for a year
--for example if the year 2019, the result would be 2010
--and for 1888, the result is 1880
function getDecade(year)
local dash = findIn(year, "^-") and "-" or nil
local decade = findandrep(year, "^", "")
local result = string.len(decade) == 1 and "0" or mw.ustring.sub(decade, 1, -2) .. 0
return (dash and dash or "") .. result
end
function getCentury(year)
local dash = findIn(year, "^-") and "-" or nil
local century = findandrep(year, "^", "")
local result = (string.len(century) == 1 or string.len(century) == 2) and 1 or tonumber(mw.ustring.sub(century, 1, -3)+1)
return (dash and dash or "") .. tostring(result)
end
function getMillennium(year)
local dash = findIn(year, "^-") and "-" or nil
local mill = findandrep(year, "^", "")
local first = mw.ustring.sub(mill, 1, 1)
local last = mw.ustring.sub(mill, -1)
local result = (string.len(mill) ~= 1 and last ~= "0") and tonumber(first)+1 or tonumber(last)
result = string.len(mill) == 1 and 1 or result
return (dash and dash or "") .. tostring(result)
end
function yearPlus(year, number)
local result = tonumber(year) + number
return tostring(result)
end
function fixBC(year)
local result = findandrep(year, ".*%", "")
local function check(y,v) return findIn(y, "%s"..v) and " "..v or (findIn(y, "-"..v) and "-"..v) end
local suffix = check(year,"thế kỷ") or check(year,"thiên niên kỷ")
result = mw.ustring.gsub(result, "%s.*", "") .. (suffix or "")
return findIn(result, "%d") and findandrep(year, "%"..result, result.." TCN") or year
end
function handleParams(name, year, _type)
local result = name
local century = _type == "thế kỷ" and year or (tonumber(year) and getCentury(year) or year)
local mill = _type == "thiên niên kỷ" and year or (tonumber(year) and getMillennium(getCentury(year)) or year)
local lYear = _type == "năm" and year
or (_type == "thập niên" and year.."")
or (_type == "thế kỷ" and "thế kỷ" .. suffixToYear(year))
or (_type == "thiên niên kỷ" and "thiên niên kỷ" .. suffixToYear(year))
or year
_type = (_type == "byCat" or _type == "thế kỷ" or _type == "thiên niên kỷ") and "" or _type
result = findandrep(result, "{{{year}}}", lYear)
result = findandrep(result, "{{{type}}}", _type)
--hidden items for by categories
if _type == "byCat" and findIn(result, '%{%{%{hiden%|([^%}%}%}]+)') then
result = findandrep(result, '%{%{%{hide%|([^%}%}%}]+)', '')
end
result = findandrep(result, '%{%{%{hide%|', '')
result = findandrep(result, '%}%}%}', '')
return fixBC(result)
end
--header bar for the next and the previous 5 stages
function headerBar(category)
--we will collect all the data inside this table
local result = {}
--[[
:getName() value, is the part after the numbers in a
category name, so for "2010s works", this value
would be "works"
--]]
local suffix = category:getName()
--getting the year for the category
local year = category:getYear()
local function repeatF(y, _type, name)
local function ifExists(page)
return mw.title.new('Thể loại:' .. page).exists
end
--we need to call 5 down-level and 5 upper-level categories
for i = -5, 5 do
--this will give us the next year value
--each time the loop starts
local nextYear = yearPlus(y, i)
if _type == "năm" or _type == "thế kỷ" or _type == "thiên niên kỷ" then
last = getByName(name, nextYear, _type)
elseif _type == "thập niên" then
nextYear = yearPlus(getDecade(y), i..0)
last = getByName(name, nextYear, "thập niên")
end
--let us check the pages
--special case for 0s BC
if _type == "thập niên" and last:getBarName() == "0" then
if ifExists(findandrep(last:getCategoryName(), "0", "0 TCN")) then
table.insert(result, '\n*[[:Thể loại:' .. findandrep(last:getCategoryName(), "0", "0 TCN") .. "|" .. last:getBarName() .. " TCN]]")
else
table.insert(result, '\n*<span style="color:#888">' .. last:getBarName() .. " TCN</span>")
end
end
--if category exists
if ifExists(last:getCategoryName()) then
table.insert(result, '\n*[[:Thể loại:' .. last:getCategoryName() .. "|" .. last:getBarName() .. "]]")
else
--and if not
table.insert(result, '\n*<span style="color:#888">' .. last:getBarName() .. "</span>")
end
end
end
local function checkParent(category, result, _type)
if category:getUpType() and category:getUpType() == _type then
table.insert(result, '\n|}')
table.insert(result, '\n{| class="toccolours hlist" style="text-align: center; margin: auto; border: none; background: transparent;"'
.. '\n|')
end
end
--start of the main header bar
table.insert(result, '<div style="padding-bottom: 10px;">\n{| class="toccolours hlist" style="text-align: center; margin: auto;"'
.. '\n|')
--check for the years
if category:getType() == "year" then
repeatF(year, "year", suffix)
end
--[[
if we are in a decade categıry, the getCentury() function
would find the right century for that decade
but if we are already in a century or in a millennium category
no need to run these functions, otherwise the results will be wrong
--]]
if category:getType() == "century" then
function getCentury(year) return year end
elseif category:getType() == "millennium" then
function getMillennium(year) return year end
end
--DECADE
checkParent(category, result, "decade")
if (category:getUpType() and category:getUpType() == "decade") or category:getType() == "decade" then
repeatF(year, "decade", suffix)
end
--CENTURY
checkParent(category, result, "century")
if (category:getUpType() and category:getUpType() == "century") or category:getType() == "century" then
repeatF(getCentury(year), "century", suffix)
end
--MILLENNIUM
checkParent(category, result, "millennium")
if (category:getUpType() and category:getUpType() == "millennium") or category:getType() == "millennium" then
repeatF(getMillennium(year), "millennium", suffix)
end
--the end of the header bar
table.insert(result, '\n|}\n</div>')
--export all data
return table.concat(result)
end
--this function handles the year suffixes
--for example: if it gets the number "1",
--it exports the result "1st", "2nd" for "2" and "3rd" for "3" etc...
function suffixToYear(year)
--detect the last digit
local lastDigit = mw.ustring.sub( tostring(year), -1 )
--special cases for 1, 2, 3
local specials = {"", "", ""}
--if the last digit is 1, 2, or 3 get the special case or the default
local suffix = specials[tonumber(lastDigit)] and specials[tonumber(lastDigit)] or ""
return tostring(year) .. suffix
end
--[[
this function is the core to this module,
it takes the page name automatically,
and detects if the page is a year, decade, century, or a millennium category
also, it splits the title into parts, so that we know
which category objects to call
for example, "2017 web series debuts";
it is a year category
and the year is: 2017
category prefix is: web series debuts
NOTE: the result type is always a table containing these data
--]]
function splitTitle(name)
--start the year parameter
local year = ""
local _type
--is this a BC category?
if findIn(name, "%sTCN") then
name = findandrep( name, "%sTCN", " " )
BC = true
end
--if the category name has numbers as prefix
--this means we can easily detach the numbers
--from the beginning
while findIn(name, "^[%d]") do
year = year .. mw.ustring.sub(name, 1, 1)
name = findandrep(name, "^[%d]", "")
--do we have a valid year now?
doWeHaveYear = true
end
--for century or millennium categories
--there could be "st, nd, rd, or th" letters
--after the number
name = findandrep(name, "^", "")
name = findandrep(name, "^", "")
name = findandrep(name, "^", "")
name = findandrep(name, "^", "")
--if we have a valid year
if doWeHaveYear then
--now it is time to detect the category type
--year, decade, century or millennium
if findIn(name, "^thập niên") then
name = findandrep(name, "^", "")
_type = "thập niên"
elseif findIn(name, "thế kỷ [%-%s]") then
name = findandrep(name, "thế kỷ [%-%s]", "")
_type = "thế kỷ"
elseif findIn(name, "thiên niên kỷ [%-%s]") then
name = findandrep(name, "thiên niên kỷ [%-%s]", "")
_type = "thiên niên kỷ"
else
_type = "năm"
end
name = findandrep(name, "^%s", "")
--the result table
return {(BC and "-" or "") .. year, name, _type}
else
return {nil, name}
end
end
function _main(frame)
local category = getByName("sinh", "2000", "năm")
return fixBC("thế kỷ 1")
end
function main(frame)
--our main parameter or the page name
local name = frame:getParent().args[1] or mw.title.getCurrentTitle()["text"]
--for all the categories
local categories = {}
--for all the display items
local display = {}
--our year parameter
local year = splitTitle(name)[1]
--the category object for the page
local category = getByName(splitTitle(name)[2], year, splitTitle(name)[3])
--parents table
local parents = category:getParents()
table.insert(display, headerBar(category))
table.insert(display, editLink(category:getDataModule()))
if category:getWikidata() and category:getWikidata().claims and category:getWikidata().claims["P373"] then
table.insert(display, mw.getCurrentFrame():expandTemplate{
title = "Thể loại Commons",
args = {category:getWikidata():formatPropertyValues("P373").value}})
end
if mw.title.new(name).exists then
table.insert(display, mw.getCurrentFrame():expandTemplate{
title = "Chính",
args = {name}})
end
if category:getPortals()[1] then
table.insert(display, mw.getCurrentFrame():expandTemplate{
title = "Cổng thông tin",
args = {category:getPortals()[1], category:getPortals()[2], category:getPortals()[3], category:getPortals()[4]}})
end
if category:getSeeCat()[1] then
table.insert(display, mw.getCurrentFrame():expandTemplate{
title = "Xem thêm thể loại",
args = {category:getSeeCat()[1], category:getSeeCat()[2], category:getSeeCat()[3], category:getSeeCat()[4]}})
end
if category:getDescription() then
table.insert(display, category:getDescription())
end
--CatAutoTOC
table.insert(display, mw.getCurrentFrame():expandTemplate{title = "CatAutoTOC",args = {}})
--insert the category to each parent categories
for key,parent in ipairs(parents) do
table.insert(categories, "[[Thể loại:" .. parent:getCategoryName() .. "|" .. category:getSortKeys()[key] .. "]]")
end
--is this category empty?
if mw.site.stats.pagesInCategory(mw.title.getCurrentTitle().text, "all") == 0 then
table.insert(categories, "[[Thể loại:Thể loại trống]]")
end
return table.concat(display) .. table.concat(categories)
end
function byCat(frame)
local args = frame:getParent().args
local categories = {}
local display = {}
local year = args[1]
local _type = args[2]
local category = getByName(_type, "theo "..year, "byCat")
local by = type(category:byCat()) == "table" and category:byCat()[1] or category:byCat()
if by and by ~= "no" and by ~= "up" then
yukari = type(category:byCat()) == "table" and category:byCat()[2] or category:byCat()
end
local function catExists(cat) if mw.title.new('Thể loại:'..cat).exists then return cat end end
local perDateTime = catExists(_type..' theo thời gian') or catExists(_type..' theo thời gian') or catExists(_type..' theo thời kỳ')
if category:stage() and category:stage() > 1 and by ~= "up" then
if perDateTime then
table.insert(display, '\n<div style="text-align:center;">'
..'[[:Thể loại:' .. perDateTime .. "|"..perDateTime.."]]</div>")
end
table.insert(display, '<div style="padding-bottom: 10px;">'
.. '\n{| class="toccolours hlist" style="text-align: center; margin: auto;"'
.. '\n|')
if catExists(_type..' theo năm') then
table.insert(display, "\n*[[:Thể loại:" .. _type.." theo năm|theo năm]]")
end
if catExists(_type..' theo thập niên') then
table.insert(display, "\n*[[:Thể loại:" .. _type.." theo thập niên|theo thập niên]]")
end
if catExists(_type..' theo thế kỷ') then
table.insert(display, "\n*[[:Thể loại:" .. _type.." theo thế kỷ|theo thế kỷ]]")
end
if catExists(_type..' theo thiên niên kỷ') then
table.insert(display, "\n*[[:Thể loại:" .. _type.." theo thiên niên kỷ|theo thiên niên kỷ]]")
end
table.insert(display, '\n|}\n</div>')
end
table.insert(display, editLink(category:getDataModule()))
if category:getWikidata() and category:getWikidata().claims and category:getWikidata().claims["P373"] then
table.insert(display, mw.getCurrentFrame():expandTemplate{
title = "Thể loại Commons",
args = {category:getWikidata():formatPropertyValues("P373").value}})
end
if category:getPortals()[1] then
table.insert(display, mw.getCurrentFrame():expandTemplate{
title = "Cổng thông tin",
args = {category:getPortals()[1], category:getPortals()[2], category:getPortals()[3], category:getPortals()[4]}})
end
if category:getSeeCat()[1] then
table.insert(display, mw.getCurrentFrame():expandTemplate{
title = "Xem thêm thể loại",
args = {category:getSeeCat()[1], category:getSeeCat()[2], category:getSeeCat()[3], category:getSeeCat()[4]}})
end
if category:getDescription() then
table.insert(display, category:getDescription())
end
local periodCheck = year == "thời kỳ" or year == "thời gian" or year == "thời gian"
if periodCheck and by == "no" then
elseif by == "up" or periodCheck then
_type = up or _type
table.insert(categories, "[[Thể loại:" .. mw.getContentLanguage():ucfirst(_type) .. "|+]]")
elseif findIn(category:getName(), "và "..year) then else
if perDateTime then
table.insert(categories, "[[Thể loại:" .. perDateTime .. "| ]]")
end
end
if category:getParents() then
for k,parent in ipairs(category:getParents()) do
local e = mw.ustring.gsub(parent:getName(), "^%s%s", "")
local e = mw.ustring.gsub(parent:getName(), "^%s", "")
if periodCheck then
umbrella = catExists(e .. " theo thời gian") or catExists(e .. " theo thời gian") or e .. " theo thời kỳ"
else
umbrella = not findIn(category:getName(), "và "..year)
and catExists(e .. " theo loại và " .. year) or e .. " theo " .. year
end
table.insert(categories, "[[Thể loại:" .. umbrella .. "|"
.. (mw.site.stats.pagesInCategory(umbrella, "subcats") > 200
and mw.ustring.char(0x0020) or category:getSortKeys()[k]) .. "]]")
end
end
return table.concat(display) .. table.concat(categories)
end
return {main = main, byCat = byCat}