Overview
Below are a list of customizations you can make via this plugin architecture. Each plugin will require an entry in the plugins.properties file. This should be located in the working directory of FitNesse. If the file does not exist FitNesse will run normally. To enable a plugin, create this file, and add the specified entries. All plugins will require complied Java code so make sure that the classpath contains an entry to locate your plugins.Wiki Page
required property: WikiPage = <class name>motivation: By default, wiki pages are stored as files on a file system (using the FileSystemWikiPage class). Providing a custom wiki page plugin allows pages to be stored using other means such as a database. Alternatively, FileSystemWikiPage can be extended to provide custom behavior when pages are create, saved, deleted, etc.
The class specified must implement the fitnesse.wiki.WikiPage interface. It must provide a public constructor of the form:public MyWikiPage(String rootPath, String rootPageName, ComponentFactory componentFactory) The rootPath parameter is the path to the root page (by default, "."). The rootPageName parameter is the name of the root wiki page (by default, "FitNesseRoot"). The ComponentFactory parameter can be used to locate other loaded components and properties entries in plugins.properties.
Html Page Factory
required property: HtmlPageFactory = <class name>motivation: Full customization of look and feel.
The class specified must extend the fitnesse.html.HtmlPageFactory class and it must also provide a constructor that accept a Properties object. The custom HtmlPageFactory will over ride the newPage() method to return a derivative of fitnesse.html.HtmlPage. The custom HtmlPage class should make use of any of the public HtmlTag member variables.
Responders
required property: Responders = <key:classname>[,<key:classname>]motivation: Allows functional customization. With this plugin you can customize the way FitNesse responds to HTTP requests.
The property provided should be a comma separated list of key:value pairs, where value is the name of a class that implements fitnesse.Responder. The key is used in the URL to designate which responder to invoke. An example responder plugin might be an RssResponder that would generate RSS feeds for wiki page updates. To do this you would first create the RssResponder to gerenate the RSS. Then add the plugin property Responders=rss:your.package.RssResponder. Then to invoke it you would use a URL like http://fitnesse.org/RecentChanges?responder=rss to get a feed on all the changes made to the .RecentChanges page.
Authenticator
required property: Authenticator = <class name>motivation: Custom security scheme. The class provided must extend the fitnesse.authentication.Authenticator class. The class will be instantiated and asked isAuthenticated(String username, String password) when ever authentication is required. See SecurityDescription for more information on security.
Symbol Types
required property: SymbolTypes = <class name>[,<class name]motivation: Custom look-n-feel, or custom functionality hook.
The plug-in class must extend fitnesse.wikitext.SymbolType. A plug-in class can specify up to four pieces of information for the parser.
The first is a name, specified in the super constructor. The name is just used for error reporting and debugging and so it can be any descriptive string.
The second is the wikiMatcher. This is an object that knows how to identify the symbol type in the source string. The Matcher class provides a lot of common matching behavior, so you can look at the Matcher source to find matching behavior.
The third is the wikiRule, which not all symbol types require. This is an object that implements a grammar production rule if our symbol type is composed of other symbol types (a non-terminal, in grammar-speak). A symbol type that is a terminal doesn't need a production rule. Look at the fitnesse.wikitext.parser package to see examples of how production rule classes are written.
The fourth is the htmlTranslation. This is an object that renders the symbol type as a string in the HTML output. We can implement the Translation interface and specify this as our translation object. The toTarget method renders our output.
Example:
public class PiSymbolType extends SymbolType implements Translation {
public PiSymbolType () {
super("Pi");
wikiMatcher(new Matcher().string("!pi"));
htmlTranslation(this);
}
public String toTarget(Translator translator, Symbol symbol) {
return Double.toString(Math.PI);
}
}
Content Filter
required property: ContentFilter = <class name>motivation: Restrict the content that is saved on wiki pages. (Damn spammers!)
The classes supplied must extend fitnesse.responders.editing.ContentFilter. ContentFilter is an interface that declares one method: boolean isContentAcceptable(String content, String pageName). When ever user attempts to save a page, isContentAcceptable() is invoked and the content is saved only if true is returned.
Slim Tables
required property: SlimTables = <class name>motivation: Allow for custom SLiM table types to be supported.
There may be certain (rare) situations where the default table types are not sufficient. This hook allows for custom SLiM table types. A custom table must extend fitnesse.slimTables.
Plugins
required property: Plugins = <class name>[,<class name>]motivation: Register multiple Responders, WikiWidgets, and WikiPage components in a single Java class, instead of multiple entries in plugins.properties.
Plugins classes can provide one or more of the following methods to register components:
* registerResponders(ResponderFactory responderFactory) - register responders using ResponderFactory.addResponder(String key, Class responderClass)
* registerWikiWidgets(WidgetBuilder widgetBuilder) - register wiki widgets using WidgetBuilder.addWidgetClass(Class widgetClass)
* registerWikiPage(WikiPageFactory wikiPageFactory) - override the default wiki page implementation using WikiPageFactory.setWikiPageClass(Class wikiPageClass)