Modul:Foundationclass/doc

ZIM HilfeWiki - das Wiki
< Modul:Foundationclass
Version vom 10. April 2022, 06:35 Uhr von imported>Oetterer
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)

This is a Template for Class Modules. It implements a class in Lua using Module:Middleclass and provides serveral static and public methods, commonly used in the typical form>page>store process.

Usage[Quelltext bearbeiten]

This is in a way an abstract class. It provides some static and public methods for resuse, and also maintains a store of private properties. If can be used to fast and easily create a typical class module that can handle:

  • creating an appropriate form
  • supplying your respective template with functionalities for
    • object initialization via template parameters, arguments, and datastore (self initialization)
    • general data assesment (basic plausibility tests)
    • data storage (supported are cargo and semantic media wiki)
    • error and warnings management
    • output and rendering
  • creating a template documentation

You can and should adjust the module in this methods:

  • individual attribute adjustment for the semantic forms fields
  • individual plausibility testing
  • individual data initialization
  • individual data store adjustments before stashing

You can access the objects core data store with getCoreData() and its uid with getUid().

How-To[Quelltext bearbeiten]

This is, what you have to do (see Useful templates for content of the corresponding pages):

  1. create your base module Module:Name
  2. create your class module Module:Name/class. For this, copy lua sample code below this list and apply the following changes:
    1. change all occurences of className into your class name
    2. change the highlighted lines and replace 'Name' with the Name of your module
    3. implement the abstract methods:
      1. myAgumentProcessing(coreData)
      2. myDataAdjustments(data)
      3. myPlausibilityTest(args)
      4. myStashAdjustments(stash)
      5. static:mySfDynamicFieldAttribute(fieldname, attribute, value)
    4. for the usual output generation, implement (shells given in sample code)
      1. addInfobox()
      2. addPageBody()
  3. create and fill your configuration Module:Name/config
  4. create your template Template:Name
  5. create your form Form:Name
  6. if applicable, create your category page Category:Name
  7. fill in documentation:
    1. of your base module (place one invoke below the first comment and before the includeonly)
    2. of your class module (new docu for your own public, static and private methods (which you can probably copy from other classes) and one invoke to show the inheritance. Sample code provided in Useful templates
    3. of your class module's configuration (just copy content)
    4. of your template (one invoke below the first comment and before the includeonly)

Useful templates[Quelltext bearbeiten]

base module:
classengine-template-module-page
base module's documentation page:
⧼classengine-template-module-documentation-page⧽
class module:
classengine-template-module-class-page
class module's documentation page:
⧼classengine-template-module-class-documentation-page⧽
class configuration (sample file):
local superglobal = mw.loadData( 'Module:Foundationclass/globalconfig' )

local form = {
	enable = true, -- Do you want to create a form for this class? Note: When you don't want to have a form _page_, but need this to be a part of another form (as a holds-template form), set this to true!
	name = '',	-- The name of the form, i.e. the form will be placed an page [[Form:Formname]]. If you don't need an actual form page, leave this empty (e.g. if this is a prot of another form as holds-template or such).
	teaserText = '',	-- This is the text displayed on the form:name page (before you see the actual form))
	typeCreateLink = 'none',	-- This field lets you choose, what kind of object create link is provided to the user on the form page: is there none, a formlink, or a forminput field? possible values are: 'none' (default), 'forminput', 'formlink'
	createInfotext = '', -- This is the short text that appears right above the input field. Short being the important part. Please limit yourself to a short sentence.
	createInputPlaceholder = '',	-- Placeholder text that is shwon in the form create input field
	createInputQueryString = '',	-- You can use this option to pass information to the form; this information generally takes the form of ''templateName[fieldName]=value''. It should look like a typical URL query string; an example would be "query string=namespace=User&User[Is_employee]=yes".
	createLinkPageName = '',	-- With this, you can have the name of the page created by the form to be set automatically. You can use any of the parameters ''<template-name[field-name]>'' or ''<unique number>''. The latter takes options start=x, unique, random, and a number (length of id string, default 6).
		-- IMPORTANT: If you want to use the one step process with a createLinkPageName, you have to add the output if your class's sfGenerateFormInfoTag() in comments to your form page!!!
			-- this is a workaround for a semantic forms bug. see https://phabricator.wikimedia.org/T123230 for more information
	createLinkQueryString = '',	-- You can use this option to pass information to the form; this information generally takes the form of ''templateName[fieldName]=value''. It should look like a typical URL query string; an example would be "query string=namespace=User&User[Is_employee]=yes".
	createLinkType = 'plain', -- This field lets you choose, what kind of form link is used to link to the form page: is it a plain link or a button (with parameter submission via get or post), possible values are nil, 'plain', 'button', 'post button'
	labelCreate = '',	-- label for create entity
	labelEdit = '',	-- label for edit entity
	headerText = '',	-- this is the text displayed above the form
	notification = '',	-- this notification will be displayed above your form
	sectionList = {},	-- if you want to have hl2 sections of text after the datafields and before the freetext, name them here. Use strings for names of section headlines
	allowsFreeText = false,	-- will the form have a free text field?
	freeTextPreload = nil,	-- when this is set your free text will have a preload=<freeTextPreload> statement. of course only when allowsFreeText is set to true
	buttons = {'save', 'preview', 'changes', 'cancel'},	-- which buttons should appera below the form
	fieldSize = 80,	-- what is the default size= for the form fields
	textareaAttributes = {	-- the defaults for your textarea fields
		cols = 80,
		rows = 4,
		autogrow = true,
		editor = 'wikieditor',	-- other values would be false or 'none'...
	},
	fieldOrder = {
		-- the order in which the form fields appear. NOTE: a parameter not in this list, will not appear in the form!!
		-- YOU HAVE TO FILL THIS TABLE! Put in here all parameters, that are used in the form, even if you have your own sfGenerateForm() implemented using a different table.
		-- Reason: This is also be used in plausibility tests
		'',
	},
}

