en En
es Es

How to add a custom module

The article presents an example of creating an interface for editing a list of abstract elements.

Problem statement

  • There is a billing platform;
  • The file /etc/myconf stores a list of elements for which an interface needs to be created for editing.

Procedure

  1. Create a plugin description file /usr/local/mgr5/etc/xml/billmgr_mod_myconf.xml with the following content:

    Expand to see the description
  2. Create a processing module file /usr/local/mgr5/addon/myconf.pl with the following content:

    Expand to view the content
  3. Set permissions on the processing module file:

    chmod 750 /usr/local/mgr5/addon/myconf.pl
    chown 0:0 /usr/local/mgr5/addon/myconf.pl
  4. Restart the billing platform:

    /usr/local/mgr5/sbin/mgrctl -m billmgr exit

Explanations

Create a description of the processing module script and specify that it will be executed when calling custom functions. The description looks similar to the description of events, only the func tag is used instead of the event tag:

<handler name="myconf.pl" type="cgi">
   <func>myconf</func>
   <func>myconf.edit</func>
   <func>myconf.delete</func>
</handler>

Describe the link in the menu:

<mainmenu level="30">
   <node name="tool">
   <node name="myconf"/>
   </node>
</mainmenu>

Describe what the data table will look like:

   <metadata name="myconf" type="list" key="item">
     <toolbar>
       <toolbtn func="myconf.edit" type="new"  img="t-new" name="new"/>
       <toolbtn func="myconf.edit" type="edit" img="t-edit" name="edit" default="yes"/>
       <toolbtn func="myconf.delete" type="group" img="t-delete" name="delete"/>
     </toolbar>
     <coldata>
       <col sort="alpha" sorted="yes" name="item" type="data"/>
     </coldata>
   </metadata>

In our example, the data table has one column, and the toolbar has buttons:

  • Create;
  • Edit;
  • Delete.

For more information about tags and attributes, refer to the article Description of lists.

Describe what the edit form will look like:

<metadata name="myconf.edit" type="form">
   <form>
     <field name="item">
       <input type="text" name="item"/>
     </field>
   </form>
</metadata>

In the example, the form has one input field. For more information about tags and attributes, refer to the article Description of forms.

Describe messages for new interfaces. For more information, please refer to the article Message names.

Processing module script

Get the data and determine the name of the called function:

 use CGI qw/:standard/;

$Q = new CGI;
 $func = $Q->param(func);

Depending on the called function, call the corresponding procedure:

if( $func eq "myconf" ){
	&List;
} elsif( $func eq "myconf.delete" ){
	&Delete;
} elsif( $func eq "myconf.edit" ){
	if(	$Q->param( "sok" ) ){
		if( $Q->param( "elid" ) ){
			&Set;
		} else{
			&New;
		}
		print "<ok/>";
	} else{
		&Get;
	}
}

Output of the data list:

sub List {
	if( open( IN, "/etc/myconf" ) ){
		while( <IN> ){
			chomp;
			print "<elem><item>$_</item></elem>";
		}
		close( IN );
	}
}

Read the file with data /etc/myconf line by line and generate an XML document with data. The elem tag denotes a data row and contains child elements describing data by columns; the name of the nested tag item can be arbitrary, but must match the name attribute in the table column description (the col tag).

Reading data when opening the element edit form:

sub Get {
	$elid = $Q->param( "elid" );
	print "<elid>$elid</elid><item>$elid</item>" if( $elid );
}

The function will be called when opening the edit form, for the case of creating and for editing an existing element. If the elid parameter is not empty, it means the element is being edited. This parameter contains a value from the list column with the name specified in the key attribute of the metadata tag when describing the data table interface.

Since in the example the form contains only one data field, nothing is read from files, and the parameter of the requested element is simply returned. A better option would be to check for the existence of the element in the data file and display an error if it is missing. The elid tag specifies the key value for the edited element; it will also be displayed in the form header. The item tag in the example contains the value that will be displayed in the input field named item.

Editing a record:

sub Set {
	$elid = $Q->param( "elid" );
	$item = $Q->param( "item" );
       .......
} 

When editing a record, the following parameters are important:

  • elid — contains the name (key field) of the edited element;
  • item — the value entered by the user in the field named item.

Next, you need to read the data file, find in it the element from the elid parameter, and replace its value with the value of the item parameter. If the desired element is not found, display an error message.

Creating a new element

sub New {
	$item = $Q->param( "item" );
	if( open( ADD, ">>/etc/myconf" ) ){
		print ADD "$item\n";
		close( ADD );
		print "<ok/>";
	} else {
		print "<error>Item hasn`t been added</error>";
	}
}

You need to take the value from the item parameter and add it to the end of the data file. If the file could not be opened for some reason, display an error message.

Deleting a list element

sub Delete {
	@all_elem = split(", ", $Q->param( "elid" ));
       ......
}

Since the delete operation is a group operation, meaning several elements can be deleted in one call, the elid parameter can contain several names separated by ", " (comma and space). Form an array of elements to be deleted, then read the data file and delete from it the lines contained in the array of elements to be deleted.