Модуль:Autosorting
Файл:Greek lc beta.svg | Этот модуль оценён как бета-версия. Он готов для широкого применения, но должен применяться с осторожностью. |
Время | Внимание! Это один из самых используемых модулей. |
Реализация шаблонов {{Сортировка: по типам}}, {{Сортировка: по странам}} и {{Сортировка: по изображениям}}. Подмодуль конфигурации: Модуль:Autosorting/config.
Тесты: Шаблон:Сортировка: по типам/тесты и Шаблон:Сортировка: по странам/тесты.
require( 'strict' ) local p = {} local mwLang = mw.getContentLanguage() local getArgs = require( 'Module:Arguments' ).getArgs local config = mw.loadData( 'Module:Autosorting/config' ) local function isEmpty( val ) return val == nil or val == '' end -- Получить назвние категории local function getCategoryName( str, name, val ) val = val or '' return string.format( str, mwLang:ucfirst( name ), val ) end -- Получить стандартный лимит local function getPageLimit( name, property ) name = mwLang:lcfirst( name ) property = mwLang:uc( property ) local propertyLimits = config.limits[ property ] if isEmpty( propertyLimits ) then return -1 end return propertyLimits[ name ] or propertyLimits.default end -- Получить соответствие категории критериям local function isValidCategory( name, catName, property, doNotCheck ) if not doNotCheck then local success, title = pcall( mw.title.new, 'Category:' .. catName ) if success and not isEmpty( title ) and title.exists then return true end end local success, catCount = pcall( mw.site.stats.pagesInCategory, catName, 'pages' ) if success then local pageLimit = getPageLimit( name, property ) return catCount > pageLimit end return false end -- Получить три первых значения из свойства в Викиданных -- TODO: переделать на получение Q-элементов, чтобы не зависеть от языка local function getWikidataProperty( frame, property, entityId ) frame = frame or mw.getCurrentFrame() local callArgs = { property, } if not isEmpty( entityId ) then callArgs.from = entityId end local success, result = pcall( frame.callParserFunction, frame, '#property', callArgs ) if success and not isEmpty( result ) then if mw.ustring.len( result ) > 255 then return {} end result = mw.text.split( result, ', ' ) return { unpack( result, 1, 3 ) } end return {} end -- Получить категорию для отсутствия изображений local function getFileCategory( frame, name, property, entityId ) if isEmpty( name ) then return '' end frame = frame or mw.getCurrentFrame() local propValues = getWikidataProperty( frame, property, entityId ) local catName = getCategoryName( name, property ) local instanceOf = getWikidataProperty( frame, 'p31', entityId ) instanceOf = #instanceOf > 0 and instanceOf[ 1 ] or '' local pageTitle = mw.title.getCurrentTitle().fullText local result = string.format( '[[Category:%s|%s%s]]', catName, instanceOf, pageTitle ) return #propValues, result end -- Сортировка по профессиям function p._byOccupation( frame, name, entityId ) if isEmpty( name ) then return '' end frame = frame or mw.getCurrentFrame() local property = 'p106' local propValues = getWikidataProperty( frame, property, entityId ) local result = '' for key, val in pairs( propValues ) do local value = mwLang:lcfirst( val ) local catName = getCategoryName( 'РуСказки:%s (тип: человек; род занятий: %s)', name, value ) -- Шаблон проставлял одну категорию if result ~= '' then break end if isValidCategory( name, catName, property ) then result = result .. string.format( '[[Category:%s]]', catName ) end end return result end -- Сортировка по типам function p._byType( frame, name, entityId ) if isEmpty( name ) then return '' end frame = frame or mw.getCurrentFrame() local property = 'p31' local propValues = getWikidataProperty( frame, property, entityId ) local defaultCatKey local result = '' for key, val in pairs( propValues ) do local catName = getCategoryName( 'РуСказки:%s (тип: %s)', name, mwLang:lcfirst( val ) ) -- TODO: переделать на получение Q-элементов, чтобы не зависеть от языка if val == 'человек' or val == 'human' then local occupations = p._byOccupation( frame, name, entityId ) if isEmpty( occupations ) then result = result .. string.format( '[[Category:%s]]', catName ) else result = result .. occupations end else if isValidCategory( name, catName, property ) then result = result .. string.format( '[[Category:%s]]', catName ) else if isEmpty( defaultCatKey ) then defaultCatKey = val end end end end -- Добавить стандартную категорию только при отсутствии иных local defaultCatName = getCategoryName( 'РуСказки:%s (не распределённые по типам)', name ) if result == '' and not isEmpty( defaultCatKey ) then local pageTitle = mw.title.getCurrentTitle().fullText result = result .. string.format( '[[Category:%s|%s%s]]', defaultCatName, defaultCatKey, pageTitle ) end if result == '' then return getCategoryName( '[[Category:РуСказки:%s (тип: не указан)]]', name ) end return result end -- Сортировка по АТЕ function p._bySubdivision( frame, name, entityId ) if isEmpty( name ) then return '' end frame = frame or mw.getCurrentFrame() local property = 'p131' local propValues = getWikidataProperty( frame, property, entityId ) local result = '' for key, val in pairs( propValues ) do local catName = getCategoryName( 'РуСказки:%s (АТЕ: %s)', name, val ) if isValidCategory( name, catName, property, false ) then result = result .. string.format( '[[Category:%s]]', catName ) end end return result end -- Сортировка по странам function p._byCountry( frame, name, entityId ) if isEmpty( name ) then return '' end frame = frame or mw.getCurrentFrame() local property = 'p17' local propValues = getWikidataProperty( frame, property, entityId ) local result = '' for key, val in pairs( propValues ) do if isEmpty( val ) then break end local catName = getCategoryName( 'РуСказки:%s (страна: %s)', name, val ) result = result .. string.format( '[[Category:%s]]', catName ) if isValidCategory( name, catName, property, false ) then result = result .. p._bySubdivision( frame, name, entityId ) end end return result end -- Сортировка по наличию/отсутствию изображений function p._byImage( frame, file, localFileProps, entityId ) frame = frame or mw.getCurrentFrame() -- Возможный сброс значения с Викиданных if file ~= nil and mw.text.trim( file ) == '-' then file = nil end -- Вывести категории при заполненном несуществующем файле (= файле с Викисклада) if not isEmpty( file ) then local success, title = pcall( mw.title.new, 'File:' .. file ) -- Игнорировать при заполненном локальном файле if success and not isEmpty( title ) and title.exists then return nil end local catName = 'РуСказки:Статьи с изображениями: заполнить свойство %s в Викиданных' local result = '' local p18, p18Category = getFileCategory( frame, catName, 'p18', entityId ) local p373, p373Category = getFileCategory( frame, catName, 'p373', entityId ) if p18 == 0 then result = result .. p18Category end if p373 == 0 then result = result .. p373Category end return result end -- Игнорировать при наличии изображений в указанных свойствах for _, val in pairs( localFileProps ) do local propValue = getWikidataProperty( frame, val, entityId ) if #propValue > 0 then return '' end end -- Вывести категории при отсутствии игнорируемых свойств local catName = 'РуСказки:Статьи без изображений (указано в Викиданных: %s)' local result = p._byCountry( frame, 'статьи без изображений', entityId ) local p18, p18Category = getFileCategory( frame, catName, 'p18', entityId ) local p242, p242Category = getFileCategory( frame, catName, 'p242', entityId ) local p373, p373Category = getFileCategory( frame, catName, 'p373', entityId ) if p18 > 0 then result = result .. p18Category end if p242 > 0 then result = result .. p242Category end if p373 > 0 then result = result .. p373Category end result = result .. p._byType( frame, 'статьи без изображений', entityId ) return result end -- Шаблон сортировки по типам function p.byType( frame ) local args = getArgs( frame ) local name = args[ 1 ] local entityId = args[ 'from' ] if isEmpty( name ) or not isEmpty( args.nocat ) then return nil end if mw.ustring.find( name, 'статьи' ) and mw.title.getCurrentTitle().namespace ~= 0 then return nil end return p._byType( frame, name, entityId ) end -- Шаблон сортировки по странам function p.byCountry( frame ) local args = getArgs( frame ) local name = args[ 1 ] local entityId = args[ 'from' ] if isEmpty( name ) or not isEmpty( args.nocat ) then return nil end if mw.ustring.find( name, 'статьи' ) and mw.title.getCurrentTitle().namespace ~= 0 then return nil end return p._byCountry( frame, name, entityId ) end -- Шаблон сортировки по изображениям function p.byImage( frame ) if mw.title.getCurrentTitle().namespace ~= 0 then return nil end local args = getArgs( frame ) local file = args[ 1 ] local entityId = args[ 'from' ] if not isEmpty( args.nocat ) then return nil end -- Игнорирование по умолчанию статей с указанным p18 local uses = args[ 'uses' ] if isEmpty( uses ) then uses = 'p18' end local localFileProps = mw.text.split( uses, ', ' ) if uses == '-' then localFileProps = {} end return p._byImage( frame, file, localFileProps, entityId ) end return p