Custom Project Templates

Version 54.1 by David Avendasora on 2009/04/07 05:47

Introduction

WOLips 3.3 supports the definition of custom project templates. These templates support creating new types of WebObjects projects beyond the ones that ship with WOLips.

To use a custom project template, create a new project by going to the "File" menu and selecting "New -> Other..." then select the "WO Project from Template" option under the WOLips section.
NewProjectFromTemplate.png

Creating a Template

Templates are basically like a regular project folder, but some of the contents are modified to use the variables defined in the template.xml file to change their names or values in their contents. The modified files within the template are processed using the Velocity Template Engine.

The declaration of templates is very simple. The template system looks for folders in the following locations (in the following order):

  1. The ProjectTemplates folder inside of the WOLips templateengine plugin jar
  2. /Library/Application Support/WOLips/Project Templates
  3. YourHomeDirocuments and Settingspplication DataOLipsroject Templates
  4. YourHomeDirocuments and SettingsppDataocalOLipsroject Templates
  5. /Library/Application Support/WOLips/Project Templates
Warning

Project templates found later in the list of locations above will override those of the same name from earlier in the list.  For instance, a "Wonder Application" template found in \/Library will override a "Wonder Application" template from /Library.

The name that the template shows up as in the New Project wizard is controlled by one of two things:

  1. The template's folder name
  2. The name attribute of the template tag in the template.xml file inside the template folder (if present, this overrides the value set by the template folder name).

For instance, if you create a folder named "/Library/Application Support/WOLips/Project Templates/Wonder Application," the template system will offer a template named "Wonder Application" in the template selection dialog. If you then set the name attribute to "My Wonder Application", that is what you will see in the dialog.

If you want to look at the current templates that ship with WOLips, the best way to analyse them is by importing the source of WOLips from Subversion. The templates are located in woproject/wolips/core/plugins/org.objectstyle.wolips.templateengine/ProjectTemplates.

Here is an additional custom template for creating Wonder ERD2W Applications that you can view as an example.

Warning

Remember, if you copy an existing template to test it out you must rename both the folder *and* the name attribute of the template tag in the template.xml file otherwise whichever loads last will replace the first!

After creating a template folder, you can create a hierarchy of files and folders within that folder. When you create a project using this template, a copy of all of the files and folders in your template will be used to create the new project. It is up to you to declare all of the files within a project, including Eclipse project metadata files like .classpath. You can refer to the built-in project templates as a starting point for creating your own custom templates.

That's it For creating static boilerplate templates, you're done.

Template Metadata and Template Inputs

For a static template, the simple process above is enough. However, it's a common requirement to have configuration options for project templates. The WOLips project template engine provides an easy way to declare these options.

After creating a template using the directions in the above section, you can additionally create a file named "template.xml" inside your project template folder.  For instance, in the example above, you would create the file "/Library/Application Support/WOLips/Project Templates/Wonder Application/template.xml".

An example template.xml is below:


<?xml version="1.0" encoding="UTF-8"?>
 <template name = "Wonder Application">
   <inputs>
     <input name = "linkToWonderProjects" type = "Boolean">
       <question>Link to Wonder Projects?</question>
       <default>false</default>
     </input>
     <input name = "linkToWonderFrameworks" type = "Boolean">
       <question>Link to Wonder Frameworks?</question>
       <default>true</default>
     </input>
     <input name = "YourFavoriteColor" type = "String">
       <question>Your Favorite Color?</question>
       <options>
         <option name = "Red" value = "#FF0000"/>
         <option name = "Green" value = "#00FF00"/>
         <option name = "Blue" value = "#0000FF"/>
       </options>
       <default>#FF0000</default>
     </input>
   </inputs>
 </template>

The "name" attribute of the template node overrides the name of the folder the templates are in.  For instance, you could have the above template.xml inside a folder named "Template 1" and the template system would consider the name of the template to be "Wonder Application."

Within a template, you can declare a single "inputs" node that can contain multiple "input" nodes. Each input node corresponds to a variable that will be presented to the user on the second page of the wizard. Each input specifies a "name" attribute, which will become the variable name of the input for later reference in the Velocity templates; and a "type" attribute which can be one of Boolean, String, Package, or Integer. The type value determines the control that will be used to display the input to the user (String = text field, Boolean = checkbox, Integer = spinner, Package = text field, etc). Each input also contains a "question" node, whose value corresponds to the label of the control when displayed to the user.  In the above example, the "linkToWonderFrameworks" will display a checkbox to the user with the label "Link to Wonder Frameworks?". Additionally, you can provide a "default" node that defines the default value of the variable.  If a default is not specified, the default value will be null for all input types.

The package type is slight extension to the String type.  For a variable declared as type Package, in addition to having your variable bound, you will also have a variable named "yourvariablenamefolder" with replaces dots for slashes.  For instance, if your variable is named "basePackage," you will also get a variable named "basePackagefolder."  This is useful because you can use template variables in folder names on the filesystem.

Finally, the input system supports the declaration of enumerated types. By declaring an "options" node that contains an ordered set of "option" nodes, you can define the possible values that the user can provide. In the above example, the "YourFavoriteColor" input defines three options: Red, Green, and Blue. Each option node has a "name" attribute, which will be the value displayed to the user, and a "value" attribute, which will be the actual backing value of the selection. The value of the option should be of the type specified in the "type" attribute of the input.  For instance, if you declare the input type to be "Integer," your option values should be integer values (in quotes).

Using Template Inputs

So now that you have template input defined, you will want to be able to use them. The name use used in the "name" attribute of your input declaration will be the name of the variable in your Velocity context. For instance, in the example above, the Velocity variable "linkToWonderProjects" will be bound to the boolean value corresponding to the user's selection, and can be used just like any other velocity variable. The Apache project provides a Velocity reference guide.

As an example, the Wonder Application template's .classpath file is defined as:


<?xml version="1.0" encoding="UTF-8"?>
 <classpath>
   <classpathentry kind="src" path="Sources"/>
    #if ($linkToWonderProjects)
   <classpathentry combineaccessrules="false" kind="src" path="/ERJars"/>
   <classpathentry combineaccessrules="false" kind="src" path="/ERExtensions"/>
   <classpathentry combineaccessrules="false" kind="src" path="/ERPrototypes"/>
   <classpathentry combineaccessrules="false" kind="src" path="/JavaWOExtensions"/>
    #end
    #if ($linkToWonderFrameworks)
   <classpathentry kind="con" path="org.objectstyle.wolips.WO_CLASSPATH/ERExtensions/ERJars/ERPrototypes/JavaWOExtensions/JavaEOAccess/JavaEOControl/JavaFoundation/JavaJDBCAdaptor/JavaWebObjects/JavaXML"/>
    #else
   <classpathentry kind="con" path="org.objectstyle.wolips.WO_CLASSPATH/JavaEOAccess/JavaEOControl/JavaFoundation/JavaJDBCAdaptor/JavaWebObjects/JavaXML"/>
    #end
   <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
   <classpathentry kind="output" path="bin"/>
 </classpath>

In addition to variables inside of Velocity templates, you can also use template inputs in folder names.  However, because $ is not allowed on some filesystems, we instead surround the variable names with "" (for instance $someVariable would be someVariable in the filename or path).  As an example, the Wonder Application template has an input named "basePackage" (of type Package), which creates a magic variable named "basePackagefolder" (where the dots are turned into slashes), and the Source folder on the filesystem is named "Wonder Application/Sources/basePackagefolder".

Happy templating