ACF how to write: Difference between revisions

From Alpine Linux
mNo edit summary
mNo edit summary
Line 117: Line 117:
  readfile = function()
  readfile = function()
     retval = ""
     retval = ""
    error = 0
     fileptr = io.open( cfgfile, "r" )
     fileptr = io.open( cfgfile, "r" )
     if fileptr ~= nil then
     if fileptr ~= nil then
Line 125: Line 126:
       fileptr:close()
       fileptr:close()
     end
     end
     return cfe({ error = 0, msg = retval })
     return error, cfe({ msg = retval })
  end
  end
   
   

Revision as of 08:52, 17 November 2007

How to Write an ACF Under Construction

For some examples please see svn

svn co svn://svn.alpinelinux.org/acf

  • shorewall
  • dhcp


From <nil> to a running ACF example application Under Construction

Step 1 - The Programming Language

  • ACF uses lua as programming language. Have a look at lua.org [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: In Model the 'real work' is done (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 files, each presenting a dynamic html page which only as much code as neccessary to format the data you retrieve from Model.
  • Controller: The event dispatcher. In controller you place one function per event. If the user calls 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 Model and passes it to 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
  • config.mk
  • myapp-model.lua
  • myapp-myview-html.lsp
  • myapp-controller.lua
  • myapp.menu


Makefile:

The Makefile once called does install our acf application so that we can look at it working.

APP_NAME=myapp
PACKAGE=acf-$(APP_NAME)
VERSION=1.0_alpha1

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

EXTRA_DIST=README Makefile config.mk

DISTFILES=$(APP_DIST) $(EXTRA_DIST)

TAR=tar

P=$(PACKAGE)-$(VERSION)
tarball=$(P).tar.bz2
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)

all:
clean:
        rm -rf $(tarball) $(P)

dist: $(tarball)

install:
        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)

include config.mk

.PHONY: all clean dist install dist-install

Remark: Should you create additional 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.


config.mk: For use with the Makefile. Just copy/paste it. We will look at it later.

prefix=/usr
datadir=${prefix}/share
sysconfdir=${prefix}/etc
localstatedir=${prefix}/var
acfdir=${datadir}/acf
wwwdir=${acfdir}/www
cgibindir=${acfdir}/cgi-bin
appdir=${acfdir}/app
acflibdir=${acfdir}/lib
sessionsdir=${localstatedir}/lib/acf/sessions


myapp-myview-html.lsp:

-- 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 = ""
   error = 0
   fileptr = io.open( cfgfile, "r" )
   if fileptr ~= nil then
      retval = fileptr:read( "*a" )
      if retval == nil then
         retval = ""
      end
      fileptr:close()
   end
   return error, cfe({ msg = retval })
end

# This function will write new contents into our file
writefile = function( newcontents )
   fileptr = io.open( cfgfile, "w+" )
   if fileptr ~= nil then
      fileptr:write( newcontents )
      fileptr:close()
   end
   return
end