local global = {
	cargoTable = '',	-- if you use dataStore cargo, name the table here. if you do not name a table, no persistant cargo data will be stored for that class
	category = '',	-- the mediawiki category, the entity is placed into
	delimiter = ',',	-- see to it, that the delimiter is not a character, that will be encoded by mw.text.encode. CargoUtil.store encodes the data for security reasons
	description = '',	-- a short description of the entity. will be displayed on the template documentation page for example
	entityTitle = '',	-- generic title for the entity
	gardeningCategory = superglobal.gardeningCategory,	-- the category, objects with erroneous/inplausible data will be put into
	namespace = '',	-- if you put this entity on a special namespace, name it here. NOTE: You have to be precise. This is case sensitive. But omit the colon.
	smwIsSubobject = false, -- when using datastore smw: is this stored as subobject (and not as normal data)?
	smwUseStorage = true,	-- if you use dataStore smw, set this to true if you actually want persistant smw data to be stored for that class
}

local parameter = {
	-- this is your list of parameters. you put all data here, that you would like to handle
	--	* parameters of your form (and thus your template)
	--		* when you fill td_type, your parameter will be shown on the template documentation page
	--		* when you add the parameter name to form.fieldOrder, it will be added to the form and processed in plausibility tests
	--	* add also data, that you only want to store (omit these from form.fieldOrder and leave the sf table, probably best, to leave td_type unset, too).
	--  * hint: if you need a row in your table as information, add pseudo parameter w/o entry in fieldOrder, w/o sf table, w/o td_type, and w/o cargo/property entries
	name = {
		cardinality = 'single|list',
		cargo_hidden = false, -- takes no value. If set, the field is not listed in either Special:ViewTable or Special:Drilldown, although it is still queriable.
		cargo_size = nil, -- for fields of type "Text", sets the size of this field, i.e. the number of characters; default is 300
		cargo_type = '',
		description = '',
		label = '',
		property_name = '',	-- please use underscores (_) instead of spaces
		property_type = '', -- possible values are: Annotation URI, Boolean, Code, Date, Email, Number, Page (default), Quantity, Telephone Number, Temperature, Text, URL
		severity = 'mandatory|suggested',
		sf = {
			--	note: this list is incomplete. see [[Module:SFfield/config]] for a complete list of supported attributes
			--	note also: mandatory, list, property and values are derived form fields "above" this table
			--  IMPORTANT: If you want this to be a regular form parameter, you have to add this table. even, if you leave it empty.
			--  also: keep in mind that a parameter appears in the form only if you add its name to form.fieldOrder above
			cargo_field = '',
			cargo_table = '',
			class = '',
			default = '',
			default_filename = '',
			existing_values_only = true,
			hidden = true,
			image_preview = true,
			input_type = '',
			mapping_cargo_field = '',
			mapping_cargo_table = '',
			mapping_template = '',
			max_values = 0,
			maxlength = 0,
			placeholder = '',
			restricted = '',	-- e.g.: restricted = superglobal.restrictionRole,
			show_on_select = {}, -- takes either a string (in case of input type checkbox) or a table. table must be of format "selected value" : "field shown"
			size = 0,
			unique = true,
			unique_for_category = true,
			unique_for_namespace = true,
			uploadable = true,
			values_dependent_on = '',
			values_from_category = '',
			values_from_namespace = '',
		},
		td_default = '',
		td_type = '',
		values = {},
	},
}

local template = {
	name = 'nameOfYourTemplate',	-- the name of your template. e.g.: your template can be found on the page [[Template:nameOfYourTemplate]]
	templateDocumentationSeeAlso = {'List', 'of', 'similar', 'or', 'related', 'templates'}	-- used in the see also-section of your template documentation
}

return {
	form = form,
	global = global,
	parameter = parameter,
	template = template,
}
configuration documentation page:
⧼classengine-template-module-config-documentation-page⧽
template:
⧼classengine-template-template-page⧽
template documentation page:
⧼classengine-template-template-documentation-page⧽
form:
⧼classengine-template-form-page⧽
category:
⧼classengine-template-category-page⧽
gardening category:
⧼classengine-template-gardeningcategory-page⧽

private, public, class or instance[Quelltext bearbeiten]

