Модуль:NextPrev

Материал из Народные Сказки

Реализация ссылок на предыдущий и следующий дни для шаблона {{Шапка обсуждений по дням}}.

Тесты модуля[править код]

5 тестов провалено.

test_next_prev
Тест Ожидаемое значение Фактическое значение
Файл:X mark.svgN {{#invoke:NextPrev|next_prev|РуСказки:К объединению|1 сентября 2021}} << | >>  
test_prev_date
Тест Ожидаемое значение Фактическое значение
Файл:X mark.svgN {{#invoke:NextPrev|prev_date|parent_page=РуСказки:К объединению|raw_date=4 сентября 2021}} РуСказки:К объединению/3 сентября 2021
Файл:X mark.svgN {{#invoke:NextPrev|prev_date|parent_page=РуСказки:К объединению|raw_date=7 сентября 2021}} РуСказки:К объединению/5 сентября 2021
Файл:X mark.svgN {{#invoke:NextPrev|prev_date|parent_page=РуСказки:К объединению|raw_date=1 сентября 2021}} РуСказки:К объединению/31 августа 2021
{{#invoke:NextPrev|prev_date|parent_page=РуСказки:К разделению|raw_date=6 ноября 2021}}
Файл:X mark.svgN {{#invoke:NextPrev|prev_date|parent_page=РуСказки:Кандидаты в избранные списки и порталы|raw_date=2021-05-07|f=Y-m-d}} РуСказки:Кандидаты в избранные списки и порталы/2021-05-06

-- Module that should replace {{NextPrev}}
local p = {}
--local mw_time = mw.getContentLanguage():formatDate()

local yyyymmdd = require('Module:Dates').yyyymmdd
-- parses date
-- if it is: "7 ноября 2021" then transforms to yyyy-mm-dd
-- if it matches "^%s*%d+\-%d+\-%d+" which means format "*-*-*" where the order could be different but it ASSUMES that it is yyyy-mm-dd then does nothing

local Date = require('Module:Date')._Date
--?

-- date is Date object from Module:Date
local function prev_date(frame, parent_page, date, format)
	if(date == nil or date == '') then
		return "|"
	end
	local prev_title = nil
	for i = 1, 20 do
		local check_date = date-string.format('%dd',i) --expected to subtract something like '3d'
		local title = mw.title.new(parent_page..'/'..frame:callParserFunction('#time', format, check_date:text(), 'ru'))
		if (title.exists) then --expensive call
			prev_title = title
			break
		end
	end
	return prev_title
end

-- date is Date object from Module:Date
local function next_date(frame, parent_page, date, format)
	if(date == nil or date == '') then
		return "|"
	end
	local next_title = nil
	for i = 1, 20 do
		local check_date = date+string.format('%dd',i) --expected to subtract something like '3d'
		local title = mw.title.new(parent_page..'/'..frame:callParserFunction('#time', format, check_date:text(), 'ru'))
		if (title.exists) then --expensive call
			next_title = title
			break
		end
	end
	return next_title
end

-- next_prev seeks for previous and next non-empty page of discussion
-- the input date is supposed to be in format 22_октября_2021, alternatively an optional parameter f can contain format
-- the input date is supposed to be extracted from SUBPAGENAME but is not guaranteed to happen so
-- parent_page needs to include namespace like "РуСказки:К удалению"
function p.next_prev(frame)
	local parent_page = frame.args[1] or frame.args['parent_page']   -- no default value here
	local input_date  = frame.args[2] or frame.args['raw_date']      -- no default value here
	if(input_date == nil or input_date == '') then
		return "|"
	end
	local format      = frame.args[3] or frame.args['f'] or 'j xg Y' -- default format 'j xg Y'
	if (format=='') then
		format = 'j xg Y'
	end
	-- Get the date we are considering from text representation
	local current_page_date = yyyymmdd({args = {input_date}}) -- yyyymmdd accepts not a date, but a frame, so we artificially envelop
	local current_page_date_object = Date(current_page_date)
	
	-- Find the previous and next page that exist
	local prev_title = prev_date(frame,parent_page,current_page_date_object, format)
	local next_title = next_date(frame,parent_page,current_page_date_object, format)
	
	-- If the pages were found, form navigation buttons
	local str = ""
	if (prev_title ~= nil and prev_title.fullText ~= nil) then
		str = str..string.format('[[%s|<<]]', prev_title.fullText)
	end
	str = str.."&nbsp;|&nbsp;"
	if (next_title ~= nil and next_title.fullText ~= nil) then
		str = str..string.format('[[%s|>>]]', next_title.fullText)
	end
	return str
end

-- This version of prev_date includes convertation of raw_date into Date object
-- the argument is a frame meant to be used with #invoke:NextPrev|prev_date|parent_page=|raw_date=
function p.prev_date(frame)
	local parent_page = frame.args['parent_page']
	local current_page_date = yyyymmdd({args = {frame.args['raw_date']}})
	local date = Date(current_page_date)
	local format = frame.args['f'] or 'j xg Y'
	return prev_date(frame, parent_page, date, format)
end

-- This version of next_date includes convertation of raw_date into Date object
-- the argument is a frame meant to be used with #invoke:NextPrev|next_date|parent_page=|raw_date=
function p.next_date(frame)
	local parent_page = frame.args['parent_page']
	local current_page_date = yyyymmdd({args = {frame.args['raw_date']}})
	local date = Date(current_page_date)
	local format = frame.args['f'] or 'j xg Y'
	return next_date(frame, parent_page, date, format)
end

return p