Confluence 2.5.6 : UPT 3.2 - Using Inline Decorators
This page last changed on Aug 04, 2006 by cmiller.
This is the part of the tutorial with the most voodoo, at least so far. It involves changing the edituserinfo.vm file so that it will invoke the correct decorator, which in turn will make the plugin look like it is an integrated part of the Confluence UI. While following the instructions in this page will give you a general idea of what I'm accomplishing, some of the decisions I make, like which decorator to call and which action class to extend, are only applicable to this particular plugin. The best way to find out what's right for your plugin, if you're not familiar enough with the Confluence codebase to find out for yourself, is to ask on the developer mailing list. This tutorial should at least give you a good idea what questions you need to ask. Inline DecoratorsConfluence makes heavy use of the Sitemesh library to lay out pages. Sitemesh works by decorating content. The main decorator, main.vmd is applied to each page automatically. You can see this by looking at the results of part 2 of the tutorial. Despite the fact that edituserinfo.vm does not contain any of the code for the search bar, top bar or profile links, they're included on the resulting page. The decorators that are used to build the tab panels and other themeable parts of the Confluence page are invoked manually as inline decorators. In order to make the plugin a part of the profile tab infrastructure, I modify the vm file like this (The full velocity file is [attached|^edituserinfo.vm], this is just the important bit we're adding): #applyDecorator("root") #decoratorParam("context" "profile") #decoratorParam("mode" "edit-profile") #decoratorParam("helper" $action.helper) #decoratorParam("infopanel-width" "200px") <!-- the stuff we want decorated --> #end
Modifying the ActionEach inline decorator makes certain assumptions about the action class that it is a result of. For example, when drawing the HTML for the profile context, the decorator assumes the existence of a getUser() method on the action. The easiest way to ensure that I have all the right methods for the decorator is to find the abstract class that all of the stock Confluence actions that use that decorator extends. In the case of the profile, this is com.atlassian.confluence.user.actions.AbstractUserProfileAction. By modifying my EditUserInfoAction so that it extends AbstractUserProfileAction, the decorator will be able to render successfully. public class EditUserInfoAction extends AbstractUserProfileAction { // ... } |
![]() |
Document generated by Confluence on Oct 10, 2007 18:36 |