(fixed an error with show on select for input_type checkbox) |
imported>Oetterer K (Schützte „Modul:SFfield/class“: Automatic protection of selected project pages ([Bearbeiten=Nur Administratoren erlauben] (unbeschränkt) [Verschieben=Nur Administratoren erlauben] (unbeschränkt))) |
(kein Unterschied)
|
Version vom 7. Oktober 2022, 16:56 Uhr
This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
This is a Class Module. It implements a class in Lua using Module:Middleclass. This class provides methods for defining and creating Semantic Forms field-tags.
Usage[Quelltext bearbeiten]
local classSFfield = require('Module:SFfield/class')
local field = classSFfield:new('name')
classSFfield:setDefaultSize(80)
field:set('input type', 'tokens')
field:set('list')
field:set('mandatory', true)
field:set('property', 'goes by name')
local output = field:render()
This class provides meththods for creating field tags to use in Semantic Forms. It is fast, easy to use and does some minor plausibility checks:
- it only allows existing attributes to be set
- it only allows existing "input type"s to be set
Concerniny "existing": The module knows all input types from Semantic Forms and Semantic Forms Inputs. All valid entries are defined in Configuration Data
Besides some debugging, the class does not print any error reports or development output. See Module:Debug/class for more information on how to access debug output.
There is are some static properties to default certain values when not set individually:
size
for "tokens", "combobox", "text", ... fieldsautogrow
for "textarea" and "textarea with autocomplete"cols
for "textarea" and "textarea with autocomplete"editor
for "textarea" and "textarea with autocomplete"rows
for "textarea" and "textarea with autocomplete"
They are initialized in the class but can be overwritten by static methods.
Besides simple field-tags there is also a method with which you can have your tags enclosed in the typical tr-th-td structure to easily create a form table. You can also add a tooltip. If mandatory
was set, it also prints a small asterix next to the label.
local node = field:createTr('Name', 'This field holds the full name, the person is known for.')
Constructor[Quelltext bearbeiten]
new(fieldname)[Quelltext bearbeiten]
Creates a new Object for class Name.
- fieldname
- string, mandatory
- holds the name of the field; in SF-terms: this transforms to the parameter name of the referenced template
- return
- object, of class SFfield
Methods[Quelltext bearbeiten]
Public methods[Quelltext bearbeiten]
__tostring()[Quelltext bearbeiten]
Returns a string representation of the field by calling render().
- return
- string, representation of itself
createTr(label, tooltip)[Quelltext bearbeiten]
Uncloses the rendered field in a tr-th-td structure that can directly be used in an html formtable. When mandatory
is set in the field, it adds an asterix after the label. A tooltip can also be provided.
- label
- string, mandatory
- what var is for
- tooltip
- string, optional
- explanatory text that helps the user fill this field
- return
- object of class mw.html, one table row (tr) containing an th with the labal (and tooltip) and a tr with the rendered field.
get(attribute)[Quelltext bearbeiten]
Returns the value for the attribute.
- attribute
- string, mandatory
- the name of the attribute, you wish to get
- return
- vaiable, the value for the attribute
render()[Quelltext bearbeiten]
Renders the object and creates a semantic forms field already htmlentities-encoded (so it can be used directly in the form)
- return
- string, rendered and encoded field-tag
set(attribute, value)[Quelltext bearbeiten]
Sets an attribute for the field. Checks attribute for validity before setting it. In case of attribute input type
checks value for validity, too. When setting simple attributes like list
or mandatory
, omitting value is interpreted as adding the attribute. If you at anytime wish to remove such an attribute, you have to set value to false.
- attribute
- string, mandatory
- the name of the attribute, you wish to set
- value
- (string
static methods[Quelltext bearbeiten]
SFfield:getShowOnSelectIdPrefix()[Quelltext bearbeiten]
Returns the static property used as prefix in the html-id attribute that serves as identifier for the show on select
mechanism. When using the method createTr, you probably have no need for this.
- return
- string, prefix for the value of the id attribute
SFfield:setDefaultSize(val)[Quelltext bearbeiten]
Sets the default size for text-like fields (tokens, combobox, text, ...). The default only applies, if this attribute is not set individually in a textarea field.
- val
- integer, mandatory
- default size in characters for input fields
- return
- boolean, whether setting was successful or not
SFfield:setDefaultTextAreaAutogrow(val)[Quelltext bearbeiten]
Sets the default autogrow-behaviour of textarea-type fields. The default only applies, if this attribute is not set individually in a textarea field.
- val
- boolean, mandatory
- disables or enables default value for autogrow in textarea fields.
- return
- boolean, whether setting was successful or not
SFfield:setDefaultTextAreaCols(val)[Quelltext bearbeiten]
Sets the default for number of columns for textarea-type fields. The default only applies, if this attribute is not set individually in a textarea field.
- val
- integer, mandatory
- default for number of columns for the textarea fields.
- return
- boolean, whether setting was successful or not
SFfield:setDefaultTextAreaEditor(val)[Quelltext bearbeiten]
Sets the default editor of textarea-type fields. The default only applies, if this attribute is not set individually in a textarea field.
- val
- string
SFfield:setDefaultTextAreaRows(val)[Quelltext bearbeiten]
Sets the default for number of rows for textarea-type fields. The default only applies, if this attribute is not set individually in a textarea field.
- val
- integer, mandatory
- default for number of rows for the textarea fields.
- return
- boolean, whether setting was successful or not
SFfield:setShowOnSelectIdPrefix(val)[Quelltext bearbeiten]
Sets the default prefix for the html id-attribute used in the show on select
complex.
- val
- string, mandatory
- the static property will be set to this value
- return
- boolean, whether setting was successful or not
private methods[Quelltext bearbeiten]
_processAttributes(self)[Quelltext bearbeiten]
Converts the private property attributes (which holds all attributes for this field) from an array {attribute = value, ...} table to a sequence {'attriubte=value', ..} table. Also:
- adds the attribute 'input type' if missing to a default, depending on setting of attribute 'list'
- sets defaults (if applicable) for
- size
- autogrow
- cols
- editor
- rows
- does the 'show on select' table-conversion if necessary
- self
- object, me
- var
- type(string
Properties[Quelltext bearbeiten]
static[Quelltext bearbeiten]
- _CFG
- table, holds configuration data found in Module:Name/config
- WARNING: This is a read only table and besides functions pairs() and ipairs() nothing else will work on it, especially not the functions of the table library!
- global, table, global behaviour settings
- validAttributes, table, a sequence of all valid attributes
- validInputTypes, table, a sequence of all valid values for attribute "input type"
- _TT
- table, instance of Module:TableTools
- _defaultListInputType
- string, default value for attribute "input type" if unset. applies if "list" is set
- _defaultSingleInputType
- string, default value for attribute "input type" if unset. applies if "list" is not set
- _defaultSize
- integer, default size for most input types if not set
- _defaultTextAreaAttributes
- table, holds some default attribte values for textarea fields if unset
- _mandatoryMarker
- string, createTr uses this marker to depict mandatory fields
- _showOnSelectIdPrefix
- string, prefix string for html id-attributes for the show on select complex (e.g.: '")
private[Quelltext bearbeiten]
Note: all private properties are stored in table _private[self]. _private is a static array that is indexed by self, so the table _private[self] holds all properties for instance self.
- attributes
- table, holds "my" attributes
- dbg
- object, my instance of Module:Debug/class for debugging purposes
- name
- string, name of this field
Configuration Data[Quelltext bearbeiten]
This class holds it control data in Module:SFfield/config.
local class = require('Module:Middleclass').class
local classSFfield = class('SFfield')
local classDebug = require('Module:Debug/class')
-- ****************************************************************
-- * properties *
-- ****************************************************************
-- **************** initialization of table for private properties
local _private = setmetatable({}, {__mode = "k"}) -- weak table storing all private attributes
-- **************** declaration of private static properties
-- local _PROPERTY = require( 'Module:' )
local _CFG = mw.loadData( 'Module:SFfield/config' )
local _TT = require( 'Module:TableTools' )
local _defaultListInputType = 'tokens'
local _defaultSingleInputType = 'combobox'
local _defaultSize = 40
local _defaultTextAreaAttributes = {
autogrow = true,
cols = 80,
editor = 'wikieditor',
rows = 12
}
local _mandatoryMarker = '<sup>*</sup>'
local _showOnSelectIdPrefix = _CFG.global.showOnSelectIdPrefix
-- ***************************************************************
-- * methods *
-- ***************************************************************
-- **************** declaration of static methods
function classSFfield:initialize(fieldname) -- constructor
local fieldname = fieldname or 'no fieldname specified'
local dbg = classDebug:new('SFfield_field_' .. fieldname)
-- initialize all private properties
_private[self] = {
attributes = {},
dbg = dbg,
name = fieldname,
}
_private[self].dbg:log(11, 'Initializing field "' .. fieldname ..'"')
end -- end of function classSFfield:initialize(fieldname)
function classSFfield.static:getShowOnSelectIdPrefix()
return _showOnSelectIdPrefix
end
function classSFfield.static:setDefaultSize(val)
if val and type(val) == 'number' then
_defaultSize = val
classDebug:log(13, ' classSFfield.static:setDefaultSize(): Setting _defaultSize to ' .. val, tostring(self) .. '.static')
return true
end
return false
end
function classSFfield.static:setDefaultTextAreaAutogrow(val)
if val and type(val) == 'boolean' then
_defaultTextAreaAttributes.autogrow = val
classDebug:log(13, 'classSFfield.static:setDefaultTextAreaAutogrow(): Setting _defaultTextAreaAttributes.autogrow to ' .. val,
tostring(self) .. '.static')
return true
end
return false
end
function classSFfield.static:setDefaultTextAreaCols(val)
if val and type(val) == 'number' then
_defaultTextAreaAttributes.cols = val
classDebug:log(13, 'classSFfield.static:setDefaultTextAreaCols(): Setting _defaultTextAreaAttributes.cols to ' .. val,
tostring(self) .. '.static')
return true
end
return false
end
function classSFfield.static:setDefaultTextAreaEditor(val)
if type(val) == 'boolean' then
if val then
_defaultTextAreaAttributes.editor = 'wikieditor'
classDebug:log(13, 'classSFfield.static:setDefaultTextAreaEditor(): Setting _defaultTextAreaAttributes.editor to wikieditor',
tostring(self) .. '.static')
else
_defaultTextAreaAttributes.editor = nil
classDebug:log(13, 'classSFfield.static:setDefaultTextAreaEditor(): Setting _defaultTextAreaAttributes.editor to NIL',
tostring(self) .. '.static')
end
return true
elseif val and type(val) == 'string' then
_defaultTextAreaAttributes.editor = val
classDebug:log(13, 'classSFfield.static:setDefaultTextAreaEditor(): Setting _defaultTextAreaAttributes.editor to ' .. val,
tostring(self) .. '.static')
return true
else
classDebug:log(13, 'classSFfield.static:setDefaultTextAreaEditor(): doing nothing. parameter type is ' .. type(val),
tostring(self) .. '.static')
end
return false
end
function classSFfield.static:setDefaultTextAreaRows(val)
if val and type(val) == 'number' then
_defaultTextAreaAttributes.rows = val
classDebug:log(13, 'classSFfield.static:setDefaultTextAreaRows(): Setting _defaultTextAreaAttributes.rows to ' .. val,
tostring(self) .. '.static')
return true
end
return false
end
function classSFfield.static:setShowOnSelectIdPrefix(val)
if val and type(val) == 'string' then
_showOnSelectIdPrefix = val
classDebug:log(13, 'classSFfield.static:setShowOnSelectIdPrefix(): Setting _showOnSelectIdPrefix to ' .. val,
tostring(self) .. '.static')
return true
end
return false
end
-- **************** declaration of private methods
local _processAttributes = function (self)
_private[self].dbg:log(11, 'entering _processAttributes() to process attributes and preparing them for printout')
_private[self].dbg:log(13, ' _processAttributes(): attributes array so far looks like: <pre>' .. _TT.printTable(_private[self].attributes) .. '</pre>')
local attributes = {}
if not _private[self].attributes['input type'] and not (_private[self].attributes.hidden or _private[self].attributes['holds template']) then
_private[self].dbg:log(13, ' _processAttributes(): no input type set. defaulting dependant on the setting of attribute "list"')
if _private[self].attributes.list then
_private[self].attributes['input type'] = _defaultListInputType
else
_private[self].attributes['input type'] = _defaultSingleInputType
end
end
if _private[self].attributes['input type'] and (_private[self].attributes['input type'] == 'textarea' or _private[self].attributes['input type'] == 'textarea with autocomplete') then
_private[self].dbg:log(13, ' _processAttributes(): textarea input type detected. setting defaults when unset')
if _private[self].attributes.autogrow == nil then
_private[self].attributes.autogrow = _defaultTextAreaAttributes.autogrow
end
if _private[self].attributes.cols == nil then
_private[self].attributes.cols = _defaultTextAreaAttributes.cols
end
if _private[self].attributes.editor == nil and _defaultTextAreaAttributes.editor then
_private[self].attributes.editor = _defaultTextAreaAttributes.editor
end
if _private[self].attributes.rows == nil then
_private[self].attributes.rows = _defaultTextAreaAttributes.rows
end
elseif _private[self].attributes.size == nil and _private[self].attributes['input type']
and not _TT.inTable({'radiobutton', 'hidden', 'checkbox', 'checkboxes'}, mw.ustring.lower(_private[self].attributes['input type'])) then
_private[self].attributes.size = _defaultSize
end
for attr, val in pairs(_private[self].attributes) do
if not _private[self].attributes['input type'] or _TT.inTable(_CFG.generalAttributes, mw.ustring.lower(attr)) or
_TT.inTable(_CFG.validAttributesPerType[_private[self].attributes['input type']], mw.ustring.lower(attr)) then
local line
if type(val) == 'boolean' then
if val then
line = attr
end
elseif type(val) == 'table' then
_private[self].dbg:log(13, ' _processAttributes(): value of type "table" detected')
if attr == 'show on select' then
_private[self].dbg:log(13, ' _processAttributes(): belonging to attribute "show on select". processing table')
line = attr .. '='
for v, eid in pairs(val) do
if type(eid) == 'table' then
for _, eid_v in pairs(eid) do
line = line .. v .. '=>' .. _showOnSelectIdPrefix .. eid_v .. ';'
end
else
line = line .. v .. '=>' .. _showOnSelectIdPrefix .. eid .. ';'
end
end
else
_private[self].dbg:log(13, ' _processAttributes(): not belonging to attribute "show on select". processing table normally')
local delimiter = _private[self].attributes.delimiter or _CFG.global.defaultDelimiter or ''
-- unfortunately FoundationsClass tables get represented as arrays, albeit with integers ranging from 1 - n as keys. H2IK-Y! workaround:
local tmpvals = {}
for _, v in pairs(val) do
table.insert(tmpvals, v)
end
line = attr .. '=' .. table.concat(tmpvals, delimiter) -- '1,2,3,' .. #val .. '-<pre>' .. require('Module:TableTools').printTable(val) .. '</pre>' ..table.maxn(val) --table.concat(val, '-')
end
else
if attr == 'show on select' then
line = attr .. '=' .. _showOnSelectIdPrefix .. val
else
line = attr .. '=' .. val
end
end
if line then
_private[self].dbg:log(13, ' _processAttributes(): adding "' .. line .. '" to table of attributes')
end
table.insert(attributes, line)
else
_private[self].dbg:log(13, ' _processAttributes(): ignoring attribute ' .. attr .. '; reason is: ' ..
(_private[self].attributes['input type'] and 'not found in tables _CFG.generalAttributes and _CFG.validAttributesPerType["' .. _private[self].attributes['input type'] .. '"]' or 'no input type set')
)
end
end
return attributes
end
-- **************** declaration of public methods
function classSFfield:__tostring()
_private[self].dbg:log(11, 'entering classSFfield:__tostring() to render field output')
return self:render()
end
function classSFfield:createTr(label, tooltip)
_private[self].dbg:log(11, 'entering classSFfield:createTr() to create a table row around self:render()')
_private[self].dbg:log(12, ' classSFfield:createTr() has label "' .. (label and label or 'NOT PROVIDED') .. '"')
_private[self].dbg:log(12, ' classSFfield:createTr() has tooltip "' .. (tooltip and tooltip or 'NONE') .. '"')
local frame = mw.getCurrentFrame()
tr = mw.html.create('tr')
tr:attr( 'id', _showOnSelectIdPrefix .. mw.uri.encode(_private[self].name, 'WIKI') )
:tag((_private[self].attributes.mandatory and 'th' or 'td'))
:wikitext((label or 'LABEL_' .. fieldname) ..
(_private[self].attributes.mandatory and _mandatoryMarker or '') ..
(tooltip and frame:callParserFunction(_CFG.global.tooltipParserFunction, tooltip) or ''))
:done()
:newline()
:tag('td')
:wikitext(self:render())
:done()
:newline()
:done()
return tr
end
function classSFfield:get(attribute)
return _private[self].attributes[attribute]
end
function classSFfield:render()
_private[self].dbg:log(11, 'entering classSFfield:render() to render field output')
local str = '{{{field|' .. _private[self].name .. '|'
.. table.concat(_processAttributes(self), '|') .. '}}}'
_private[self].dbg:log(11, ' classSFfield:render() renders <code>' .. mw.text.nowiki(str) .. '</code>')
return str
end
function classSFfield:set(attribute, value)
local attribute = (attribute and mw.ustring.lower(attribute) or 'NOT PROVIDED!')
_private[self].dbg:log(11, 'entering classSFfield:set() to set attribute: ' .. attribute)
local value = value
if value == nil then
value = true
end
if _TT.inTable(_CFG.validAttributes, attribute) then
-- we have a valid attribute. do some plausibility check
if attribute == 'input type' then
value = mw.ustring.lower(value)
if not _TT.inTable(_CFG.validInputTypes, value) then
_private[self].dbg:log(11, ' classSFfield:set() trying to set "intput type" to invalid value: ' .. value and mw.ustring.lower(value) or 'NIL')
return false
end
end
_private[self].attributes[attribute] = value
if type(value) == 'number' or type(value) == 'string' then
_private[self].dbg:log(12, ' classSFfield:set() setting attribute: "' .. attribute .. '" to value ' .. value)
else
_private[self].dbg:log(12, ' classSFfield:set() setting attribute: "' .. attribute .. '" to a value of type ' .. type(value))
end
return true
else
_private[self].dbg:log(11, ' classSFfield:set() called with invalid attribute: ' .. attribute)
return false
end
end
return classSFfield