ACF how to write

From Alpine Linux
Revision as of 18:05, 25 April 2008 by Ttrask (talk | contribs) (How to Write an ACF <span style="color:red"> Under Construction</span>)
Jump to: navigation, search

How to Write an ACF Under Construction

For some examples please see svn

svn co svn://

  • shorewall
  • dhcp

From <nil> to a running ACF example application

Step 1 - The Programming Language

  • ACF uses lua as programming language. Have a look at [1] before starting.

Step 2 - The Development Environment

Step 3 - Create A Development Directory

Once you entered the ACF Development Environment as described in step 2:

  • in your user home create a directory for your application (e.g. mkdir ~/myapp)
  • and cd into it (e.g. cd ~/myapp)

Step 4 - MVC, How Does It Affect My Coding?

ACF is an MVC based framework. What does this mean to you? Your application is separated into three layers: Model, View, Controller - each of which has one or more files.

  • Model: The 'real work' is done in the Model (e.g. modifying config files, starting/stopping services etc.)
  • View: This is where you define what your application will look like. You can have one or more View files, each presenting a dynamic html page with only as much code as neccessary to format the data you receive from the Controller.
  • Controller: The event dispatcher. In the Controller, you create one function per action. If the user loads the respective 'event page' (web), acf will fire an action - the same-named function in controller will be called. This function then retrieves neccessary data from the Model and passes it to the View to be displayed to the user.

Step 5 - The Example Files To Start With

Now let us have a look at the files we need to place into our application directory:

  • Makefile
  • myapp-model.lua
  • myapp-myview-html.lsp
  • myapp-controller.lua
  • myapp.roles


The Makefile is called to install our acf application so that we can see it working.


APP_DIST=myapp-model.lua        \
         myapp-myview-html.lsp  \
         myapp-controller.lua   \
         myapp.roles            \





        rm -rf $(tarball) $(P)

dist: $(tarball)

        mkdir -p "$(install_dir)"
        cp -a $(APP_DIST) "$(install_dir)"

$(tarball):     $(DISTFILES)
        rm -rf $(P)
        mkdir -p $(P)
        cp $(DISTFILES) $(P)
        $(TAR) -jcf $@ $(P)
        rm -rf $(P)

# target that creates a tar package, unpacks is and install from package
dist-install: $(tarball)
        $(TAR) -jxf $(tarball)
        $(MAKE) -C $(P) install DESTDIR=$(DESTDIR)
        rm -rf $(P)


.PHONY: all clean dist install dist-install

Remark: Should you create additional application files (view files for example), don't forget to place their names in Makefile under APP_DIST otherwise they will not be installed later on and your application will fail with an error message. For use with the Makefile. Just copy/paste it. We will look at it later.



-- acf model for myapp
-- Copyright(c) 2007 <Your name here> - Licensed under terms of GPL2
module (..., package.seeall)

cfgfile = "/tmp/myfile"

-- This function returns a cfe (table of values) containing the files'
-- value as string and an error code. If the file does not exist, we'll
-- simply return "" (an empty string, but NOT nil)
readfile = function()
   retval = ""
   fileptr = cfgfile, "r" )
   if fileptr ~= nil then
      retval = fileptr:read( "*a" )
      if retval == nil then
         retval = ""
   return cfe({ msg = retval })

-- This function will write new contents into our file
writefile = function( newcontents )
   fileptr = cfgfile, "w+" )
   if fileptr ~= nil then
      fileptr:write( newcontents )


   form = ...
<h1>MyApp - MyView</h1>
<form action="" method="POST">
  <textarea name="textdata"><? io.write( form.msg ) ?></textarea>
  <input type="submit" name="cmd" value="update">


-- the myapp  controller
module (..., package.seeall) 

myview = function( self )
   -- self.clientdata contains the data from the html form
   -- in your myapp-myview-html.lsp
   local clidat = self.clientdata  

   -- user did submit the form (not just call the page)
   if clidat.cmd then
      if clidat.cmd == "update" then -- user pressed update button
         self.model.writefile( clidat.textdata )
   value = self.model.readfile()
   return (value)



# Cat   Group   Tab     Action
Test    MyApp   MyView  myview

Step 6 - What Does It Do?

This program just displays a <textarea> box and a submit "update" button. The user can enter text that is saved into a file once he presses "update".

In Depth

Now let us have a closer look at the different files' contents:


The functions defined in here can be accessed by the controller to update/set/retrieve data, start/stop services, basically do any 'real work'.


This is our view. It receives the data to be displayed from the controller. Whatever is returned by a controller action (function) can be accessed by the view (see the first three lines .. <? .. ?>).


The controller is an event dispatcher. So, in here you define all the actions that the user can call or that are defined in the menu. Each action is a separate function that will receive self as the only parameter.

In our case the action is myview.

For every action you define here, you can define a separate view file using the nameage: myapp-action-html.lsp

If there is no view file for a specific action, the application will look for a generic view file using the nameage: myapp-html.lsp

This function can call the model's functions to update and/or retrieve data (e.g. self.model.readfile()).

Anything that this function returns will be passed on to the view


This file determines which users have access to which controllers and views. A separate roles file is generally defined for each ACF. The format of the files is as follows:


Each line defines controller:action combinations that are permitted for a particular group. ALL is a special group to which all users, including anonymous users, are members.

In this file you define:

  • The Category in which a menu entry for your program will appear
  • The Group menu name under Category for this controller
  • The Tab name on the controller page
  • The Action with-in your controller that will be called once the user clicks on the menu entry or tab defined by Category, Group, and Tab.

How to exchange data between model-view-controller?

To exchange data between model, view and controller ACF uses Configuration Framework Entities (CFE).

Please see ACF_core_principles for further details on CFEs.

Step 7 - How To Get It Going?

Once you have completed all the above mentioned steps, go on with: