FormMagick HOWTO

This HOWTO will outline how to create and maintain panels on the SME Server using the esmith::FormMagick module, just like all of the official panels are done.

This is currently a work-in-progress.

Why use FormMagick?

Primarily, because FormMagick provides a localization API, so that panels can be provided in multiple languages, with the text separated out in XML lexicon files. These files can then be given to anyone wanting to translate the server's panels, and they can provide translations. This makes the SME Server a truly international project. Please, think of others. Not everyone speaks English.

Additionally, esmith::FormMagick subclasses CGI::FormMagick and provides certain boilerplate code for the panels to make life easier for panel authors. It also causes certain problems which will be detailed here, with their current solutions.

Getting Started

As always, use the source. Look at the existing panels, most of which use FormMagick, and learn from them. The ones that truly use FormMagick have an xml page definition in the cgi script at /etc/e-smith/web/functions. Lets look at a simple one. If you have a 6.0 SME Server, look at /etc/e-smith/web/functions/quota. This is the cgi script that is run when you click on quotas in the server manager's menu.

#!/usr/bin/perl -wT

#----------------------------------------------------------------------
# heading     : Collaboration
# description : Quotas
# navigation  : 2000 2300
#----------------------------------------------------------------------

As you can see, we're running perl with warnings and taint-checking turned-on. Good ideas for a CGI script. The comments here are picked up when the menu is generated, so the Quota panel ends up the Collaboration section, and the weighting controls where not only that section ends up, but where in that section it appears. Lets continue past the Mitel copyright.

use strict;
use esmith::FormMagick::Panel::quota;

my $panel = esmith::FormMagick::Panel::quota->new();
$panel->display();

We use the strict pragma, good idea for any Perl script beyond 10 lines or so, and then use a module called esmith::FormMagick::Panel::quota. We'll find out what that is later. Then, we instantiate an instance of that class, and call its display method. That's basically it for Perl code in the CGI front-end.

Next, in the section of the CGI, is the XML page definition. This is the heart of FormMagick, allowing you to describe the pages in your CGI using XML. Lets look at it.

<form title="FORM_TITLE" header="/etc/e-smith/web/common/head.tmpl"
                         footer="/etc/e-smith/web/common/foot.tmpl">

We start the DATA section, and then the form itself, specifying the lexicon tag for the form title, and the paths to the page header and footer. I'll explain lexicon later, but pay attention to it. It's a vital part of FormMagick's localisation API (not everyone speaks English...).

  <page name="Initial" pre-event="print_status_message">
    <subroutine src="showInitial()"/>
  </page>

This is our first page definition. We name the page "Initial", define a pre-event to call the print_status_message function, and then define the contents of our page. In this case, we don't define a bunch of widgets and their callbacks, we just tell FormMagick to call a subroutine called showInitial. That subroutine is exported in the module we included, and we'll cover it later, but basically, it outputs the initial quota page you see when you load the panel.

The next page definition is a little more standard FormMagick.

  <page name="Modify" pre-event="turn_off_buttons"
  post-event="performModifyUser">
    <title>MODIFY_USER_TITLE</title>
    <subroutine src="modifyUser()"/>
    <subroutine src="print_button('SAVE')"/>
  </page>

Here, we define a page called "Modify", and call a pre-event subroutine of turn_off_buttons. We do that because by default, FormMagick will create a "Next" button, and we don't want one here. We define a post-event of performModifyUser, a function we define to handle the form submission. The page title is defined as the lexicon of MODIFY_USER_TITLE, and then we call two subroutines to draw the page itself. Note that for static form contents, like groups of widgets, we would define them right in the XML. We will cover an example of that later. For now, I'd like to cover the relationship between the front-end and the back-end.