<?xml version="1.0" encoding="UTF-8"?>
<!--
  Copyright 2002-2005 The Apache Software Foundation or its licensors,
  as applicable.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!DOCTYPE howto PUBLIC "-//APACHE//DTD How-to V2.0//EN" "http://forrest.apache.org/dtd/howto-v20.dtd">
<howto>
  <header>
    <title>How to Build a Plugin</title>

    <version>0.1</version>

    <abstract>This How-To describes the steps necessary to build a plugin for 
    Forrest. Forrest uses plugins to add new input formats, output formats
    and to change its default behaviour. Since plugins are downloaded when
    needed and can be hosted at any location, plugin code can be developed 
    independently of Apache Forrest. This how-to describes each of the major
    steps in creating a plugin and then works through some examples of 
    plugin creation in order to illustrate the materials.</abstract>

    <last-modified-content-date date="2005-04-12" />
  </header>

  <audience title="Intended Audience">
    <p>Users needing to add additional input formats or output formats or
    to change the operation of the Forrest internals.</p>
    
    <warning>The Plugin Infrastructure is still at an early stage of design 
    and implementation, consequently this How-To <em>may</em> be out of date
    and/or incomplete. If you are having problems with any of the steps 
    described, please ask for help on the developers mailing list (and then
    provide patches for this document).</warning>
    <warning>Please make sure that you are using forrest 0.7 if you want use 
    plugins. Forrest 0.6 will not work!!!</warning>
  </audience>

  <purpose title="Purpose">
    <p>This How-To will illustrate how to build a plugin, publish a plugin
    and configure a Forrest project to use their plugin.</p>
  </purpose>

  <prerequisites title="Prerequisites">
    <p>Plugin developers should have:</p>
    
    <ul>
      <li>a basic knowledge of XML, XSLT and Cocoon pipelines</li>
      <li>a clear use-case for extending Forrest</li>
      <li>read
        <a href="site:plugins/infrastructure">Plugin Infrastructure</a>
      </li>
      <li>verified with the Apache Forrest developer community that the
      requried functionality does not already exist</li>
    </ul>
  </prerequisites>

  <steps title="Steps">
    <p>Here is how to proceed.</p>

    <section id="typeOfPlugin">
      <title>Type of Plugin</title>

      <p>There are three types of plugin, each with a clear purpose, you
      must first decide which 
      <a href="site:plugins/infrastructure">type of plugin</a>
      you need to build.</p>
      
    </section>
    
    <section id="ant">
      <title>Make ant available on the command-line</title>
      <p>
        The following instructions rely heavily on
        <a href="http://ant.apache.org/">Apache Ant</a>
        to automate some steps in the process. Since ant
        is distributed as part of Forrest, all you need to do
        is add the ant executable directory to your system path. The
        name of this directory is <code>tools/ant/bin</code>
        in your Forrest program directory.
        (Alternatively you can prefix all calls to ant in
        the following instructions with the full path of the ant binary directory.)
        Also clear the ANT_HOME environment variable.
      </p>
      <p>
        If instead you really want to use your own version of Ant,
        then you will need to copy
        forrest/lib/core/xml-commons-resolver.jar
        to $ANT_HOME/lib directory, otherwise your plugins will go across
        the network to get the DTDs on every parse.
      </p>
    </section>

    <section id="seed">
      <title>Seed a New Plugin</title>
      <p>Regardless of the type of plugin you are building, the directory
      structure is almost identical, as are most of the requried
      configuration files. In this How-To we will assume that you are creating a 
      plugin in the Forrest source tree. All plugins are developed in the
      <code>forrest/plugins</code> directory.</p>
      
      <p class="instruction">Run the following set of commands:</p>
      
      <source>
      cd [path_to_forrest]/plugins
      ant seedPlugin
      </source>      
      
      <p>The above ant target will ask you the name of the plugin and will
      build a minimal plugin directory structure and configuration. You will 
      need to customise these files to build your plugin.</p>
      
      <note>Although you can name your project anything you like we do have 
      some <a href="site:plugins/infrastructure">naming 
      conventions</a> that we recommend you follow. Plugins intended to be
      held at forrest.apache.org must follow the naming convention.</note> 
      
      <note>If you plan on building your plugin elsewhere you can copy the
      <code>build.xml</code> build file to your own plugin work directory and 
      use it there.</note>
      
      <p>See 
      <a href="site:plugins/infrastructure">Plugin
      Infrastructure</a> for more information about the plugin
      directory structure and configuration files.</p>
    
      <section id="edit-template">
        <title>Edit the Plugin Template</title>
        <p>You now have a skeleton plugin project. However, it doesn't do 
        anything useful yet. Now is a good time to edit some of the files
        provided.</p>

        <note>
          For plugins intended to be held at forrest.apache.org please
          adjust the skinconf.xml etc to be in accordance with the other
          forrest plugins. See <a href="#hosted">notes</a> below.
        </note>

        <p>Here are some general notes:</p>
        
        <section id="status">
          <title>status.xml</title>
          <p>This file is used to track changes to the plugin
          project and to manage lists of things that still need to be done.
          At this stage you should correct the <code>person</code> entry
          near the top of the file. It is also a good idea to add a few key
          milestones in the task list towards the bottom of the file.</p>
          
          <p>As you work on the plugin you should record all major changes in
          this file so that it can then be used as a changelog for your
          plugin.</p>
        </section>
        
        <section id="forrest-properties">
          <title>forrest.properties</title>
          
          <p>This file defines many configuration parameters for Forrest. It
          does not need to be customised in most cases. However, see
          for more details.</p>
        </section>
        
        <section id="skinconf">
          <title>src/documentation/skinconf.xml</title>
          <p>This configures the skin for your plugins documentation. There
          are some items that need to be configured in here, for example, the
          copyright information. The file is heavily commented so probably
          best to read through it, changing what you need to.</p>
        </section>
        
        <section id="doc">
          <title>Documentation</title>
          <p>It is also a good idea to start writing the documentation at this
          stage. The above process created a very simple plugin documentation
          site for you. All you have to do is add the content.</p>
        </section>
        
        <section id="hosted">
          <title>Style notes for plugins hosted at forrest.apapche.org</title>
          <p>
            After seeding a new plugin, copy the configuration from an
            exisiting plugin (e.g. org.apache.forrest.plugin.input.projectInfo).
            Copy src/documentation/skinconf.xml and 
            src/documentation/content/xdocs/images/project-logo.gif
          </p>
        </section>
      </section>
    </section>
    
    <section id="edit-sitemap">
      <title>Edit the Plugin sitemap file(s)</title>
      <p>The plugin <code>xmap</code> file is a Cocoon sitemap that is mounted
      at a strategic place in the Forrest pipeline. It is in this file
      that you will instruct Forrest how to operate. An input plugin
      must provide a <code>input.xmap</code> file, an output plugin
      must provide a <code>output.xmap</code> file, whilst an internal
      plugin provides a <code>internal.xmap</code> file. In addition, an
      input plugin may provide a <code>resources.xmap</code> file to
      allow the plugin to handle items such as JavaScript files.</p>
      
      <p>It is beyond the scope of this How-To to give details about how to 
      build your plugins XMap. See the 
      <a href="site:v0.70//documentation/developers/sitemap-ref">Sitemap Reference</a> for general
      information. See also 
      <a href="site:plugins/infrastructure">Plugin Infrastructure</a>
      for some hints and tips on creating plugin sitemaps. In addition, as with
      all development work on Forrest, you will find
      the <a href="site:mail-lists/forrest-dev">developer mailing list</a>
      a very good resource (check the archives before posting, please).</p>
      
      <section id="components">
        <title>Components, Actions and Resources</title>
        <p>If your plugin uses any components (i.e. generators, transformers or
        serializers), actions or resources they must
        be defined in either the xmap for this plugin or one of its parents. The parents
        of an <code>input.xmap</code> are <code>sitemap.xmap</code> and
        <code>forrest.xmap</code>, whilst the parent of both 
        <code>output.xmap</code> and <code>internal.xmap</code> are 
        <code>sitemap.xmap</code></p>
        <p>If you want to use the realpath where the sitemap.xmap of your plugin 
        resides then you need to use 
        <code>{forrest:plugins}/PLUGIN_NAME</code> instead of <code>{realpath:/}</code>.
        </p>
        <p>See the examples below for more details.</p>
      </section>
    </section>
    
    <section id="resources">
      <title>Create the Necessary Resource Files</title>
      <fixme author="rdg">Discuss the XSL files and other such resources</fixme>
    </section>
    
    <section id="samples">
      <title>Create Samples in the Documentation</title>
      <p>Plugin documentation should provide (as a minimum) an
      index page that provides an overview and a set of samples that demonstrate
      the functionality of the plugin. Typically these samples will be
      provided in a <code>samples</code> subdirectory in the plugin 
      documentation and will be referenced from both <code>site.xml</code>
      and <code>tabs.xml</code> configuration files.</p>
      
      <p>Try to provide a sample for all the major functions of your plugin
      and document any configuration that is available.</p>
    </section>
    
    <section id="test">
      <title>Testing a Plugin</title>
      <p>Since your documentation for the plugin illustrates all of its 
      functionality, you can use that site for testing the plugin. However, you
      must first deploy in your local install of Forrest. Each plugin contains
      a buildfile that includes a <code>test</code> target. This target, by
      default, builds the documentation for your plugin.</p>
      
      <p class="instruction">Run the command <code>ant test</code> in
      the plugins directory.</p>
      
      <p>Of course, the build should complete without errors.</p>
      
      <note>You can also use <code>forrest run</code> to interactively examine
      your documentation (point your browser at 
      <a href="http://localhost:8888">http://localhost:8888</a>).</note>
      
      <p>It is also a really good idea to build proper tests for your 
      plugins using a suitable testing framework, for example, 
      <a href="http://webtest.canoo.com/">WebTest</a>. We recommend that you
      extend the <code>test</code> target in your plugins build file because
      this target is also used when performing integration tests on Forrest.
      In addition, we recommend that you use the samples in your documentation 
      for your tests, this way you are documenting your plugin at the same time 
      as writing your tests.</p>

      <p>Ensure that your sitemaps are robust and handle matches for files
      in sub-directories, as well as those at the root level.</p>
    </section>
    
    <section id="release">
      <title>Releasing a Plugin</title>
    
      <section id="register">
        <title>Register the Plugin with Apache Forrest</title>
        <fixme author="rdg">Describe the plugins.xml file</fixme>
        <fixme author="rdg">Describe making a request of Forrest devs for 
        inclusion</fixme>
      </section>
      
      <section id="deploy">
        <title>Deploying the Plugin</title>
        <p>To deploy the plugin so that others can use it, it must be made 
        available as a zip from the URL indicated in the 
        <code>plugins.xml</code> file. The plugins build file provides targets 
        to assist with this task.</p>
        
        <p class="instruction">To deploy a plugin simply run the command
        <code>ant deploy</code> from within the plugin directory.</p>
        
        <p>This command will, by default, deploy to the Apache Forrest web site.
        In order to do this you need commit access to Forrest. If you want to
        deploy your plugin to a different location you 
        can build the zip of your plugin with <code>ant dist</code>
        and then copy the zip file from <code>build/dist</code> to wherever
        you intend to host the plugin.</p>
        
        <note>Running this command on any plugin will also deploy any
        changes to the <code>plugins.xml</code> file. If you are deploying to
        your own website you will have to request changes to the 
        <code>plugins.xml</code> and ask the Forrest committers to publish the new
        document.</note>
        
        <warning>Running the <code>deploy</code> or <code>dist</code> targets
        will always run the <code>test</code> target first. This is to ensure
        that your only deploy working plugins. This adds a little time to
        the deploy cycle, but we feel the peace of mind is worth it.</warning>
        
      </section>
    </section>
    
    <section id="examples">
      <title>Examples</title>
      <p>This section will provide some example plugins to help illustrate the
      steps discussed above.</p>
        <section id="input">
          <title>Input Plugin</title>
          <fixme author="RDG">Discuss OpenOffice.org plugin here</fixme>
        </section>
        
        <section id="output">
          <title>Output Plugin</title>
          <fixme author="RDG">Discuss s5 plugin here</fixme>
        </section>
        
        <section id="internal">
          <title>Internal Plugin</title>
          <fixme author="RDG">Discuss IMSManifest plugin here</fixme>
        </section>
    </section>

    <section id="extension">
      <title>Further Reading</title>
      
      <ul>
        <li><a href="site:plugins/infrastructure">Plugin Infrastrucuture Documentation</a> for Developers</li>
        <li><a href="site:plugins">Plugins Documentation</a> for users</li>
      </ul>
    </section>

    <section id="summarise">
      <title>Summarise the Entire Process</title>

      <fixme author="rdg">In a few sentences, remind the reader what they have just learned.
      This helps to reinforce the main points of your How-To.</fixme>
    </section>
  </steps>
</howto>
