יחידה:תבנית מידע

From האנציקלופדיה היהודית
Jump to: navigation, search

תבנית מידע היא יחידה המשמשת ליצירת תבניות מידע (infobox) בצורה קלה והמקושרות לוויקינתונים.

אופן השימוש

להלן תיעוד קצר של הפרמטרים הנתמכים על ידי היחידה. ניתן להיעזר גם ב#דוגמאות שימוש.

הגדרת פרמטרים

  • היחידה תומכת בקבלת פרמטרים ממסופרים כאשר המספר מגדיר יחס סדר בין הפרמטרים
  • סוגי הפרמטרים הנתמכים (יש להחליף את X במספר)
    • תוויתX - תווית עבור פרמטר מספר X (לא יוצג ללא מילוי מידעX)
    • מידעX - תוכן עבור פרמטר X
      • אם מופיע פרמטר תוויתX, יופיע משמאל לתווית המתאימה שהוגדרה
      • אם לא מופיע פרמטר תוויתX, יוצג בשתי עמודות
      • תווית-מידעX - קיצור דרך כדי לציין פרמטר שהתווית שלו זהה לשם הפרמטר (מקביל ל "תוויתX=שם הפרמטר" בצירוף "מידעX={{{שם הפרמטר|}}}". התווית יכולה להכיל קישור, אשר מוסר משם הפרמטר.
    • כותרתX - כותרת שתופיע לפני מקבץ של פרמטרים (הפרמטרים X+1, X+2 וכו'). הכותרת תופיע רק אם הפרמטרים שמופיעים בינה לבין הכותרת הבאה אחריה מלאים. (ראו removeEmptyHeaders)
    • תמונה וכיתוב - הגדרת התוכן שיופיע כתמונה, והתוכן שיופיע ככיתוב
    • תמונה ימין ותמונה שמאל - תוכן שיופיע עבור תמונה שתופיע מימין/שמאל (בתבנית שתומכות בתמונה ימנית ושמאלית)
    • כותרת תבנית - מציין את הכותרת הראשית לתבנית

תמיכה בוויקינתונים

התבנית תומכת במילוי אוטומטי של מידע מוויקינתונים כאשר לא מוזן מידע על ידי המשתמשים:

  • קואורדינטות - עבור פרמטר שנקרא קואורידנטות התבנית מוסיפה בצורה אוטומטית {{קואורדינטות מוויקינתונים}}. אין צורך להגדיר בצורה מיוחדת, אך יש להימנע ממתן שם "קואורדינטות" לפרמטר שלא מיועד לקואורדינטות גאוגרפיות
  • עבור {{{שם הפרמטר}}} היחידה מחפשת הגדרה של "שם הפרמטר-ויקינתונים" המגדיר את שם התכונה שיש למשוך מוויקינתונים במקרה שהמידע לא הוזן על ידי המשתמש. לשימושים מתקדמים:
    • שם הפרמטר-ויקינתונים מגדיר משיכה חכמה של פרמטרים מוויקינתונים, שיודעת להוסיף קישורים מתאימים לערכים, להגדיר תמונות , ולהוסיף "נכון ל" עבור ערכים מספריים (ראו עוד ביחידה:PropertyLink)
    • שם הפרמטר-ויקינתונים-פשוט - מגדיר משיכה לא חכמה של פרמטרים מוויקינתונים
    • שם הפרמטר-ויקינתונים-מרובה - מגדיר שאפשר למשוך מספר ערכים מוויקינתונים, כשכל ערך מופרד בפסיק.

הגדרות מתקדמות נוספות לשליטה על אופן התצוגה של ערכים מיובאים מוויקינתונים:

  • שם הפרמטר-ויקינתונים-מרובה-הפרדה - מאפשר להגדיר את התו המפריד בין ערכים שונים. ברירת המחדל היא פסיק (,). בשדות שעשויות להכיל תוכן רב, מומלץ להגדיר את ההפרדה כשבירת שורה (<br>)
  • שם הפרמטר-ויקינתונים-פרטים - מאפשר להגדיר פרט אופציונלי נוסף שיופיע בסוגריים ליד הנתון. הפרט הנוסף צריך להיות שם של מבחין (Qualifier).
  • שם הפרמטר-ויקינתונים-מגדר - יש לציין "כן" אם ערכי הפרמטר תלויים במגדר. למשל בפרמטר של "עיסוק" נרצה "סופר" או "סופרת" בהתאם למין.

עיצוב

הפרמטרים הבאים מאפשרים שליטה על עיצוב התבנית:

  • עיצוב-שורהX - שליטה על עיצוב שורה
  • תוויתX-עיצוב - שליטה על עיצוב תוויתX
  • מידעX-עיצוב - שליטה על עיצוב מידעX
  • כותרתX-עיצוב - שליטה על עיצוב כותרתX
  • כותרת תבנית-עיצוב - הגדרת עיצוב לכותרת התבנית
  • כותרת תבנית-מחלקה - הגדרת מחלקת עיצוב לכותרת התבנית
  • טבלה-עיצוב - מגדירה את עיצוב הטבלה
  • טבלה-מחלקה - מגדירה מחלקה לעיצוב הטבלה. דוגמאות למחלקות שימושיות:
    • infobox-nowrap-labels - מגדירה ללא שבירות שורה בתוויות
    • bordered - מוסיפה מסגרות

הסתרת פרמטר

כאשר מעוניינים להסתיר פרמטר שהתבנית מקבלת, ניתן להגדיר את הערך שלו כ"-".

דוגמאות שימוש

ניתן להיעזר בתבניות אחרות שמשתמשות ביחידה זו כדוגמאות (מיוחד:דפים המקושרים לכאן/יחידה:תבנית מידע)


local propertyLink = require('Module:PropertyLink')
local WikidataCrossValidation = require('Module:WikidataCrossValidation')
local Infobox = {}
function Infobox:new()
	local o = {
		args={},
		templateStructure={},
		isSelfUse=false,
		autoDocumentation=false,
		wikidataCats= {},
		root = mw.html.create('table')
	}
	setmetatable(o, self)
	self.__index = self
	
	return o
end

function Infobox:render()
	if self.isSelfUse then
		local templateDocumentation=''
		for k,v in pairs(self.templateParams) do
			if mw.ustring.match( k, '-ויקינתונים') then
				templateDocumentation = templateDocumentation .. '[[קטגוריה:תבניות מידע שמשתמשות בוויקינתונים]]'
				break
			end
		end
		if self.autoDocumentation then
			templateDocumentation = templateDocumentation .. self:_generateDocumentation()			
		end
		return self:renderInfobox() .. templateDocumentation
	end

	return self:renderInfobox() .. table.concat(self.wikidataCats, '')
end
 
--[[
Generate auto documentation for template.
]]
function Infobox:_generateDocumentation() 
	local labelDataPrefix = 'תווית-מידע'
	
	local parameters = {}
	for k,v in pairs(self.templateParams) do
		if mw.ustring.match( tostring(k),'תווית%-מידע%d' )  then
			table.insert(parameters, '"'..string.gsub(v, '"', '\\"')..'":'..'{ "description": ""}')
		else
			for mm in mw.ustring.gmatch( tostring(v),'%{%{%{(.-)[%}|]') do
				table.insert(parameters, '"'..string.gsub(mm, '"', '\\"')..'":'..'{ "description": ""}')
			end
		end
		
	end
	local templateDoc = '{ "params": { '..table.concat(parameters,'\n,')..'}}'
	return frame:extensionTag( 'templatedata', templateDoc )
end

--[[ 
Renders the infobox title
]]
function Infobox:renderTitle()
	-- renders the title
	local  titleCaption = self.root
        :tag('caption')
        	:attr('dir', 'auto')
            :addClass(self.args.titleclass)
            :cssText(self.args.titlestyle)
            :wikitext(self.args.title)

	if self.args.subtitle and  self.args.subtitle~=nil and #(self.args.subtitle)>0 then
		local row = self.root:tag('tr')
				:tag('th')
				:attr('colspan', 2)
				:css('text-align','center')
				:cssText(self.args.subtitlestyle)
				:addClass(self.args.subtitleclass)
				:wikitext(self.args.subtitle)
	end
	return self.titleCaption
end

--[[ 
Renders the right/left images (possibly 1/2/none of them available) and the main image
]]
function Infobox:renderImages()
	-- render right an left images 
	self.args.rightImage = self.args.rightImage~=nil and #(self.args.rightImage)>0 and self.args.rightImage
	self.args.leftImage = self.args.leftImage~=nil and #(self.args.leftImage)>0 and self.args.leftImage
	
	if self.args.rightImage or self.args.leftImage then
		if self.args.rightImage and self.args.rightImageDesc~=nil and #(self.args.rightImageDesc)>0 then
			self.args.rightImage = self.args.rightImage..'<div>' .. self.args.rightImageDesc .. '</div>'
		end
		if self.args.leftImage and self.args.leftImageDesc~=nil and #(self.args.leftImageDesc)>0 then
			self.args.leftImage = self.args.leftImage .. '<div>' .. self.args.leftImageDesc .. '</div>'
		end
		local row = self.root:tag('tr')
						:tag('td')
						:attr('colspan', 2)
						:css('text-align','center')
		if self.args.rightImage and self.args.leftImage then
			row:tag('table')
				:css('width','100%')
				:css('display','table')
				:tag('tr')
					:tag('td')
						:css('width','50%')
						:css('vertical-align','middle')
						:css('text-align','center')
						:wikitext(self.args.rightImage)
					:tag('td')
						:css('width','50%')
						:css('vertical-align','middle')
						:css('text-align','center')
						:wikitext(self.args.leftImage)
					:done()
		else
			row:wikitext(self.args.leftImage or self.args.rightImage)
		end
	end
	-- render the main image
	if self.args.image then
		self.root:tag('tr')
			:tag('td')
			:attr('colspan', 2)
			:css('text-align','center')
			:wikitext(self.args.image)
		if self.args.imageDesc and #self.args.imageDesc>0 then
			self.root:tag('tr')
			:tag('td')
			:attr('colspan', 2)
			:addClass('thumbcaption')
			:addClass('borderless')
			:css('text-align','center')
			:wikitext(self.args.imageDesc)
		end
		
	end
end

--[[ 
Adds edit links for easier editing of the template. If the template use data from wikidata it also adds edit link in Wikidata
]]
function Infobox:renderEditLinks()
	local wbEdit='' -- link to wikidata
	if self.args.usingWikidata then
		wbEdit = '[[File:Wikidata-logo S.svg|22px|link=d:'..self.args.entityId..'|לעריכה בוויקינתונים שמשמש מקור לחלק מהמידע בתבנית]]'
		wbEdit = wbEdit .. mw.ustring.format(' [[File:OOjs UI icon info big.svg|16px|link=%s]]', 'עזרה:תבנית מידע')
	end
	if #wbEdit > 0 then
		self.root:tag('tr')
			:tag('td')
			:attr('colspan', 2)
			:css('text-align','left')
			:wikitext(wbEdit)
	end
end

--[[ 
Adds a styled row to the table
]]
function Infobox:addRow(rowArgs)
    -- Adds a row to the infobox, with either a header cell
    -- or a label/data cell combination.
    if rowArgs.header then
        self.root
            :tag('tr')
                :addClass(rowArgs.rowclass)
                :cssText(self.args.rowsstyle)
                :cssText(rowArgs.rowstyle)
                :attr('id', rowArgs.rowid)
                :tag('th')
                    :attr('colspan', 2)
                    :attr('id', rowArgs.headerid)
                    :addClass(rowArgs.class)
                    :addClass(self.args.headerclass)
                    :css('text-align', 'center')
                    :cssText(self.args.headerstyle)
                    :cssText(rowArgs.headerstyle)
                    :newline()
                    :wikitext(rowArgs.data)
    elseif rowArgs.data and #(rowArgs.data) > 0 then
        local row = self.root:tag('tr')
        row:addClass(rowArgs.rowclass)
           :cssText(self.args.rowsstyle)
           :cssText(rowArgs.rowstyle)
           :attr('id', rowArgs.rowid)
        if rowArgs.label then
            row
                :tag('th')
                    :attr('scope', 'row')
                    :attr('id', rowArgs.labelid)
                    :cssText(self.args.labelstyle)
                    :cssText(rowArgs.labelstyle)
                    :newline()
                    :wikitext(rowArgs.label)
                    :done()
        end
 
        local dataCell = row:tag('td')
        if not rowArgs.label then 
            dataCell
                :attr('colspan', 2)
            if not rowArgs.datastyle then 
                dataCell:css('text-align', 'center') 
            end
        end
        dataCell
            :attr('id', rowArgs.dataid)
            :addClass(rowArgs.class)
            :cssText(self.args.datastyle)
            :cssText(rowArgs.datastyle)
            :newline()
            :wikitext(rowArgs.data)
    end
end


 --[[ 
This function removes redundent keys from templateStructure: nil entries and header entries with no data
]]
function Infobox:removeEmptyHeaders()
 	local lastHeaderIndex=nil
 	local removeFirstHeader = (not self.args.image or #self.args.image==0) -- remove the first header if there is no image
	
 	local tempTemplateStructure = {}
 	for i,v in pairs(self.templateStructure) do
  		if v~=nil then
 			if v.header then
 				lastHeaderIndex = i
 			else
 				if lastHeaderIndex then
 					if not removeFirstHeader then
 						table.insert(tempTemplateStructure, self.templateStructure[lastHeaderIndex])
 					end
 					lastHeaderIndex = nil
 				end
 				removeFirstHeader = false
 				table.insert(tempTemplateStructure, v)
 			end
 		end
 	end
 	self.templateStructure=tempTemplateStructure
end

--[[ 
This function builds the infobox table using structure templateStructure and args
]]
function Infobox:renderInfobox()
	self:removeEmptyHeaders()
	-- error if there is no data/structure given to template from wiki page or wikidata
	if ((#self.templateStructure)==0) and not self.args.subtemplate then
		local templateTitle = mw.getCurrentFrame():getParent():getTitle()
		errors = {}
		
		local templateName = mw.ustring.gsub(templateTitle, 'תבנית:', '', 1)
		if mw.title.getCurrentTitle().namespace==0 then
			table.insert(errors, '[[קטגוריה:שגיאות פרמטריות בתבנית '..templateName..']]')
			table.insert(errors, '[[קטגוריה:שגיאות פרמטריות בתבנית מידע]]')
			table.insert(errors, '[[קטגוריה:שגיאות פרמטריות]]' )
		else
			table.insert(errors, '[[קטגוריה:שגיאות פרמטריות מחוץ למרחב הערכים]]')
		end
		local report = 'תבנית {{' .. templateName .. '}} ריקה מתוכן. יש להזין פרמטרים בערך או בוויקינתונים. ' .. table.concat(errors, '')
		local ParamValidator = require('Module:ParamValidator')
		return ParamValidator.wrapReport(report, templateName, {})
	end
	
	-- sub infobox
	if self.args.subtemplate then
		self.root:cssText(self.args.tablestyle):css('width', '100%'):css('line-height', '1.4em')
	else
		self.root:addClass('infobox'):cssText(self.args.tablestyle)
	end
	if self.args.tableclass then
		self.root:addClass(self.args.tableclass)
	end
	if self.args.title ~='-' then
		self:renderTitle()
	end
	
	if not self.args.subtemplate then
		self:renderImages()
	end
	
	local infobox_rows={}
	for k,v in pairs(self.templateStructure) do
		self:addRow(v)
	end
	if self.args.title ~= '-' then
		self:renderEditLinks()
	end
	
	return tostring(self.root)
end

--[[ 
This function adds image using valueArg, or if not specified by the user tries to get image from wikidata using property
]]
function getValueOrWikidataImage(args)
	valueArg = args.valueArg
	if valueArg and #valueArg>0 then 
		if valueArg == '-' then
			return nil
		else
			if not mw.ustring.match(valueArg, '^ *%[%[') and
			not mw.ustring.match(valueArg, '^ *%[%[') and 
			   not  mw.ustring.match(valueArg, '^ *<') then
			   	local imgSuffix = '|'..args.width .. 'px'
			   	if args.imgDesc~=nil and #args.imgDesc>0 then
			   		imgSuffix = imgSuffix .. '|' .. args.imgDesc
			   	end
			   	imgSuffix = imgSuffix .. ']]'
				if mw.ustring.match(valueArg, '^[Ff]ile:') or 
				mw.ustring.match(valueArg, '^[Ii]mage:') or
				mw.ustring.match(valueArg, '^קובץ:') or
				mw.ustring.match(valueArg, '^תמונה:') then
					valueArg = '[[' .. valueArg .. imgSuffix
				else
					valueArg = '[[File:' .. valueArg .. imgSuffix
				end
			end
			return valueArg
		end
	end
	if args.wikidataArg and args.args.entityId~=nil then 
		args.args.usingWikidata = true
		return propertyLink.getImageLink(args.wikidataArg, args.width, nil, nil,nil, args.args.entityId)
	end
	return ''
	
end

--[[
Split category links from value, return tuple of whether data exists and maitainance cats in case no data exists
]]
function splitMaintainceCategory(value)
	local maintainceCats = nil
	local hasData =  #(mw.ustring.gsub(value, '%[%[קטגוריה:.-%]%]', ''))>0
	if not hasData then
		maintainceCats = value
	end
	return hasData, maintainceCats
end

function getPropertyByOptions( propertyName, entityId, options )
	if propertyName == nil or #propertyName == 0 then
		return nil
	end

	local res = propertyLink.getPropertyByOptions(propertyName, entityId, options)
	if (res==nil) or (#res == 0) then
		return nil
	end
	
	local hasData, maintainceCats = splitMaintainceCategory(res)
	
	if hasData then
		local link = mw.title.makeTitle( 0, entityId, propertyName, 'wikidata' ):fullUrl('uselang=he')
		res = res .. mw.ustring.format(' [[File:Blue pencil RTL.svg|15px|link=%s|עריכת הנתון בוויקינתונים]]', link)
	end
	return res
end

--[[
Filters statements to statements with existing links only
]]
function filterExists( propertyVals )
	local tempVals = {}
    for i, property in ipairs(propertyVals) do
    	local propValue = property.mainsnak and property.mainsnak.datavalue
    	if propValue and propValue.value then
	    	local linkTarget = mw.wikibase.sitelink( propValue.value['id'] )
			if linkTarget then
				table.insert(tempVals, property)
			end
		end
	end
	return tempVals
end

--[[
This function fills missing parameter using wikidata
]]
function fillMissingParamFromWikidata(missingParam, templateParams, templateArg, entityId, frame)
	local inWikidata = false
	local hasData=false
	local maintainceCats = nil
	local includeWikidataRef = frame and frame:getParent()
	if entityId == nil then return inWikidata, maintainceCats end -- early terminate
	includeWikidataRef = includeWikidataRef and includeWikidataRef.args and includeWikidataRef.args['ויקינתונים-מקורות'] == 'כן'
	
	local wikidataOptions = {
		['entity-gender-aware'] =  templateParams[missingParam..'-ויקינתונים-מגדר'] == 'כן',
		['source'] = includeWikidataRef
	}
	if templateParams[missingParam..'-ויקינתונים-סינון'] == 'קיים' then
		wikidataOptions['filter'] = filterExists
	elseif templateParams[missingParam..'-ויקינתונים-סינון'] and mw.ustring.match(templateParams[missingParam..'-ויקינתונים-סינון'], 'filter[a-zA-Z]+') then
		local moduleTitle = mw.ustring.match( frame:getParent():getTitle(), 'תבנית:(.+)' )
		moduleTitle = mw.ustring.format('יחידה:%s', moduleTitle)
		local filterFunc = mw.ustring.match(templateParams[missingParam..'-ויקינתונים-סינון'],'filter[a-zA-Z]+')
		wikidataOptions['filter'] = require(moduleTitle)[filterFunc]
	end
	
	if templateParams[missingParam..'-ויקינתונים-פרטים']~=nil then
		wikidataOptions['qualifiers'] = {}
		wikidataOptions['qualifiers-sep'] = templateParams[missingParam..'-ויקינתונים-פרטים-הפרדה'] or nil
		for v in string.gmatch(templateParams[missingParam..'-ויקינתונים-פרטים'], "[^,%s]+") do
    		table.insert(wikidataOptions['qualifiers'], v)
		end
	end
	if templateParams[missingParam..'-ויקינתונים-תמונה-גודל']~=nil then
		wikidataOptions['img-width'] = templateParams[missingParam..'-ויקינתונים-תמונה-גודל']
	end
	if templateParams[missingParam..'-ויקינתונים'] then
		if templateParams[missingParam..'-ויקינתונים-יחידה'] then
			templateArg.data = require('Module:Convert').convert(mw.getCurrentFrame():newChild{ args = {
				['input'] = templateParams[missingParam..'-ויקינתונים'],
				[2] = templateParams[missingParam..'-ויקינתונים-יחידה'],
				['disp'] = 'out',
				['qid'] = entityId,
				['abbr']='off'
			} }:newChild{})
		else
			templateArg.data = getPropertyByOptions(templateParams[missingParam..'-ויקינתונים'], entityId,  wikidataOptions) or nil
		end
		inWikidata = templateArg.data and #(templateArg.data)>0
	elseif templateParams[missingParam..'-ויקינתונים-מרובה'] then
		wikidataOptions['allowMulti'] = true
		wikidataOptions['seperator'] = templateParams[missingParam..'-ויקינתונים-מרובה-הפרדה']
		paramsData = {}
		-- split multiple params to include all of them (e.g: "P1,P2")
		for paramToFetch in string.gmatch(templateParams[missingParam..'-ויקינתונים-מרובה'], '([^,]+)') do
			-- split optional params to include ONLY the first one of them (e.g: "P1/P2")
			for optionalParam in string.gmatch(paramToFetch, '([^/]+)') do
				if (string.sub(optionalParam, 1, 1) == 'P' or string.sub(optionalParam, 1, 1) == 'Q') then
					if getPropertyByOptions(optionalParam, entityId,  wikidataOptions) then
						table.insert(paramsData, getPropertyByOptions(optionalParam, entityId,  wikidataOptions) or nil)
						-- found one of the optionals - stop the loop
						break
					end
				else
					-- one of the optionals is static data - take it and stop the loop
					table.insert(paramsData, optionalParam)
					break
				end
			end
		end
		templateArg.data = table.concat(paramsData, wikidataOptions['seperator'])
		inWikidata = templateArg.data and #(templateArg.data)>0
	elseif templateParams[missingParam..'-ויקינתונים-פשוט'] then
		-- use data should be taken from wikidata and link must not be added
		local wikidataParamValue = propertyLink.getLabel(templateParams[missingParam..'-ויקינתונים-פשוט'], entityId)
		if wikidataParamValue and #wikidataParamValue>0 then
			templateArg.data = frame:preprocess(mw.ustring.gsub(templateArg.data, '\{\{\{('..missingParam..')\}\}\}', wikidataParamValue))
			inWikidata = true
		end
	-- special cases
	elseif missingParam == 'קואורדינטות' then
		
		templateArg.data = propertyLink.getPropertyByOptions('P625', entityId, {['coord-display'] = templateParams['קואורדינטות-תצוגה'] or 'title,inline' })
		inWikidata = templateArg.data and #(templateArg.data)>0
	elseif  missingParam == 'מפה' and templateParams['מפה-זום'] then
		inWikidata = (#mw.wikibase.getBestStatements(entityId, 'P625'))>0
		if inWikidata then
			local defaultZoom = templateParams['מפה-זום']
			templateArg.data = frame:expandTemplate{ title = 'מפה דינמית', args = { 
				['יישור'] = 'center', 
				['זום ברירת מחדל'] = defaultZoom,
				['פריטים'] = entityId
			} }
		end
	end
	if inWikidata then
		hasData, maintainceCats = splitMaintainceCategory(templateArg.data)
		if not hasData then
			inWikidata = false
			maintainceCats = maintainceCats
		end
	end

	return inWikidata, maintainceCats
end


--[[
This function fills missing parameter using wikidata
]]
function crossValidateWikidata(missingParam, templateParams, templateArg, frame, entityId)
	local matching = nil
	local propertyName

	if entityId == nil or missingParam==nil then
		return nil
	end
	if templateParams[missingParam..'-ויקינתונים'] then
		propertyName = templateParams[missingParam..'-ויקינתונים']
		matching = WikidataCrossValidation.crossValidate(templateArg, propertyName)
	elseif templateParams[missingParam..'-ויקינתונים-פשוט'] then
		propertyName = templateParams[missingParam..'-ויקינתונים-פשוט']
		matching = WikidataCrossValidation.crossValidate(templateArg, propertyName)
	elseif templateParams[missingParam..'-ויקינתונים-מרובה'] then
		local genderAware = templateParams[missingParam..'-ויקינתונים-מגדר'] == 'כן'
		propertyName =  templateParams[missingParam..'-ויקינתונים-מרובה']
		matching = WikidataCrossValidation.crossValidate(templateArg, propertyName)
	end
	
	if matching then
		return WikidataCrossValidation.maintainceCategory(matching, propertyName)
	end
end

--[[
If template doesn't specify title parameter, the default is name (fallback by title) + origin name (fallback by wikidata)
]]
function standardTitle(templateArgs, isSubTemplate, entityId)
	local name = templateArgs['שם']
	if name=='-' then return name end -- 
	if isSubTemplate then return name or '' end
	
	if not name or #name==0 then --fallback to title
		name = mw.title.getCurrentTitle().text
    	name = mw.ustring.gsub(name, " *[(].*[)]","")
	end
	
	local originName = templateArgs['שם בשפת המקור']
	if originName == '-' then 
		originName = ''
	else
		-- use wikidata as fallback
		if (not originName or #originName==0) and entityId~=nil then 
			local propertyVals = mw.wikibase.getBestStatements(entityId, 'P1705')
			if #propertyVals == 0 then propertyVals = mw.wikibase.getBestStatements(entityId, 'P1476') end
			if #propertyVals == 0 then propertyVals = mw.wikibase.getBestStatements(entityId, 'P1559') end
			if #propertyVals > 0 then
				local propValue = propertyVals[1].mainsnak and propertyVals[1].mainsnak.datavalue
				if  propValue and propValue.value and propValue.value.text and propValue.value.text~=name then
					originName = mw.ustring.format('<span lang="%s" title="%s">%s</span>', propValue.value.language, 
    											     mw.language.fetchLanguageName( propValue.value.language , 'he'), propValue.value.text)
    			end
			end
			
		end
		
		if originName and #originName and originName~=name then
			name = name..'<br>'..originName
		end
	end
	return name
end

function Infobox:parseArgs(frame)
	local DEFAULT_IMAGE_PROPERTY = 'P18'
	local templateParams =  frame.args
	local templateArgs = frame:getParent().args
	local args={}
	local templateStructure = {}
	args.subtemplate = frame.args['תת-תבנית']
	args.entityId = templateArgs['qid'] or templateParams['qid'] or mw.wikibase.getEntityIdForCurrentPage()
	-- disable wikidata fetching
	if args.entityId == '' or args.entityId == '-' then args.entityId = nil	end
	args.title = frame.args['כותרת תבנית'] or standardTitle(templateArgs, args.subtemplate, args.entityId)
	if args.title=='-' then args.subtemplate = true	end
	args.titlestyle = templateParams['כותרת תבנית-עיצוב']
	args.titleclass = templateParams['כותרת תבנית-מחלקה']
	args.subtitle = templateParams['תת כותרת תבנית']
	args.subtitlestyle = templateParams['תת כותרת תבנית-עיצוב']
	args.subtitleclass = templateParams['תת כותרת תבנית-מחלקה']
	args.rightImage = getValueOrWikidataImage{
		valueArg=templateParams['תמונה ימין'],
		wikidataArg=templateParams['תמונה ימין-ויקינתונים'], 
		width='100x80', 
		args=args
	}
	args.rightImageDesc = templateParams['כיתוב ימין']
	args.leftImage = getValueOrWikidataImage{
		valueArg=templateParams['תמונה שמאל'],
		wikidataArg=templateParams['תמונה שמאל-ויקינתונים'], 
		width='100x80', 
		args=args
	}
	args.leftImageDesc = templateParams['כיתוב שמאל']
	args.imageDesc = templateParams['כיתוב']
	args.image = getValueOrWikidataImage{
		valueArg=templateParams['תמונה'],
		wikidataArg=templateParams['תמונה-ויקינתונים'] or 'P18',
		width=templateParams['תמונה-גודל'] or '220',
		imgDesc=args.imageDesc,
		args=args
	}
	args.headerclass = templateParams['כותרת-מחלקה']
	args.headerstyle = templateParams['כותרת-עיצוב']
    args.rowsstyle = templateParams['שורה-עיצוב']
    args.labelstyle = templateParams['תווית-עיצוב']
    args.datastyle = templateParams['מידע-עיצוב']
	args.tablestyle = templateArgs['טבלה-עיצוב'] or templateParams['טבלה-עיצוב']
	args.tableclass = templateArgs['טבלה-מחלקה'] or templateParams['טבלה-מחלקה']
	local pageNs = mw.title.getCurrentTitle().namespace
	local isSelfUse = (pageNs==10)
	self.autoDocumentation = templateParams['תיעוד-אוטומטי']

	local labelPrefix = 'תווית'
	local dataPrefix = 'מידע'
	local subheader = 'כותרת'
	local labelDataPrefix = 'תווית-מידע'
	local rowStylePrefix = 'עיצוב-שורה'
	local rowStyleClassPrefix = 'מחלקה-שורה'
	local styleSuffix = '-עיצוב'
	local explicitWikidata = '-ויקינתונים-מפורש'
	local k=0
	local processedParams = {['0']=1} -- param0 may be used by Lua, not be template
	local wikidataCats = {}
	for k,v in pairs(templateParams) do
		local i= string.match(k, '.-([0-9]+)$')
		if i and not (processedParams[i]) then
			indic = tonumber(i)
			processedParams[i]=1
			
			local subHeaderName = templateParams[subheader..i]
			if subHeaderName and #subHeaderName>0  then --subheader type
				table.insert(templateStructure, {header=1,data=subHeaderName,rowstyle=templateParams[rowStylePrefix..i], rowclass=templateParams[rowStyleClassPrefix..i], headerstyle=templateParams[subheader..i..styleSuffix], indic=indic})
			else
				local labelName = templateParams[labelPrefix..i]
				local dataTemplate = templateParams[dataPrefix..i]
				if dataTemplate then
					-- if parameter contains only category with no value, replace with with nil and add teh value to maintaince category
					local hasData, maintainceCats = splitMaintainceCategory(dataTemplate)
					if maintainceCats and not hasData then
						table.insert(wikidataCats, maintainceCats)
						dataTemplate=nil
					end
				end
				if labelName and dataTemplate then
					--label: data type
					table.insert(templateStructure, {label=labelName, data=dataTemplate, rowstyle=templateParams[rowStylePrefix..i], rowclass=templateParams[rowStyleClassPrefix..i], datastyle=templateParams[dataPrefix..i..styleSuffix], 
						labelstyle=templateParams[labelPrefix..i..styleSuffix], indic=indic})
				elseif labelName and not dataTemplate then
					--skip it. no only label [use subheader]
				elseif not labelName and dataTemplate then
					--only data type
					table.insert(templateStructure, {data=dataTemplate, rowstyle=templateParams[rowStylePrefix..i], rowclass=templateParams[rowStyleClassPrefix..i], datastyle=templateParams[dataPrefix..i..styleSuffix], indic=indic})
				else
					 local label_data_names = templateParams[labelDataPrefix..i]
					 if label_data_names then
					 	labelName = label_data_names
					 	label_data_names = mw.text.trim(label_data_names, '%[%]')
						local hasContent = templateArgs[label_data_names] and #templateArgs[label_data_names]>0
						-- + and use explicit wikidata replace the content with such if available from wikidata
						local isExplicitWikidataParam = templateParams[label_data_names..explicitWikidata]
						local isExplicitWikidataEnabled = false 
						if isExplicitWikidataParam then
							isExplicitWikidataEnabled = templateArgs[label_data_names]~=nil and mw.ustring.match(templateArgs[label_data_names], '^ *+$')
						end
						local skipContent = false
					 	if hasContent and not isExplicitWikidataEnabled then
					 		dataTemplate = templateArgs[label_data_names]
				 		else
							if isExplicitWikidataParam and not isExplicitWikidataEnabled then
								skipContent = true
							end
				 			dataTemplate = '{{{' ..label_data_names.. '}}}'
				 			
					 	end
					 	if not skipContent then
					 		table.insert(templateStructure, {label=labelName, data=dataTemplate, rowstyle=templateParams[rowStylePrefix..i], rowclass=templateParams[rowStyleClassPrefix..i], datastyle=templateParams[dataPrefix..i..styleSuffix], 
					 									 labelstyle=templateParams[labelPrefix..i..styleSuffix], indic=indic})
						end					 									 
				 	end
				end
			end
		end
	end
	table.sort(templateStructure, function (x, y) return x.indic<y.indic end)
	
	-- use wikidata / remove unused parameters
	if not isSelfUse then
		local entriesToRemove = {}
		local crossValidatedFields = {}
		
		for k,v in pairs(templateStructure) do
			if v.data then
				-- remove parameters that were explicitly defined to be removed
				local ignoreParam = mw.ustring.match(v.data, '^%-$')
				if ignoreParam then
					table.insert(entriesToRemove, 1, k)
				else
					-- otherwise if the template isn't full - try to use wikidata to fill it
					local m = mw.ustring.match(v.data, '\{\{\{(.-)\}\}\}')
					if m then
						m = mw.uri.decode( m ) -- some templates may add encoding and are preprocessed before
						local inWikidata, maintainceCats = fillMissingParamFromWikidata(m, templateParams, v, args.entityId, frame)
						if maintainceCats then
							table.insert(wikidataCats, maintainceCats)
						end
						
						if inWikidata then
							crossValidatedFields[m] = 1
							args.usingWikidata = true
						else
							-- if data isn't available remove it
							table.insert(entriesToRemove, 1, k)
							-- no need to cross validate it
							crossValidatedFields[m] = 1
						end
				
					end					
				end
			end
		end
		
		for k,v in pairs(templateArgs) do
			if crossValidatedFields[k]==nil and v and #v>0 and pageNs==0 and k~= 'תמונה' then
				local maintainceCats = crossValidateWikidata(k,templateParams, v, frame, args.entityId)
				if maintainceCats and #maintainceCats>0 then
					table.insert(wikidataCats, maintainceCats)
				end
			end
		end
		
		for k,v in pairs(entriesToRemove) do table.remove(templateStructure, v) end

		-- use wikidata in title
		if args.title then
			local m = mw.ustring.match(args.title, '\{\{\{(.-)\|?\}\}\}') 
			if m then
				local inWikidata = false
				if templateParams[m..'-ויקינתונים'] then
					local wikidataParamValue = getPropertyByOptions(templateParams[m..'-ויקינתונים'], args.entityId) or nil
					if wikidataParamValue then
						args.title = wikidataParamValue
					end
				elseif templateParams[m..'-ויקינתונים-פשוט'] then
					-- use data should be taken from wikidata and link must not be added
					local wikidataParamValue = propertyLink.getLabel(templateParams[m..'-ויקינתונים-פשוט'])
					if wikidataParamValue then
						args.title = frame:preprocess(mw.ustring.gsub(args.title, '\{\{\{('..m..')\|?\}\}\}', wikidataParamValue))
					end
				end
			end
		end
	end
	
	self.args = args
	self.templateStructure = templateStructure
	self.wikidataCats = wikidataCats
	self.isSelfUse = isSelfUse
	self.templateParams = templateParams
end

function infobox(frame)
	local infoObj = Infobox:new()
	infoObj:parseArgs(frame)
	return infoObj:render()
end

return 	{
	['מידע']=infobox,
	Infobox=Infobox
}