Skip navigation

Adding Custom Tool Modules

Developers can add extend AssetNow (ANX) by adding their own application modules. Modules can be be used to provide front-end web site functionality and integrated with the ANX Tools.

Getting Started

The easiest approach is to copy and rename an existing AssetNow tool module and then modify it to your requirements.

Each ANX tool module resides in a subdirectory under the /sys/cfapps/assetnow/ directory. This directory also contains the /cfcs subdirectory where all ANX ColdFusion components are located.

When a module subdirectory is placed inside /sys/cfapps/assetnow and if the module directory contains an index.cfm template and a valid config-xml.cfm configuration template it will be automatically registered by ANX when Modules tool is selected. After a module is registered, you create instances - at least one instance is required - of the module, and assign the instances to roles.

Instances can differ in the module settings applied. These settings are called AppActions, and set in the user session when they load the module. Your module code can use AppActions to enable/disable features. You do not have to define any AppActions if your application module does not need them. You can add and test AppActions easily as you develop your application by adding/enabling/disabling them using the ANX Module tool.

Module Structure

AssetNow modules all use a common directory and code structure. The easiest way to get started is to copy and existing module, rename the subdirectory, and then add your database tables (if required) and modify the copied code.

The ANX Forms module is a good place to start. The default contact form uses a single table in the database with no primary/foregin key relationships to other tables. The following example assumes you are signed in to the ANX tools as the ANX site administrator.

1. Make a copy of the /sys/cfapps/assetnow/forms directory and rename it to /sys/cfapps/assetnow/demo.

2. Edit the config-xml.cfm template in the /sys/cfapps/assetnow/demo directory and change the application id tag located near the top of the XML configuration file from <anapp id="FORMS"> to <anapp id="DEMO">.

For ANX to register the module the id must be the same as the name of the subdirectory. Convention is to use uppercase.

Next give your application a unique REGCODE value. Typically this code is a UUID however can be any string of up to 35 characters provided it is unique within your ANX installation. You can easily generate a UUID from the ANX code pad unsing <cfoutput>#createUUID()#</cfoutput> and copy/paste the result into the configuration file.

The REGCODE can be used to secure access to your module templates. Access is secured via the ANX module launcher since this must be loaded in the user session to access modules. It is only loaded into the session if the user has the required permissions. The REGCODE provides secondary protection in the case of users with tool access manually editing URLs.

Next set the CATEGORY parameter value. This can be either tool or custom. Most often is set to tool as modules typically require a back-end tool interface. If set to custom the module will not be displayed in the ANX tool menu.

Lastly, the DESCRIPTION and APPACTIONS can be added via the ANX Module tool once the module is registered. For now just leave then unchanged.

Save the updated configuration template.

3. Next edit the index.cfm template, this is the module start template. When ANX launches a module it will always loads index.cfm. This template is typically displayed in the left frame of the ANX tools workspace.

At the top of index.cfm you will see conditional code that refers to the REGCODE:

<cfif session.anmodule.appUUID eq "A0185BBC-1372-25C0-2EC47D36453AE2B7">

Change the UUID value to the same value you entered in step 2 for the REGCODE in the config-xml.cfm template.

The tree control used in the index.cfm template also refers to the original form module path, change this in the line of code near the top of the template by replacing /forms/ with /demo/:

<cfset treeTarget = jsStringFormat("#application.virtualpaths.CFAPPS#/demo/frame_index.cfm")/>

Save the updated start template.

4. Edit the frame_index.cfm template and change the UUID to the new REGCODE value. The frame_index.cfm template is essentially a controller template that displays the output of the module application code contained in subdirectories of the /frame directory.

By using subdirectories you can partition and manage complex modules more easily. For example the ANX content publishing tool, located in the /tree module directory has a number of frame subdirectories.

When the Form module is launched, and the user clicks the Contact folder in the left panel tree control, the contact form code located in the /frame/contact directory is processed. The output is displayed in the right panel of the tools workspace . Most user interaction then occurs in the right panel and processing is handled by the /fame/contact/index.cfm template. This template is the controller for the contact form part of the module.

You can choose to secure the index.cfm template of the frame subdirectories in using the REGCODE however this is not essential.

Registering the Module

We are now all set to register our new Demo module. Since it is a copy of the form tool we should end up with two modules that perform the same function.

Register the module by going to the ANX System tool and clicking the Modules folder in the left panel tree. This lists all available/registered modules. You should see the demo module listed with a red Off status icon. Edit the demo module and set the status to On. You should also see that the AppActions have been read from the configuration file.

You can also adjust the order of your module which affects where in the top tools menu the application will be listed.

Once registered the modules details are stored in the ANX database. If you edit the configuration file you must click the Modules folder to update the values stored in the database. If you edit values, such as the Description or add/remove AppActions using the Module tool these changes are also saved in the the config-xml.cfm configuration template.

Creating a Module Instance

Next we must create at least one instance of our module and assign the instance to a Role.

In the System tool, under the Modules folder, click the demo folder, no instances are currently available for the demo module. Click the green + icon to add a new instance. Enable the AppActions you want set for this instance, for now check them all.

