Modul:Arg filter

Page skabelon-beskyttet
Fra Wikipedia, den frie encyklopædi
Documentation icon Moduldokumentation[vis] [redigér] [historik] [opfrisk]

Dette modul er filteret som bruges af {{Infoboks med filter}}.

Det læser alle argumenter til dets forældre-frame, dvs. de argumenter som den kaldende skabelon (normalt Skabelon:Infoboks med filter) selv blev kaldt med. Disse argumenter kan så ændres på 2 måder:

  • 1) Hvis der i et arguments værdi er brugt et særligt skilletegn (normalt bruges tegnet som laves af skabelonen {{Nyt felt}}), vil det som kommer efter skilletegnet blive brugt til ændre, oprette eller slette andre argumenter.
  • 2) Hvis et arguments navn begynder med "arg filter fjern", vil det argument hvis navn kommer efter "arg filter fjern", blive fjernet såfremt ikke mindst et af de argumenter som er nævnt i argumentets værdi, er til stede og ikke er tomt.

De nærmere detaljer for de 2 filterfunktioner er beskrevet i dokumentationen til Skabelon:Infoboks med filter.

Modulet vil så kalde et andet modul med de eventuelt ændrede argumenter, og returnere dette moduls returværdi. Det andet modul kaldes uden en frame, men med argumenttabellen direkte som første argument. Det vil afhænge af hvordan det kaldte modul håndterer sine argumenter om denne kaldmetode vil virke.

Modulet kaldes gennem funktionen filter(frame). Funktionens direkte argumenter i egen frame er:

  • 1. unavngivne argument: Modul som skal kaldes
  • 2. unavngivne argument: Funktionen som skal kaldes i det kaldte modul
  • 3. unavngivne argument: Det tegn som skal bruges som skilletegn i filterfunktion nr. 1.


Kategori mangler
Dette modul hører til i en eller flere kategorier. Kategoriser venligst dette modul ved at placere den sammen med lignende emner. Fjern skabelonen efter kategorisering. Bemærk, at kategorier påsat via skabeloner, samt meget generelle kategorier ikke bør betragtes som tilstrækkelige.

-- Dette modul bruges af [[Skabelon:Infoboks med filter]]. Se skabelondokumentationen for detaljer.

-- Module to act as a filter between a template and another module
-- The transfered arguments from the template may be changed before calling the other module
-- The return value from the other module is returned unchanged

-- This module is made especially as a filter for Module:Infoboks.

-- WARNING: The arguments are transferred in another way than normal, and the current frame
-- is not transferred as normal. It may not work depending on how the called module interprets
-- its arguments and frame. This should work with Module:Infoboks. Check carefully before other uses.

local p = {}

-- Direct arguemnts (to be applied in #invoke call):
-- 1 argument: Module to call
-- 2 argument: Function to call in the module
-- 3 argument: Delimiter for parsing transfered template arguments

-- Arguments from the calling template:

-- If any argument contains the delimiter, it will be split into the parts between
-- occurances of the delimiter. The first part will be the new value for the argument.
-- Any subsequent parts will be spilt to <name>=<value> parts, and new arguments with
-- the given name and value will be created. Any existing arguments with the same names
-- will be overwritten. If the value part is empty, any existing argument with the name
-- will be removed without replacement.

-- If any argument starts with "arg filter fjern" then the rest of that argument names
-- an argument which may be deleted. The argument value is a comma separated list
-- of argument names. The argument in the argument name will be deleted if all of the
-- arguments in the argument list are not defined or only contains whitespace.

p.filter = function(frame)
	local my_args = frame.args

	local module = mw.text.trim(my_args[1] or '')
	local func = mw.text.trim(my_args[2] or '')
	local delim = mw.text.trim(my_args[3] or '')

	if module == '' or func == '' or delim == '' then
		return 'Error: Module Arg filter called without module, function or delimiter arguments'
	end

	local args
	if frame == mw.getCurrentFrame() then
		-- Arguments from the parent template
		args = frame:getParent().args
	else
		-- Try local given arguments for testing
		args = frame.args
	end

	local old_args = {}
	local changed_args = {}
	local deleted_args = {}
	local test_for_deletion = {}

	local mwText = mw.text
	local string = string

	for name, value in pairs(args) do
		if string.sub(name, 1, 16) == 'arg filter fjern' then
			test_for_deletion[mwText.trim(string.sub(name, 17))] = value
		else
			local first_part = true
			for part in mwText.gsplit(value, delim, true) do
				if first_part then
					old_args[name] = part
					first_part = nil
				else
					local new_name, new_value = string.match(part, '^(.-)=(.*)$')
					if new_name then
						new_name = mwText.trim(new_name)
						if new_name ~= '' then
							if new_value ~= '' then
								changed_args[new_name] = new_value
							else
								deleted_args[new_name] = true
							end
						end
					end
				end
			end
		end
	end

	for name, value in pairs(changed_args) do
		old_args[name] = value
	end

	for name, value in pairs(deleted_args) do
		old_args[name] = nil
	end

	for name, value in pairs(test_for_deletion) do
		if old_args[name] then
			local found_not_empty_arg
			for arg in mwText.gsplit(value, ',', true) do
				arg = mwText.trim(arg)
				if old_args[arg] and mwText.trim(old_args[arg]) ~= '' then
					found_not_empty_arg = true
					break
				end
			end
			if found_not_empty_arg == nil then
				old_args[name] = nil
			end
		end
	end

	-- I cannot change the current frame. It is no use to create a new frame for calling Module:Infoboks
	-- because it tests if the passed frame argument is really the current frame or not. Instead just
	-- pass the changed args alone as Module:Infoboks will assume that it is args when not the current frame. 
	return require(module)[func](old_args)
end

return p