ACF mvc.lua reference: Difference between revisions
(explain the pathologicial inheritance model) |
m (Reverted edits by RuthHughes (talk) to last revision by Ttrask) |
||
(16 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
= | == mvc.lua function reference == | ||
This lua module provides the basics for creating an mvc application. It is patterned | |||
loosely after the Ruby on Rails pattern - but much more simplistic. | |||
The general pattern is to use the mvc '''new''' function to create a set of tables, | |||
and then use '''new'' within those tables to create sub "objects". By using | |||
metatable .__index methods, function references flow up through the parent tables. | |||
=== new( self, modname ) === | |||
Returns 3 values: an ''mvc'' table and 2 booleans ( true or false if the ''modname''-controller and ''modname''-model.lua were loaded) | |||
The ''mvc'' table contains: | |||
{| | |||
! table !! used for !! comments !! .__index points to | |||
|- | |||
|conf | |||
|configuration items | |||
|only created if a ''conf'' table does not exist in a parent | |||
| n/a | |||
|- | |||
|clientdata | |||
|data sent from the client | |||
|only created if a ''clientdata'' table does not exist in a parent | |||
| n/a | |||
|- | |||
|worker | |||
|the "controller" methods | |||
|if '''modname''' is given, then '''''modname'''-controller.lua'' module is loaded into this table. Otherwise, an empty table is returned. | |||
|'''self''' (parent mvc object) | |||
|- | |||
|worker.mvc | |||
|special methods run by the mvc dispatch function | |||
|If the '''modname'''-controller.lua module does not initalize a .mvc table, an empty one is created | |||
|'''self.mvc''' (parent mvc object's mvc table) | |||
|- | |||
| | |model | ||
|the "model" methods | |||
|if '''modname''' is given, then '''''modname'''-model.lua'' module is loaded into this table. Otherwise, an empty table is returned. | |||
|'''worker''' (this mvc object's worker table) | |||
|} | |} | ||
The returned table has a .__index method that points to '''worker''', so this table can | |||
inherit values from the parent table. | |||
If the '''''modname'''-controller.lua'' contains a .mvc.on_load function, the function is run before ''new'' returns. | |||
The | The .__index metamethods mean that this code will set up inheritance as shown in the diagram: | ||
require("mvc") | require("mvc") | ||
MVC=mvc:new() | MVC=mvc:new() | ||
APP=MVC:new() | APP=MVC:new() | ||
Line 53: | Line 56: | ||
subcontroller=controller:new() | subcontroller=controller:new() | ||
If you try to run '''subcontroller.model.somefunction()''', and it does not exist, the inheritance will look for somefunction() in ... | |||
# subcontroller.worker | # subcontroller.worker | ||
Line 67: | Line 69: | ||
This allows, for instance, the application to set a default method that is available to all child controllers. The reason the model looks to its parent worker table first is that controller methods are usually in the worker table, and models do not normally inherit from each other. | This allows, for instance, the application to set a default method that is available to all child controllers. The reason the model looks to its parent worker table first is that controller methods are usually in the worker table, and models do not normally inherit from each other. | ||
The calling code should be sure to call the ''destroy'' function when done with this object. | |||
=== destroy ( self ) === | |||
Calls the ''mvc.on_unload'' function, if it exists, to close any resources opened by the object. | |||
=== dispatch ( self, prefix, controller, action, clientdata ) === | |||
The gateway for executing controller actions in a protected xpcall. | |||
# If no controller specified, use default prefix/controller | |||
# Creates a '''self:new ( prefix .. controller)''' mvc object | |||
# If no action specified, use controller default_action | |||
'' | # runs any existing ''worker.mvc.pre_exec'' function | ||
# runs the ''worker.'''action''''' | |||
# runs any existing ''worker.mvc.post_exec'' function | |||
# gets the view function from ''view_resolver'' | |||
# executes the view with the results of the ''worker.'''action''''' | |||
# and calls ''destroy'' to destroy the mvc object | |||
If an error occurs, an exception_handler function is run. If possible, the exception handler of the new mvc object is run, otherwise ''self::exception_handler'' function handles the error. If an exception occurs after creating the new mvc object, ''mvc.on_unload'' is guaranteed to run, but ''mvc.post_exec'' is not. | |||
=== soft_require ( self, modname ) === | |||
Looks for '''''modname'''.lua'' in ''self.conf.appdir'' and returns the results of a ''require()'' If the '''modname''' does not exist, returns nil. | |||
This function allows modules to be loaded without generating an exception if they do not exist. | |||
=== read_config ( self, modname ) === | |||
Looks in various places for a '''''modname'''.conf'' file and parses its contents into the '''self.conf''' table. | |||
=== parse_path_info ( string ) === | |||
Returns 3 strings: a prefix, controller, and action. Given a string in the format of a URI or pathspec, returns the ''basename'' as the action, the last component of the ''dirname'' as the controller, and the | |||
rest as the prefix. Missing components are returned as empty strings. | |||
=== find_view ( appdir, prefix, controller, action, viewtype ) === | |||
Returns a string with the view filename for this combination of prefix/controller/action/viewtype or nil if no view file exists. | |||
=== create_helper_library ( self ) === | |||
Returns a table of function pointers to be passed to each view. | |||
=== auto_view (viewtable, viewlibrary, pageinfo, session) === | |||
This functions is used as the view of last resort. If no view file is found, this function is called to display the CFE resulting from the invoked action. The following 'viewtype's are supported: | |||
* | * html | ||
* json | |||
* stream | |||
* serialized | |||
=== view_resolver ( self ) === | |||
The | Returns a function pointer to display the view, a table of functions made available to the view function, a table containing values of interest to the view, and a table containing the session data. The last three return values are designed to be the last three parameters to the view function pointer. | ||
=== soft_traceback ( self, message ) === | |||
If called with no arguments, returns a ''debug.traceback'', otherwise returns "message". | |||
=== exception_handler ( self, message ) === | |||
Prints an error message and then re-asserts the exception. Called if the xpcall in ''dispatch'' has an error. | |||
This is the exception_handler of last resort. The application should provide | |||
a more robust exception handler. | |||
=== cfe ( table ) === | |||
Returns a table with ''value'', ''type'', and ''label'' values. If an input table is given in the call, those key/value pairs are added as well. | |||
Guarantees the view will not get a "nil" on value, type, or label. | |||
This function is added to the global (_G) environment so it is available to the entire application. | |||
=== logevent ( message ) === | |||
Logs the message to syslog. | |||
=== handle_clientdata ( form, clientdata ) === | |||
This is a helper function for controllers to implement forms. It parses the form CFE and applies any changes submitted by the user in clientdata. | |||
=== handle_form ( self, getFunction, setFunction, clientdata, option, label, descr ) === | |||
This is a helper function for controllers to implement forms. It calls the getFunction to get the form CFE. If the form is submitted, it will call handle_clientdata and the setFunction to submit the form. The form CFE is returned. | |||
[[Category:ACF]] [[Category:Lua]] | |||
Latest revision as of 12:30, 7 March 2016
mvc.lua function reference
This lua module provides the basics for creating an mvc application. It is patterned loosely after the Ruby on Rails pattern - but much more simplistic.
The general pattern is to use the mvc new function to create a set of tables, and then use 'new within those tables to create sub "objects". By using metatable .__index methods, function references flow up through the parent tables.
new( self, modname )
Returns 3 values: an mvc table and 2 booleans ( true or false if the modname-controller and modname-model.lua were loaded)
The mvc table contains:
table | used for | comments | .__index points to |
---|---|---|---|
conf | configuration items | only created if a conf table does not exist in a parent | n/a |
clientdata | data sent from the client | only created if a clientdata table does not exist in a parent | n/a |
worker | the "controller" methods | if modname is given, then modname-controller.lua module is loaded into this table. Otherwise, an empty table is returned. | self (parent mvc object) |
worker.mvc | special methods run by the mvc dispatch function | If the modname-controller.lua module does not initalize a .mvc table, an empty one is created | self.mvc (parent mvc object's mvc table) |
model | the "model" methods | if modname is given, then modname-model.lua module is loaded into this table. Otherwise, an empty table is returned. | worker (this mvc object's worker table) |
The returned table has a .__index method that points to worker, so this table can inherit values from the parent table.
If the modname-controller.lua contains a .mvc.on_load function, the function is run before new returns.
The .__index metamethods mean that this code will set up inheritance as shown in the diagram:
require("mvc") MVC=mvc:new() APP=MVC:new() controller=APP:new() subcontroller=controller:new()
If you try to run subcontroller.model.somefunction(), and it does not exist, the inheritance will look for somefunction() in ...
- subcontroller.worker
- controller
- controller.worker
- APP
- APP.worker
- MVC
- MVC.worker
This allows, for instance, the application to set a default method that is available to all child controllers. The reason the model looks to its parent worker table first is that controller methods are usually in the worker table, and models do not normally inherit from each other.
The calling code should be sure to call the destroy function when done with this object.
destroy ( self )
Calls the mvc.on_unload function, if it exists, to close any resources opened by the object.
dispatch ( self, prefix, controller, action, clientdata )
The gateway for executing controller actions in a protected xpcall.
- If no controller specified, use default prefix/controller
- Creates a self:new ( prefix .. controller) mvc object
- If no action specified, use controller default_action
- runs any existing worker.mvc.pre_exec function
- runs the worker.action
- runs any existing worker.mvc.post_exec function
- gets the view function from view_resolver
- executes the view with the results of the worker.action
- and calls destroy to destroy the mvc object
If an error occurs, an exception_handler function is run. If possible, the exception handler of the new mvc object is run, otherwise self::exception_handler function handles the error. If an exception occurs after creating the new mvc object, mvc.on_unload is guaranteed to run, but mvc.post_exec is not.
soft_require ( self, modname )
Looks for modname.lua in self.conf.appdir and returns the results of a require() If the modname does not exist, returns nil.
This function allows modules to be loaded without generating an exception if they do not exist.
read_config ( self, modname )
Looks in various places for a modname.conf file and parses its contents into the self.conf table.
parse_path_info ( string )
Returns 3 strings: a prefix, controller, and action. Given a string in the format of a URI or pathspec, returns the basename as the action, the last component of the dirname as the controller, and the rest as the prefix. Missing components are returned as empty strings.
find_view ( appdir, prefix, controller, action, viewtype )
Returns a string with the view filename for this combination of prefix/controller/action/viewtype or nil if no view file exists.
create_helper_library ( self )
Returns a table of function pointers to be passed to each view.
auto_view (viewtable, viewlibrary, pageinfo, session)
This functions is used as the view of last resort. If no view file is found, this function is called to display the CFE resulting from the invoked action. The following 'viewtype's are supported:
- html
- json
- stream
- serialized
view_resolver ( self )
Returns a function pointer to display the view, a table of functions made available to the view function, a table containing values of interest to the view, and a table containing the session data. The last three return values are designed to be the last three parameters to the view function pointer.
soft_traceback ( self, message )
If called with no arguments, returns a debug.traceback, otherwise returns "message".
exception_handler ( self, message )
Prints an error message and then re-asserts the exception. Called if the xpcall in dispatch has an error. This is the exception_handler of last resort. The application should provide a more robust exception handler.
cfe ( table )
Returns a table with value, type, and label values. If an input table is given in the call, those key/value pairs are added as well. Guarantees the view will not get a "nil" on value, type, or label. This function is added to the global (_G) environment so it is available to the entire application.
logevent ( message )
Logs the message to syslog.
handle_clientdata ( form, clientdata )
This is a helper function for controllers to implement forms. It parses the form CFE and applies any changes submitted by the user in clientdata.
handle_form ( self, getFunction, setFunction, clientdata, option, label, descr )
This is a helper function for controllers to implement forms. It calls the getFunction to get the form CFE. If the form is submitted, it will call handle_clientdata and the setFunction to submit the form. The form CFE is returned.