Next assign the instance to a Role, select the Site Administrator role and save the changes.

Sign out and then sign in again to reset your module permissions. You should see a new menu item in the top tools menu named MODULE_DEMO. The reason it is displayed in uppercase is that the module name is displayed using ANX localization text. We have not defined a localization text key/value pair for the demo module. If no corresponding key/value pair is found ANX writes the key/value to the i18n bundle file using uppercase. ANX also logs the missing value in the i18n log file. You can edit the corresponding text for the key in the tools localization bundle using the System > Tools > Bundles tool and set the required text for the module name.

Select the Demo tool from the top menu. You should see a form tool that functions just like the default forms tool.

ANX Module/Application Structure

All ANX tool modules use a common coding structure. The structure follows a Model View Controller approach and uses ColdFusion components (CFCs) for most logic. However the code is not object oriented and so is easy for typical ColdFusion developers to understand and modify. We will use the the Form module as an example.

 

Most modules will interact with a database and create, read, update and delete (CRUD) records from a database table (or tables). ANX uses entity CFCs for most CRUD operations. You will find an entity CFC for each table in the ANX database in the /sys/cfapps/assetnow/cfcs/entities directory.

When coding your module it is best to create your database table/s first. Then create a corresponding entity CFC for each table. Review the formcontacts.cfc entity CFC as an example. Note that it uses the common slqlib.cfm template and sqllengths.cfc CFC. These provide common string processing functions and set the default string lengths used in ANX.

We also recommend you adopt the ANX database table/column naming conventions. Column names use a table derived lowercase prefix, for example frmcContactID where frmc means FormContacts table. Doing so will ensure you do not have name conflicts. All tables have an auto-increment primary key ID and an identifier column that is typically a UUID. If you create join tables use _ID when naming foreign keys.

All table references in SQL use lowercase table names for compatibility with file-based databases such as MySQL on Linux.

Use general timestamps for date/time fields and use uppercase TS in the column name, for example frmcTSCreated, when processing form data ANX will convert value timestamps in field name with TS to ODBC compatible values before saving.

The entity CFC is used by the module's core component. The module CFC contains most of the module application logic and the application data model. Review the Forms module CFC located in the /sys/cfapps/assetnow/cfcs/modules directory. At a minimum the module's CFC will contain an initialization method, a list method to list records, and new, update (edit), and delete methods (CRUD methods). The new, update and delete methods use the corresponding entity CFC.

The initialization method sets up the data model, the model parameters correspond to the associated table columns. the initialization code can also set additional values required by the user interface templates. The data model is either initialized to default values or populated with a specific record by passing in the primary key value.

 

Next look a the module controller template. This is located in a subdirectory of /frame subdirectory of the module. Take a look at /sys/cfapps/assetnow/forms/frame/contact/index.cfm.

The key items to note are that at the top we set default request parameters that are used by the module. Typically this will be the primary key which is passed when the user interacts with the record listing or form displays. Also define/set any other parameters required to process requests. Also notice that we instantiate a copy of the module CFC and then initialize the data model using the primary key value:

<cfset objApp=createObject("component","#application.config.CFCOMPONENTS_PREFIX#.modules.formcontacts")/>
<cfset objApp.init(request.frmcContactID)/>

What this means is we can now access our data model and module functions using objApp.

 

ANX copies URL and FORM variables in the ColdFusion request scope so in most cases your code only needs to refer to the model object, objApp, or values in the request scope (values passed by the user clicking a link, URL, or submitting a form, FORM).

The ANX requestToObject() function copies request scope values in the corresponding data model, objApp (object), variables. Consequently your model variable names should be the same as the table column names to allow ANX to automatically copy the data. For example a form submission editing a record would be processed by ANX as FORM > request > ObjApp.

 

The code in index.cfm action code driven by the selected user request.AppAction. Note that these AppActions do not have to be set in the module AppActions. They are simply controller actions that direct the program flow and must be set in the frame_index.cfm template.

 

If you have used an identifier in your data, then you can use ANX record locking to prevent simultaneous editing of records. This is done by adding the conditional code, <cfif not isRecordLocked(objApp.frmcIdentifier)>, to the controller as shown in the index.cfm.

 

While it is not essential to use localization bundles for your module test we recommend that you do as it is far easier to do it from the start than have to go back and apply it later. Also keep in mind that tools users can select their own language for the tool interface if you allow this. Localization text is displayed using LSMessage("AN_TEXT_IDENTIFER","tools") where AN_TEXT_IDENTIFER is the key to the text in the bundle file and tools is the bundle file. you can create you own bundle file for each application and optionally choose not to persist the bundle text in memory, for example, load your own bundle before using the LSMessage() function with <cfset LSBundle("demo","demo")/> where demo is the bundle name, and use this bundle with like this LSMessage("AN_TEXT_IDENTIFER","demo").

 

Review the ANX list and form templates for a typical CRUD style user interface. The form uses tool widgets to provide tabs and other standardized input elements such as calendars and text fields.

Location

http://www.assetnow.com/index.cfm/1,84,299,0,html