This module is used for generating category boilerplate templates. It is not meant to be used directly. Rather, each template will have its own submodule, which handles the specifics of that template.
This documentation only covers the generics of the category tree system. If you are looking for documentation on a specific template, or on how to add or modify category information, see the documentation of that template.
The category tree module is invoked as:
{{#invoke:category tree|show|template=name of the template|...other parameters...}}
Every template that uses this module should have a submodule of this module with the name given in the |template=
parameter. (For example, {{poscatboiler}}
uses Module:category tree/poscatboiler.) This submodule should export a function named new
which takes a single parameter: a table named info
that contains the various parameters that were passed to the template initially. This function should return a new Category
object representing those parameters, or nil
if the combination of parameters was not valid (i.e. no such category exists).
Most templates accept and pass this common set of parameters. The parameters passed to the module by a template are defined by that template individually, so not every template will necessarily use all of these. {{family cat}}
for example only passes the |code=
parameter to the module.
|code=
en
, but it can also be a script code like Latn
or the code of a language family, depending on how the specific template treats it.|label=
|sc=
The module is based on the principle of two main kinds of category:
Basic categories are those for which the |code=
parameter is not empty. These therefore belong to a specific language (or similar) and are the "regular" categories. Examples are: Category:English nouns, Category:French templates, Category:nl:Linguistics, Category:English terms derived from Japanese, Category:Latin script characters.
Umbrella categories do not have a code, but contain all basic categories of their label, one for each code. These are the "by language" type categories. Examples are: Category:Nouns by language, Category:Templates by language, Category:Linguistics, Category:Terms derived from Japanese, Category:Characters by script.
Some templates also distinguish a third type of category, the fundamental category. This category is used as the parent category for umbrella categories.
Sablon:documentation outdated
Category objects are returned by each submodule's new
function. They represent a single category in the tree. A category object has a variety of methods which may be called on it to ask for information about the category.
getBreadcrumbName()
Returns the name that is used for the category in the "breadcrumbs" at the top of the category page.
getDataModule()
Returns the name of the module which contains the data for this category. This is used to create an "edit" link on the category, which allows users to find and edit the information more easily.
canBeEmpty()
Returns true
either if the category contains pages but might be empty or if the category only contains categories, otherwise returns false
.
getCategoryName()
Returns the name of the category that this category object represents.
getDescription()
Returns the description text that is shown at the top of the category page. If the category has no description, this returns nil
.
getParents()
Returns a table of the parent categories of this category. Each element in the table is a table itself, with two elements:
.name
.sort
If the category has no parents, this returns nil
.
If there are two or more parent categories, the first will be used to generate the breadcrumbs that are displayed at the top of the category page. For example, Category:English language is in numerous categories (All languages, West Germanic languages, Latin script languages, Braille script languages, and so on), but the first category, All languages, is the one displayed in the breadcrumbs: Sablon:serif.
getChildren()
Returns a table of the child categories of this category. Each element in the table is a category object representing the child category. If the category has no children, this returns nil
.
getUmbrella()
Returns a category object for the current category's corresponding umbrella category. If the current category is already an umbrella category, this returns nil
. It also returns nil
if the category has no umbrella category.
getAppendix()
Returns an appendix link (such as Appendix:French verbs) if the page exists, else returns nil
.
In categories that contain terms in a given language, the module looks for a table of contents for the language in the titles Template:language code-categoryTOC
(for categories with more than 200 but less than 2500 entries) and Template:language code-categoryTOC/full
(for categories with more than 2500 entries). For English, these templates are {{en-categoryTOC}}
and {{en-categoryTOC/full}}
.
local export = {}
local m_languages = require('Module:languages')
local m_utilities = require('Module:utilities')
local inFundamental = mw.loadData("Module:category tree/data")
local function capitalize(text)
return mw.getContentLanguage():ucfirst(text)
end
-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
if mw.title.getCurrentTitle().nsText == "Sablon" then
return "(Ez a sablon a kategórianévtérben használandó.)"
elseif mw.title.getCurrentTitle().nsText ~= "Kategória" then
error("Ez a sablon/modul csak a kategórianévtérben használható.")
end
local template = frame.args
if not template or template == "" then
error("A „template” paraméter nincs megadva.")
end
local submodule = require("Module: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
info = val; if info == "" then info = nil end
end
info.template = nil
current = submodule.new(info, true)
end
local functions = {
"getBreadcrumbName",
"getDataModule",
"canBeEmpty",
"getDescription",
"getParents",
"getChildren",
"getUmbrella",
"getAppendix",
}
if current then
for i, functionName in pairs(functions) do
if type(current) ~= "function" then
require("Module: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
table.insert(categories, "]")
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
table.insert(categories, "]")
table.insert(categories, isEmpty and "]" or nil)
table.insert(display, show_error(
"A(z) " ..
mw.getCurrentFrame():expandTemplate{title = "temp", args = {template}} ..
" sablonnak megadott címke érvénytelen. Lehet, hogy elgépelted, vagy egyszerűen még nem lett létrehozva. " ..
"Új címke hozzáadásához lásd a sablondokumentációt."))
-- Exit here, as all code beyond here relies on current not being nil
return table.concat(categories, "") .. table.concat(display, "\n\n")
end
-- Does the category have the correct name?
if mw.title.getCurrentTitle().text ~= current:getCategoryName() then
table.insert(categories, "]")
table.insert(display, show_error(
"A(z) " ..
mw.getCurrentFrame():expandTemplate{title = "temp", args = {template}} ..
" sablonnak megadott paraméterek alapján a kategória helyes elnevezése ''']''' lenne."))
end
-- Add cleanup category for empty categories
if isEmpty and not current:canBeEmpty() then
table.insert(categories, "]")
end
if current:isHidden() then
table.insert(categories, "__HIDDENCAT__")
end
table.insert(boxes, show_editlink(current))
table.insert(boxes, show_pagelist(current))
-- Generate the displayed information
table.insert(display, show_breadcrumbs(current))
table.insert(display, show_description(current))
table.insert(display, show_appendix(current))
table.insert(display, show_children(current))
table.insert(display, show_TOC(current))
table.insert(display, show_catfix(current))
show_categories(current, categories)
return table.concat(boxes, "\n") .. "\n" .. table.concat(display, "\n\n") .. table.concat(categories, "")
end
function show_error(text)
return mw.getCurrentFrame():expandTemplate{title = "maintenance box", args = {
"red",
image = "]",
title = "A kategória automatikusan generált tartalma hibás.",
text = text,
}}
end
-- Check the name of the current page, and return an error if it's not right.
function check_name(current, template, info)
local errortext = nil
local category = nil
if not current then
errortext =
"A(z) " ..
mw.getCurrentFrame():expandTemplate{title = "temp", args = {template}} ..
" sablonnak megadott „" .. (info.label or "") .. "” címke érvénytelen." ..
"Lehet, hogy elgépelted, vagy egyszerűen még nem lett létrehozva. " ..
"Új címke hozzáadásához lásd a sablondokumentációt."
category = "]"
else
end
if errortext then
return (category or "") .. show_error(errortext)
else
return nil
end
end
function show_catfix(current)
if current._lang then
return m_utilities.catfix(current._lang, (sc and require("Module:scripts").getByCode(info.sc) or nil))
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
if type(parent.name) == "string" then
if not (current._lang and current:getCategoryName() == capitalize(current._lang:getCategoryName())) and not (current._sc and current:getCategoryName():find(capitalize(current._sc:getCategoryName()), nil, true)) and current:getInfo().code then
require("Module:debug").track("category tree/string")
end
table.insert(categories, "]")
else
table.insert(categories, "]")
end
end
-- Also put the category in its corresponding "umbrella" or "by language" category.
local umbrella = current:getUmbrella()
if umbrella then
local sort
if current._lang then
sort = current._lang:getCanonicalName()
else
sort = current:getCategoryName()
end
if type(umbrella) == "string" then
table.insert(categories, "]")
else
table.insert(categories, "]")
end
end
end
function show_editlink(current)
return
"<div class=\"noprint plainlinks\" style=\"float: right; clear: both; margin: 0 0 .5em 1em; background: #f9f9f9; border: 1px #aaaaaa solid; padding: 5px; font-weight: bold;\">[" ..
mw.getCurrentFrame():callParserFunction{name = "fullurl", args = {current:getDataModule(), action = "edit"}} ..
" Kategória adatainak szerkesztése]</div>"
end
function show_pagelist(current)
do return '' end -- ] not enabled on huwiktionary
local namespace = ""
local info = current:getInfo()
if info.label == "citations" or info.label == "citations of undefined terms" then
namespace = "Citations"
elseif info.code then
local lang = require("Module:languages").getByCode(info.code)
if lang then
if lang:getType() == "reconstructed" then
namespace = "Reconstruction"
elseif lang:getType() == "appendix-constructed" then
namespace = "Appendix"
end
end
end
local recent = mw.getCurrentFrame():callParserFunction{
name = "#tag",
args = {
"DynamicPageList",
"category=" .. mw.title.getCurrentTitle().text .. "\n" ..
"namespace=" .. 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=" .. namespace .. "\n" ..
"count=10\n" ..
"mode=ordered\n" ..
"ordermethod=lastedit\n" ..
"order=ascending"
}
}
return [=[
{| id="newest-and-oldest-pages" class="wikitable" style="float: right; clear: both; margin: 0 0 .5em 1em;"
! Recent additions to the category
|-
| id="recent-additions" style="font-size:0.9em;" | ]=] .. recent .. [=[
|-
! Oldest pages ordered by last edit
|-
| 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
if type(current) == "string" then
category = current
display_name = current:gsub("^Category:", "")
else
category = "Category:" .. current:getCategoryName()
display_name = current:getBreadcrumbName()
end
display_name = capitalize(display_name)
table.insert(steps, 1, "]")
-- Move up the "chain" by one level.
if type(current) == "string" then
current = nil
else
current = current:getParents()
end
if current then
current = current.name
elseif inFundamental then
current = "Category:Fundamental"
end
end
steps = table.concat(steps, " » ")
return "<small>" .. steps .. "</small>"
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 "További információért lásd: ]."
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
table.sort(children, function(first, second) return first.sort < second.sort end)
local children_list = {}
for _, child in ipairs(children) do
local child_basic = child.name:getCategoryName()
local child_page = mw.title.new("Category:" .. child_basic)
if child_page.exists then
local child_description = child.name:getDescription("child")
table.insert(children_list, "* ]: " .. child_description)
end
end
return table.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 code = current:getInfo().code
if code and not require("Module:languages").getByCode(code) then
return nil
end
if not code then
code = "en"
end
-- If category can be empty, then it only contains subcategories.
local hasPages = not current:canBeEmpty()
local titleText = mw.title.getCurrentTitle().text
local inCategory
if hasPages then
inCategory = mw.site.stats.pagesInCategory(titleText, "pages")
else
inCategory = mw.site.stats.pagesInCategory(titleText, "subcats")
end
-- No need for a TOC if all pages or subcategories can fit on one page.
if inCategory > 200 then
-- This category is very large, see if there is an "extended" version of the TOC.
if inCategory > 2500 then
local TOC_template_extended = mw.title.new("Template:" .. code .. "-categoryTOC/full")
if TOC_template_extended.exists then
return mw.getCurrentFrame():expandTemplate{title = TOC_template_extended.text, args = {}}
end
end
local TOC_template = mw.title.new("Template:" .. code .. "-categoryTOC")
if TOC_template.exists then
return mw.getCurrentFrame():expandTemplate{title = TOC_template.text, args = {}}
end
end
return nil
end
return export