Zugriffsmatrix
- public private
instance
function MyClass:publicMethod()
MyClass.publicProperty
local _privateMethod = function (self, var)
_private[self]._privateProperty
class
function MyClass.static:staticMethod()
MyClass.static.staticProperty
-- accessing
MyClass.staticProperty
-- being "outside":
MyClass:staticMethod()
-- being inside a static method
self:staticMethod()
-- being inside a public method
self.class:staticMethod()
local _privateMethod = function (self, var)
local _privateProperty

private[Quelltext bearbeiten]

property[Quelltext bearbeiten]

you can declare a property private in one of two ways:

  1. anywhere, preferably before your constructor, declare a local var to have a private propery, this is not recommended, but it allows you to declare a private property, that can be used by your static methods. thus being somewhat private static
  2. for your instances, you can use the table _private[self] as a private store. it is available after your construrctor has been called (since this is an instance attribute)
method[Quelltext bearbeiten]

a private method is declared thus: local _privateMethod = function(self, var). If you want to use the method in an public/static/other private method before it is declared (aka: the calling method is on a lower line number than your private method's declaration), decare it ahead and define it later:

local _privateImportantMethod
..
privateImportantMethod = function(self, var)

private class and instance methods are basically the same.

public[Quelltext bearbeiten]

property[Quelltext bearbeiten]

can be dclared via class.property. DONT DO THIS. It is bad style!

method[Quelltext bearbeiten]

Declare them class:publicMethod(var). They are, after all, public

NOTE: public methods can be called by an instance, but also as static method:

function Class:public()
	return 'public: ' .. tostring(self)
end

local me = Class:new()
me.public()	-- returns "public: Instance of class Class"
Class:public()	-- returns "public: class Class"

static[Quelltext bearbeiten]

property[Quelltext bearbeiten]

Declare a static property like this: class.static.myProperty = 'Hello World'. This produces a public property, that can be accessed by the class, childclasses or instances via *.myProperty (replace * with class, object, childclass, ...)

method[Quelltext bearbeiten]

Much the same as static properties, but you should use the colon operator: function Class.static:staticMethod() when definig the method. On accessig this method, you should use the dot-notation: function Class.staticMethod(self)

NOTE: Other than public methods, they can only be called by the class, but not by an instance:

function Class.static:static()
	return 'static: ' .. tostring(self)
end

local me = Class:new()
me.static()	-- returns "error:  attempt to call method 'static' (a nil value)"
Class:static()	-- returns "static: class Class"
Class.static(self)	-- this is not called via colon (:) operator as to preserve the childClass's scope when inheriting from this class

Methods[Quelltext bearbeiten]

MediaWiki:Classengine-content-documentation-methods

private methods[Quelltext bearbeiten]

These private Methods can not be used by child classes!

_amIPlausible(self)[Quelltext bearbeiten]

Returs true or false, whether the object is plausible or not (i.e. has no errors or 1+)

self
object, me
return
boolean, whether the object is plausible or not

_debug(self, level, text)[Quelltext bearbeiten]

Adds output to the internal debug log.

self
object, me
level
int; mandatory
debug level for the message
text
string; mandatory
debug message text
return
void

_plausibilityTest(self, args)[Quelltext bearbeiten]

Checks, if input provided via template is plausible enough, to represent the object (to be stored and displayed). Also fills the list of errors and does some argument preparation.

self
object, me
args
table, mandatory
arguments passed to the template to be checked
return
boolean, whether the object is plausible or not

Properties[Quelltext bearbeiten]

static[Quelltext bearbeiten]

MediaWiki:Classengine-content-documentation-properties

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.

categories
table, holds the objects categories
coreData
table, holds the objects data ofter initializing
dbg
object, my instance of Module:Debug/class for debugging purposes
errors
table, a list of errors that occurred
fullpagename
string, name of currentpage including namespace
initialized
boolean, is this object properly initialized
loadedDataFromDataStore
boolean, did this object get its data from the data store
output
object of type mw.html, holds all output to be rendered()
pagename
string, name of current page (or current page's super page) w/o namespace
uid
string, uinique identifier ('NIL' if unset)
warnings
table, a list of warnings that came up

Configuration Data[Quelltext bearbeiten]

This class holds gets its control data from the child class. Also, there is some global configuration data in Module:Foundationclass/globalconfig, that applies to all classes.

Dependencies[Quelltext bearbeiten]

If you want to use Module:Foundationclass, you also need the following items (and their doc pages!):

also

and of course Extension:Semantic Forms

Also, have a look at the extended functionality of the Class engine.

Interface messages[Quelltext bearbeiten]

To generate the Useful_templates, Foundationclass makes use of the following interface messages:

Next in dev queue[Quelltext bearbeiten]

  1. have foundation class try to detect integer inputs (by td_type or cargo_type) and run a regexp in _plausibilityTest
  2. have foundationclass use mw message system for printouts instead of hardcoded text
  3. a template or page, that #autogenerates all categories, defined in Module:Foundationclass/globalconfig
Cookies helfen uns bei der Bereitstellung des ZIM HilfeWikis. Bei der Nutzung vom ZIM HilfeWiki werden die in der Datenschutzerklärung beschriebenen Cookies gespeichert.