<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://wiki.dzmuh.com/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%3AMetaCat</id>
	<title>Модуль:MetaCat - История изменений</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.dzmuh.com/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%3AMetaCat"/>
	<link rel="alternate" type="text/html" href="https://wiki.dzmuh.com/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:MetaCat&amp;action=history"/>
	<updated>2026-05-05T10:38:49Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.38.4</generator>
	<entry>
		<id>https://wiki.dzmuh.com/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:MetaCat&amp;diff=14686&amp;oldid=prev</id>
		<title>Dzmuh: Новая страница: «-- ══════════════════════════════════════════════════════════════════════════════ -- ◆ MetaCat - Универсальный модуль категоризации для Википедии -- ═════════════════════════════════════...»</title>
		<link rel="alternate" type="text/html" href="https://wiki.dzmuh.com/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:MetaCat&amp;diff=14686&amp;oldid=prev"/>
		<updated>2026-01-26T06:44:45Z</updated>

		<summary type="html">&lt;p&gt;Новая страница: «-- ══════════════════════════════════════════════════════════════════════════════ -- ◆ MetaCat - Универсальный модуль категоризации для Википедии -- ═════════════════════════════════════...»&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- ══════════════════════════════════════════════════════════════════════════════&lt;br /&gt;
-- ◆ MetaCat - Универсальный модуль категоризации для Википедии&lt;br /&gt;
-- ══════════════════════════════════════════════════════════════════════════════&lt;br /&gt;
--&lt;br /&gt;
-- Главный диспетчер системы MetaCat. Автоматически определяет тип категории&lt;br /&gt;
-- по заголовку страницы и делегирует обработку соответствующему модулю.&lt;br /&gt;
--&lt;br /&gt;
-- АРХИТЕКТУРА:&lt;br /&gt;
--   MetaCat (диспетчер)&lt;br /&gt;
--     ├── MetaCat/Core       — общая логика, утилиты, фабрики&lt;br /&gt;
--     ├── MetaCat/Year       — обработчик категорий годов&lt;br /&gt;
--     ├── MetaCat/Decade     — обработчик категорий десятилетий&lt;br /&gt;
--     ├── MetaCat/Century    — обработчик категорий веков&lt;br /&gt;
--     ├── MetaCat/Millennium — обработчик категорий тысячелетий&lt;br /&gt;
--     └── MetaCat/Geo        — обработчик географических объектов (страны, части света, города, регионы)&lt;br /&gt;
--&lt;br /&gt;
-- ПРИОРИТЕТ ОПРЕДЕЛЕНИЯ ТИПА:&lt;br /&gt;
--   1. Параметр force=year/decade/century (принудительный тип)&lt;br /&gt;
--   2. Временные паттерны в заголовке (год/десятилетие/век)&lt;br /&gt;
--   3. Временные плейсхолдеры в аргументах (&amp;lt;год&amp;gt;, &amp;lt;век&amp;gt;)&lt;br /&gt;
--   4. Географические плейсхолдеры (&amp;lt;страна&amp;gt;, &amp;lt;город&amp;gt;)&lt;br /&gt;
--   5. Географические объекты в заголовке (через Find topic)&lt;br /&gt;
--&lt;br /&gt;
-- ══════════════════════════════════════════════════════════════════════════════&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- ══════════════════════════════════════════════════════════════════════════════&lt;br /&gt;
-- ▼ РАЗДЕЛ 1: ЗАВИСИМОСТИ&lt;br /&gt;
-- ══════════════════════════════════════════════════════════════════════════════&lt;br /&gt;
&lt;br /&gt;
local getArgs = require('Модуль:Arguments').getArgs&lt;br /&gt;
local Core = require('Модуль:MetaCat/Core')&lt;br /&gt;
&lt;br /&gt;
-- ══════════════════════════════════════════════════════════════════════════════&lt;br /&gt;
-- ▼ РАЗДЕЛ 2: КОНФИГУРАЦИЯ&lt;br /&gt;
-- ══════════════════════════════════════════════════════════════════════════════&lt;br /&gt;
&lt;br /&gt;
local MODULES = {&lt;br /&gt;
	year       = { module = 'Year',       supports_expand = true },&lt;br /&gt;
	decade     = { module = 'Decade',     supports_expand = true },&lt;br /&gt;
	century    = { module = 'Century',    supports_expand = true },&lt;br /&gt;
	millennium = { module = 'Millennium', supports_expand = true },&lt;br /&gt;
	geo        = { module = 'Geo',        supports_expand = true }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- ══════════════════════════════════════════════════════════════════════════════&lt;br /&gt;
-- ▼ РАЗДЕЛ 3: ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ&lt;br /&gt;
-- ══════════════════════════════════════════════════════════════════════════════&lt;br /&gt;
&lt;br /&gt;
local function get_module_name(category_type)&lt;br /&gt;
	return MODULES[category_type] and MODULES[category_type].module or nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function supports_expand(category_type)&lt;br /&gt;
	return MODULES[category_type] and MODULES[category_type].supports_expand or false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function build_module_map(category_type)&lt;br /&gt;
	local module_map = {}&lt;br /&gt;
	if category_type then&lt;br /&gt;
		local module_name = get_module_name(category_type)&lt;br /&gt;
		if module_name then&lt;br /&gt;
			module_map[category_type] = module_name&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return module_map&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function parse_common_params(frame)&lt;br /&gt;
	local args = getArgs(frame)&lt;br /&gt;
	local title = args['title'] or mw.title.getCurrentTitle().text&lt;br /&gt;
	return args, title&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ══════════════════════════════════════════════════════════════════════════════&lt;br /&gt;
-- ▼ РАЗДЕЛ 4: ДЕТЕКЦИЯ ТИПА КАТЕГОРИИ&lt;br /&gt;
-- ══════════════════════════════════════════════════════════════════════════════&lt;br /&gt;
&lt;br /&gt;
-- ▼ Определение типа по плейсхолдерам в аргументах (общая логика)&lt;br /&gt;
local function detect_type_from_placeholders(args)&lt;br /&gt;
	if not args then return nil end&lt;br /&gt;
	&lt;br /&gt;
	local template_type = Core.detect_template_time_type(args)&lt;br /&gt;
	if template_type then&lt;br /&gt;
		return template_type&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	for _, arg in pairs(args) do&lt;br /&gt;
		if type(arg) == 'string' then&lt;br /&gt;
			if Core.has_country_placeholders(arg) or Core.has_month_placeholder(arg) then&lt;br /&gt;
				return 'geo'&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ▼ Определение типа категории (для страниц категорий)&lt;br /&gt;
-- Приоритет: force → заголовок → плейсхолдеры&lt;br /&gt;
local function detect_category_type(title, args)&lt;br /&gt;
	-- Приоритет 0: Принудительный тип через параметр force (кроме force=geo)&lt;br /&gt;
	if args and args['force'] then&lt;br /&gt;
		local force_type = mw.ustring.lower(args['force'])&lt;br /&gt;
		if force_type ~= 'geo' and MODULES[force_type] then&lt;br /&gt;
			return force_type&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Приоритет 1: Временные паттерны в заголовке&lt;br /&gt;
	local time_type = Core.detect_category_time_type(title, args)&lt;br /&gt;
	if time_type then&lt;br /&gt;
		return time_type&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Приоритет 2: Плейсхолдеры в аргументах&lt;br /&gt;
	return detect_type_from_placeholders(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ▼ Определение типа шаблона (для категоризации шаблонов)&lt;br /&gt;
-- Приоритет: force → плейсхолдеры → заголовок&lt;br /&gt;
local function detect_template_type(title, args)&lt;br /&gt;
	-- Приоритет 0: Принудительный тип через параметр force (кроме force=geo)&lt;br /&gt;
	if args and args['force'] then&lt;br /&gt;
		local force_type = mw.ustring.lower(args['force'])&lt;br /&gt;
		if force_type ~= 'geo' and MODULES[force_type] then&lt;br /&gt;
			return force_type&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Приоритет 1: Плейсхолдеры в аргументах&lt;br /&gt;
	local placeholder_type = detect_type_from_placeholders(args)&lt;br /&gt;
	if placeholder_type then&lt;br /&gt;
		return placeholder_type&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Приоритет 2: Временные паттерны в заголовке (fallback)&lt;br /&gt;
	return Core.detect_category_time_type(title, args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ══════════════════════════════════════════════════════════════════════════════&lt;br /&gt;
-- ▼ РАЗДЕЛ 5: ПУБЛИЧНЫЙ API&lt;br /&gt;
-- ══════════════════════════════════════════════════════════════════════════════&lt;br /&gt;
&lt;br /&gt;
-- ▼ Главная функция модуля&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local args, title = parse_common_params(frame)&lt;br /&gt;
&lt;br /&gt;
	-- Категоризация шаблонов&lt;br /&gt;
	-- Для шаблонов тип определяется по плейсхолдерам в аргументах (приоритет), затем по заголовку&lt;br /&gt;
	if mw.title.getCurrentTitle().namespace == 10 then&lt;br /&gt;
		local template_type = detect_template_type(title, args)&lt;br /&gt;
		local module_name = template_type and get_module_name(template_type)&lt;br /&gt;
		local full_module_name = module_name and ('MetaCat/' .. module_name) or 'MetaCat'&lt;br /&gt;
		return Core.template_module_categories(full_module_name, args)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local category_type = detect_category_type(title, args)&lt;br /&gt;
	local module_map = build_module_map(category_type)&lt;br /&gt;
	return Core.dispatch_to_module(frame, category_type, module_map, 'MetaCat')&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ▼ Функция расширения плейсхолдеров&lt;br /&gt;
function p.expand(frame)&lt;br /&gt;
	local args, title = parse_common_params(frame)&lt;br /&gt;
	local category_type = detect_category_type(title, args)&lt;br /&gt;
&lt;br /&gt;
	if not category_type or not supports_expand(category_type) then&lt;br /&gt;
		return ''&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local module_map = build_module_map(category_type)&lt;br /&gt;
	return Core.expand_with_module(frame, category_type, module_map)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ▼ Отладка: определение типа категории&lt;br /&gt;
function p.detect_type(frame)&lt;br /&gt;
	local args, title = parse_common_params(frame)&lt;br /&gt;
	local category_type = detect_category_type(title, args)&lt;br /&gt;
&lt;br /&gt;
	if not category_type then&lt;br /&gt;
		return '&amp;lt;span class=&amp;quot;error&amp;quot;&amp;gt;Тип категории: не определён&amp;lt;/span&amp;gt;'&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local module_name = get_module_name(category_type)&lt;br /&gt;
	return string.format('Тип: %s → модуль: %s', category_type, module_name or 'неизвестен')&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Dzmuh</name></author>
	</entry>
</feed>