ניתן ליצור תיעוד על היחידה הזאת בדף יחידה:תבנית מידע/תיעוד
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') :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.rightImageDesc~=nil and #(self.args.rightImageDesc)>0 then self.args.rightImage = self.args.rightImage..'<div>' .. self.args.rightImageDesc .. '</div>' end if 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%') :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 local entityId = mw.wikibase.getEntityIdForCurrentPage() wbEdit = '[[File:Wikidata-logo S.svg|22px|link=d:'..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.header) 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) :css('text-align', 'right') :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 = 'תבנית ריקה מתוכן. יש להזין פרמטרים בערך או בוויקינתונים. ' .. 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'):css('width', '18em'):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 self:renderImages() 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(valueArg, wikidataArg, width, imgDesc) 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 = '|220px' if imgDesc~=nil and #imgDesc>0 then imgSuffix = imgSuffix .. '|' .. 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 wikidataArg then return propertyLink.getImageLink(wikidataArg, width) end return '' end 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 getProperty( propertyName, allowMulti, allowNA, entityId, multiSeperator, optionalQualifier, genderAware ) local res = propertyLink.getProperty(propertyName, allowMulti, allowNA, entityId, multiSeperator, optionalQualifier, genderAware) if res then local missingTranslation = mw.ustring.find(res, '%[%[קטגוריה:ויקינתונים:ערכים_חסרי_תווית_בעברית%]%]') local link = 'd:'..mw.wikibase.getEntityIdForCurrentPage().. '#'..propertyName if not missingTranslation then res = res .. mw.ustring.format(' [[File:Blue pencil RTL.svg|15px|link=%s|עריכת הנתון בוויקינתונים]]', link) --else --res = res .. mw.ustring.format('[[%s|חסר תרגום]] [[File:Red pencil RTL.svg|15px|link=%s|חסר תרגום בוויקינתונים]]', link, link) end end return res end --[[ This function fills missing parameter using wikidata ]] function fillMissingParamFromWikidata(missingParam, templateParams, templateArg, frame) local inWikidata = false local hasData=false local maintainceCats = nil local propertyName = nil if templateParams[missingParam..'-ויקינתונים'] then templateArg.data = getProperty(templateParams[missingParam..'-ויקינתונים'], false, false, nil, nil, templateParams[missingParam..'-ויקינתונים-פרטים']) or nil inWikidata = templateArg.data and #(templateArg.data)>0 elseif templateParams[missingParam..'-ויקינתונים-מרובה'] then local genderAware = templateParams[missingParam..'-ויקינתונים-מגדר'] == 'כן' templateArg.data = getProperty(templateParams[missingParam..'-ויקינתונים-מרובה'], true, false, nil, templateParams[missingParam..'-ויקינתונים-מרובה-הפרדה'], templateParams[missingParam..'-ויקינתונים-פרטים'], genderAware) or nil 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..'-ויקינתונים-פשוט']) if wikidataParamValue and #wikidataParamValue>0 then templateArg.data = frame:preprocess(mw.ustring.gsub(templateArg.data, '\{\{\{('..missingParam..')\}\}\}', wikidataParamValue)) inWikidata = true end elseif missingParam == 'קואורדינטות' then templateArg.data = frame:expandTemplate{ title = 'קואורדינטות מוויקינתונים', args = { display = 'title,inline' } } inWikidata = templateArg.data and #(templateArg.data)>0 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) local matching = nil local propertyName if missingParam==nil then return nil end if templateParams[missingParam..'-ויקינתונים'] then propertyName = templateParams[missingParam..'-ויקינתונים'] matching = WikidataCrossValidation.crossValidate(templateArg.data, propertyName) elseif templateParams[missingParam..'-ויקינתונים-מרובה'] then local genderAware = templateParams[missingParam..'-ויקינתונים-מגדר'] == 'כן' propertyName = templateParams[missingParam..'-ויקינתונים-מרובה'] matching = WikidataCrossValidation.crossValidate(templateArg.data, propertyName) end if matching then return WikidataCrossValidation.maintainceCategory(matching, propertyName) end end function Infobox:parseArgs(frame) local DEFAULT_IMAGE_PROPERTY = 'P18' local templateParams = frame.args local templateArgs = frame:getParent().args local args={} local templateStructure = {} args.title = frame.args['כותרת תבנית'] args.titlestyle = frame.args['כותרת תבנית-עיצוב'] args.titleclass = frame.args['כותרת תבנית-מחלקה'] args.subtitle = frame.args['תת כותרת תבנית'] args.subtitlestyle = frame.args['תת כותרת תבנית-עיצוב'] args.subtitleclass = frame.args['תת כותרת תבנית-מחלקה'] args.rightImage = getValueOrWikidataImage(frame.args['תמונה ימין'], frame.args['תמונה ימין-ויקינתונים'], '100') args.rightImageDesc = frame.args['כיתוב ימין'] args.leftImage = getValueOrWikidataImage(frame.args['תמונה שמאל'], frame.args['תמונה שמאל-ויקינתונים'], '100') args.leftImageDesc = frame.args['כיתוב שמאל'] args.imageDesc = frame.args['כיתוב'] args.image = getValueOrWikidataImage(frame.args['תמונה'], frame.args['תמונה-ויקינתונים'] or 'P18', '250', args.imageDesc) args.headerclass = frame.args['כותרת-מחלקה'] args.headerstyle = frame.args['כותרת-עיצוב'] args.rowsstyle = frame.args['שורה-עיצוב'] args.labelstyle = frame.args['תווית-עיצוב'] args.datastyle = frame.args['מידע-עיצוב'] args.tablestyle = frame.args['טבלה-עיצוב'] args.tableclass = frame.args['טבלה-מחלקה'] args.subtemplate = frame.args['תת-תבנית'] local isSelfUse = (mw.title.getCurrentTitle().namespace==10) self.autoDocumentation = frame.args['תיעוד-אוטומטי'] local labelPrefix = 'תווית' local dataPrefix = 'מידע' local subheader = 'כותרת' local labelDataPrefix = 'תווית-מידע' local rowStylePrefix = 'עיצוב-שורה' local rowStyleClassPrefix = 'מחלקה-שורה' local styleSuffix = '-עיצוב' 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=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, '%[%]') if templateArgs[label_data_names] and #templateArgs[label_data_names]>0 then dataTemplate = templateArgs[label_data_names] else dataTemplate = '{{{' ..label_data_names.. '}}}' end 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 table.sort(templateStructure, function (x, y) return x.indic<y.indic end) -- use wikidata / remove unused parameters if not isSelfUse then local entriesToRemove = {} 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, frame) if maintainceCats then table.insert(wikidataCats, maintainceCats) end -- if data isn't available remove it if inWikidata then args.usingWikidata = true else table.insert(entriesToRemove, 1, k) end else local maintainceCats = crossValidateWikidata(v.label,templateParams, v, frame) if maintainceCats and #maintainceCats>0 then table.insert(wikidataCats, maintainceCats) end end 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 = getProperty(templateParams[m..'-ויקינתונים']) 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 if args.title=='-' then args.subtemplate = true 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 }