Модул:category tree
Изглед
Script error: The function "main" does not exist.
local m_utilities = require("Модул:utilities")
local concat = table.concat
local insert = table.insert
local sort = table.sort
local uupper = require("Модул:string utilities").upper
local inFundamental = mw.loadData("Модул:category tree/data")
local show_error, link_box, show_catfix, show_categories, show_topright, show_editlink, show_pagelist,
show_breadcrumbs, show_description, show_appendix, show_children, show_TOC
local export = {}
-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
local template = frame.args["template"]
if not template or template == "" then
error("The \"template\" parameter was not specified.")
end
if mw.title.getCurrentTitle().nsText == "Шаблон" then
local text = {}
insert(text, "This template should be used on pages in the Категорија: namespace, ")
insert(text, "and automatically generates descriptions and categorization for categories of a recognized type (see below).")
insert(text, " It is implemented by [[Модул:category tree]] and its submodule [[Модул:category tree/")
insert(text, template .. "]].")
if frame.args["useautocat"] then
insert(text, " It is preferable not to invoke this template directly, but to simply use ")
insert(text, require("Модул:template link").format_link("auto cat"))
insert(text, " (with no parameters), which will automatically invoke this template on appropriately-named category pages.")
end
return concat(text)
elseif mw.title.getCurrentTitle().nsText ~= "Категорија" then
error("This template/module can only be used on pages in the Category: namespace.")
end
local submodule = require("Модул:category tree/" .. template)
-- Get all the parameters and the label data
local current
if submodule.new_main then
current = submodule.new_main(frame)
else
local info = {}
for key, val in pairs(frame.args) do
if val ~= "" and key ~= "useautocat" then
info[key] = val
end
end
info.template = nil
current = submodule.new(info, true)
end
local functions = {
"getBreadcrumbName",
"getDataModule",
"canBeEmpty",
"getDescription",
"getParents",
"getChildren",
"getUmbrella",
"getAppendix",
"getTOCTemplateName",
}
if current then
for _, functionName in pairs(functions) do
if type(current[functionName]) ~= "function" then
require("Модул:debug").track{ "category tree/missing function", "category tree/missing function/" .. functionName }
end
end
end
local boxes = {}
local display = {}
local categories = {}
if template == "topic cat" then
insert(categories, "[[Категорија:topic cat]]")
end
-- Check if the category is empty
local isEmpty = mw.site.stats.pagesInCategory(mw.title.getCurrentTitle().text, "all") == 0
-- Are the parameters valid?
if not current then
-- WARNING: The following name is hardcoded and checked for in [[Module:auto cat]]. If you change it, you
-- also need to change that module.
insert(categories, "[[Категорија:Категорије that are not defined in the category tree]]")
insert(categories, isEmpty and "[[Категорија:Празне категорије]]" or nil)
insert(display, show_error(
"Double-check the category name for typos. <br>" ..
"[[Special:Search/Category: " .. mw.title.getCurrentTitle().text:gsub("^.+:", ""):gsub(" ", "~2 ") .. '~2|Search existing categories]] to check if this category should be created under a different name (for example, "Fruits" instead of "Fruit"). <br>' ..
"To add a new category to Wiktionary's category tree, please consult " .. mw.getCurrentFrame():expandTemplate{title = "section link", args = {
"Помоћ:Категорија#How_to_create_a_category",
}} .. "."))
-- Exit here, as all code beyond here relies on current not being nil
return concat(categories, "") .. concat(display, "\n\n")
end
-- Does the category have the correct name?
if mw.title.getCurrentTitle().text ~= current:getCategoryName() then
insert(categories, "[[Категорија:Категорија са неисправним именом]]")
insert(display, show_error(
"Based on the parameters given to the " ..
require("Модул:template link").format_link(template) ..
" template, this category should be called '''[[:Категорија:" .. current:getCategoryName() .. "]]'''."))
end
-- Add cleanup category for empty categories
local canBeEmpty = current:canBeEmpty()
if isEmpty and not canBeEmpty then
insert(categories, "[[Категорија:Празне категорије]]")
end
if current:isHidden() then
insert(categories, "__HIDDENCAT__")
end
if canBeEmpty then
insert(categories, " __EXPECTUNUSEDCATEGORY__")
end
-- Put all the float-right stuff into a <div> that does not clear, so that float-left stuff like the breadcrumbs and
-- description can go opposite the float-right stuff without vertical space.
insert(boxes, "<div style=\"float: right;\">")
insert(boxes, show_topright(current))
insert(boxes, show_editlink(current))
insert(boxes, show_related_changes())
insert(boxes, show_pagelist(current))
insert(boxes, "</div>")
-- Generate the displayed information
insert(display, show_breadcrumbs(current))
insert(display, show_description(current))
insert(display, show_appendix(current))
insert(display, show_children(current))
insert(display, show_TOC(current))
insert(display, show_catfix(current))
insert(display, '<br class="clear-both-in-vector-2022-only">')
show_categories(current, categories)
return concat(boxes, "\n") .. "\n" .. concat(display, "\n\n") .. concat(categories, "")
end
function show_error(text)
return mw.getCurrentFrame():expandTemplate{title = "maintenance box", args = {
"red",
image = "[[File:Ambox warning pn.svg|50px]]",
title = "This category is not defined in Wiktionary's category tree.",
text = text,
}}
end
local function get_catfix_info(current)
local lang, sc
if current.getCatfixInfo then
lang, sc = current:getCatfixInfo()
elseif not (current._info and current._info.no_catfix) then
-- FIXME: This is hacky and should be removed.
lang = current._lang
sc = current._info and require("Модул:scripts").getByCode(current._info.sc, true, nil, true) or nil
end
return lang, sc
end
-- Show the "catfix" that adds language attributes and script classes to the page.
function show_catfix(current)
local lang, sc = get_catfix_info(current)
if lang then
return m_utilities.catfix(lang, sc)
else
return nil
end
end
-- Show the parent categories that the current category should be placed in.
function show_categories(current, categories)
local parents = current:getParents()
if not parents then
return
end
for _, parent in ipairs(parents) do
local sortkey = type(parent.sort) == "table" and parent.sort:makeSortKey() or parent.sort
if type(parent.name) == "string" then
insert(categories, "[[" .. parent.name .. "|" .. sortkey .. "]]")
else
insert(categories, "[[Категорија:" .. parent.name:getCategoryName() .. "|" .. sortkey .. "]]")
end
end
-- Also put the category in its corresponding "umbrella" or "by language" category.
local umbrella = current:getUmbrella()
if umbrella then
-- FIXME: use a language-neutral sorting function like the Unicode Collation Algorithm.
local sortkey = current._lang and current._lang:getCanonicalName() or current:getCategoryName()
sortkey = require("Модул:languages").getByCode("en", true, nil, nil, true):makeSortKey(sortkey)
if type(umbrella) == "string" then
insert(categories, "[[" .. umbrella .. "|" .. sortkey .. "]]")
else
insert(categories, "[[Категорија:" .. umbrella:getCategoryName() .. "|" .. sortkey .. "]]")
end
end
end
function link_box(content)
return "<div class=\"noprint plainlinks\" style=\"float: right; clear: both; margin: 0 0 .5em 1em; background: #f9f9f9; border: 1px #aaaaaa solid; margin-top: -1px; padding: 5px; font-weight: bold;\">"
.. content .. "</div>"
end
function show_related_changes()
local title = mw.title.getCurrentTitle().fullText
return link_box(
"["
.. tostring(mw.uri.fullUrl("Special:RecentChangesLinked", {
target = title,
showlinkedto = 0,
}))
.. ' <span title="Задњи уноси и друге промене страна у ' .. title .. '">Задње промене</span>]')
end
function show_editlink(current)
return link_box(
"[" .. tostring(mw.uri.fullUrl(current:getDataModule(), "action=edit"))
.. " Унос категорија података]")
end
function show_pagelist(current)
local namespace = "namespace="
local info = current:getInfo()
local lang_code = info.code
if info.label == "citations" or info.label == "citations of undefined terms" then
namespace = namespace .. "Цитати"
elseif lang_code then
local lang = require("Модул:languages").getByCode(lang_code, true, nil, nil, true)
if lang then
-- Proto-Norse (gmq-pro) is the probably language with a code ending in -pro
-- that's intended to have mostly non-reconstructed entries.
if (lang_code:find("%-pro$") and lang_code ~= "gmq-pro") or lang:hasType("reconstructed") then
namespace = namespace .. "Reconstruction"
elseif lang:hasType("appendix-constructed") then
namespace = namespace .. "Додатак"
end
end
elseif info.label:match("шаблони") then
namespace = namespace .. "Шаблон"
elseif info.label:match("модули") then
namespace = namespace .. "Модул"
elseif info.label:match("^Викиречник") or info.label:match("^Странице") then
namespace = ""
end
local recent = mw.getCurrentFrame():callParserFunction{
name = "#tag",
args = {
"DynamicPageList",
"category=" .. mw.title.getCurrentTitle().text .. "\n" ..
namespace .. "\n" ..
"count=10\n" ..
"mode=ordered\n" ..
"ordermethod=categoryadd\n" ..
"order=descending"
}
}
local oldest = mw.getCurrentFrame():callParserFunction{
name = "#tag",
args = {
"DynamicPageList",
"category=" .. mw.title.getCurrentTitle().text .. "\n" ..
namespace .. "\n" ..
"count=10\n" ..
"mode=ordered\n" ..
"ordermethod=lastedit\n" ..
"order=ascending"
}
}
return [=[
{| id="newest-and-oldest-pages" class="wikitable mw-collapsible" style="float: right; clear: both; margin: 0 0 .5em 1em;"
! Најновије и најстарије стране
|-
| id="recent-additions" style="font-size:0.9em;" | '''Најновије стране поређане по задњем [[mw:Manual:Categorylinks table#cl_timestamp|освежавање]]:'''
]=] .. recent .. [=[
|-
| id="oldest-pages" style="font-size:0.9em;" | '''Најстарије странице поређане по задњој измени:'''
]=] .. oldest .. [=[
|}]=]
end
-- Show navigational "breadcrumbs" at the top of the page.
function show_breadcrumbs(current)
local steps = {}
-- Start at the current label and move our way up the "chain" from child to parent, until we can't go further.
while current do
local category = nil
local display_name = nil
local nocap = nil
if type(current) == "string" then
category = current
display_name = current:gsub("^Категорија:", "")
else
if not current.getCategoryName then
error("Internal error: Bad format in breadcrumb chain structure, probably a misformatted value for `parents`: " ..
mw.dumpObject(current))
end
category = "Категорија:" .. current:getCategoryName()
display_name, nocap = current:getBreadcrumbName()
end
if not nocap then
display_name = mw.getContentLanguage():ucfirst(display_name)
end
insert(steps, 1, "[[:" .. category .. "|" .. display_name .. "]]")
-- Move up the "chain" by one level.
if type(current) == "string" then
current = nil
else
current = current:getParents()
end
if current then
current = current[1].name
elseif inFundamental[category] then
current = "Категорија:Почетак"
end
end
local templateStyles = require("Модул:TemplateStyles")("Модул:category tree/styles.css")
local ol = mw.html.create("ol")
for i, step in ipairs(steps) do
local li = mw.html.create("li")
if i ~= 1 then
local span = mw.html.create("span")
:attr("aria-hidden", "true")
:addClass("ts-categoryBreadcrumbs-separator")
:wikitext(" » ")
li:node(span)
end
li:wikitext(step)
ol:node(li)
end
local div = mw.html.create("div")
:attr("role", "navigation")
:attr("aria-label", "Breadcrumb")
:addClass("ts-categoryBreadcrumbs")
:node(ol)
return templateStyles .. tostring(div)
end
-- Show the text that goes at the very top right of the page.
function show_topright(current)
return (current.getTopright and current:getTopright() or "")
end
-- Show a short description text for the category.
function show_description(current)
return (current:getDescription() or "")
end
function show_appendix(current)
local appendix
if current.getAppendix then
appendix = current:getAppendix()
end
if appendix then
return "For more information, see [[" .. appendix .. "]]."
else
return nil
end
end
-- Show a list of child categories.
function show_children(current)
local children = current:getChildren()
if not children then
return nil
end
sort(children, function(first, second) return uupper(first.sort) < uupper(second.sort) end)
local children_list = {}
for _, child in ipairs(children) do
local child_pagetitle
if type(child.name) == "string" then
child_pagetitle = child.name
else
child_pagetitle = "Категорија:" .. child.name:getCategoryName()
end
local child_page = mw.title.new(child_pagetitle)
if child_page.exists then
local child_description =
child.description or
type(child.name) == "string" and child.name:gsub("^Категорија:", "") .. "." or
child.name:getDescription("child")
insert(children_list, "* [[:" .. child_pagetitle .. "]]: " .. child_description)
end
end
return concat(children_list, "\n")
end
-- Show a table of contents with links to each letter in the language's script.
function show_TOC(current)
local titleText = mw.title.getCurrentTitle().text
local inCategoryPages = mw.site.stats.pagesInCategory(titleText, "pages")
local inCategorySubcats = mw.site.stats.pagesInCategory(titleText, "subcats")
local TOC_type
-- Compute type of table of contents required.
if inCategoryPages > 2500 or inCategorySubcats > 2500 then
TOC_type = "full"
elseif inCategoryPages > 200 or inCategorySubcats > 200 then
TOC_type = "normal"
else
-- No (usual) need for a TOC if all pages or subcategories can fit on one page;
-- but allow this to be overridden by a custom TOC handler.
TOC_type = "none"
end
if current.getTOC then
local TOC_text = current:getTOC(TOC_type)
if TOC_text ~= true then
return TOC_text
end
end
if TOC_type ~= "none" then
local templatename = current:getTOCTemplateName()
local TOC_template
if TOC_type == "full" then
-- This category is very large, see if there is a "full" version of the TOC.
local TOC_template_full = mw.title.new(templatename .. "/full")
if TOC_template_full.exists then
TOC_template = TOC_template_full
end
end
if not TOC_template then
local TOC_template_normal = mw.title.new(templatename)
if TOC_template_normal.exists then
TOC_template = TOC_template_normal
end
end
if TOC_template then
return mw.getCurrentFrame():expandTemplate{title = TOC_template.text, args = {}}
end
end
return nil
end
function export.test(frame)
local template = frame.args[1]
local submodule = require("Модул:category tree/" .. template)
if submodule.new_main then
current = submodule.new_main(frame)
else
local info = {}
for key, val in pairs(frame.args) do
info[key] = val; if info[key] == "" then info[key] = nil end
end
info.template = nil
current = submodule.new(info, true)
end
end
return export