This documentation relates to the latest version of Confluence.
If you are using an earlier version, please go to the documentation home page and select the relevant version.

XWork-WebWork Plugins

All Versions
Click for all versions
Confluence 2.9 Documentation

Index

XWork plugin modules are available in Confluence 1.4 and later.

XWork plugin modules enable you to deploy XWork / WebWork actions and views as a part of your plugins.

The XWork Plugin Module

Each XWork module is deployed as a plugin module of type xwork and contains one of more XWork package elements.

Here is an example atlassian-plugin.xml file containing a single XWork module:

<atlassian-plugin name='List Search Macros' key='confluence.extra.livesearch'>
    ...

    <xwork name="livesearchaction" key="livesearchaction">
        <package name="livesearch" extends="default" namespace="/plugins/livesearch">
            <default-interceptor-ref name="defaultStack" />

            <action name="livesearch" 
                class="com.atlassian.confluence.extra.livesearch.LiveSearchAction">
                <result name="success" type="velocity">
                /templates/extra/livesearch/livesearchaction.vm
                </result>
            </action>
        </package>
    </xwork>
</atlassian-plugin>
  • the xwork element has no class attribute.
  • beneath this element, multiple package elements can be specified. These are standard XWork package elements, just as you would specify in xwork.xml.

Writing an Action

For information on how to write a WebWork action, please consult the WebWork documentation.

WebWork actions must implement com.opensymphony.xwork.Action. However, we recommend you make your action extend ConfluenceActionSupport, which provides a number of helper methods and components that are useful when writing an Action that works within Confluence.

Other action base-classes can be found within Confluence, but we recommend you don't use them - the hierarchy of action classes in Confluence is over-complicated, and likely to be simplified in the future in a way that will break your plugins.

Accessing Your Actions

Actions are added to the XWork core configuration within Confluence, which means they are accessed like any other action!

For example, given the above atlassian-plugin.xml, the livesearch action would be accessed at http://yourserver/confluence/plugins/livesearch/livesearch.action.

Notes

Some issues to be aware of when developing or configuring an XWork plugin:

  • Your packages should almost always extend the default Confluence package. It is useful to be aware of what this provides to you in the way of interceptors and result types.
  • You can give your packages any namespace you like, but we recommend using /plugins/unique/value - that is prefixing plugin packages with /plugins and then adding a string globally unique to your plugin. The only name you can't use is servlet as the /plugins/servlet URL pattern is reserved for Servlet Plugins.
  • Views must be bundled in the JAR file in order to be used by your actions. This almost always means using Velocity views.
  • It is useful to be aware of the actions and features already bundled with Confluence, for example your actions will all be auto-wired by Spring (see Accessing Confluence Components From Plugin Modules) and your actions can use useful interfaces like PageAware and SpaceAware to reduce the amount of work they need to do.

Example

The LiveSearch example is a neat example of an Ajax-style Confluence plugin which uses a bundled XWork module to do it's work:

Find this example in the /plugins/macros/livesearch directory within your Confluence distribution.

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Nov 02, 2005

    Avinash Sharma says:

    Is there a way to modify the livesearch macro so that it only searches in a cert...

    Is there a way to modify the livesearch macro so that it only searches in a certain space?

    thanks in advance

    1. Nov 03, 2005

      Daniel Ostermeier says:

      At this point, not without making modifications to the livesearch macro itself. ...

      At this point, not without making modifications to the livesearch macro itself. If you would like to see this feature, please raise a feature request via http://jira.atlassian.com

      Regards,
      -Daniel

    2. Apr 12, 2006

      Jens Schumacher says:

      Since Confluence 2.1 you can specify a spaceKey parameter. For example: {livese...

      Since Confluence 2.1 you can specify a spaceKey parameter. For example:

      {livesearch:spaceKey=ds}

      will list only pages from the Demonstration Space

      Cheers,
      Jens

  2. Mar 17, 2006

    Andrew Miller says:

    There's actually a bug for that here.... http://jira.atlassian.com/browse/CONF-...

    There's actually a bug for that here....

    http://jira.atlassian.com/browse/CONF-4546

    but it doesn't seem to be working in 2.1.4 as indicated there.

  3. May 02, 2006

    vincent chen says:

    I'm creating a plugin. the XWork part is not working properly. The following is ...

    I'm creating a plugin. the XWork part is not working properly. The following is part of plugin.xml file.

    <package name="news" extends="default" namespace="/plugins/news">
                <default-interceptor-ref name="defaultStack" />
    <action name="/plugins/news/preview" class="com.icsynergy.confluence.news.NewsAction" method="preview">
                <result name="preview" type="velocity">
                	/plugins/news/templates/preview.vm
                </result>
    </action>
    </package>
    

    The problem happens when to forward to the preview result. I got the following exception:

    org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource '/ /plugins/news /plugins/news/templates/preview.vm '

    Can anyone give me some idea? Thanks

    1. May 02, 2006

      Dan Hardiker says:

      Few comments: Namespacing You have specified the /plugins/news namespace, and s...

      Few comments:

      Namespacing
      You have specified the /plugins/news namespace, and still prepended the namespace to the action name ... this would mean the action is at http://confluence.atlassian.com/plugins/news/plugins/news/preview.action ... I assume you want http://confluence.atlassian.com/plugins/news/preview.action, so just remove plugins/news/ from the begining of the action element's name attribute.

      Whitespace
      I would remove the whitespace around the result contents and have <result...>/plugin/news/templates/preview.vm</result> instead.

      VM Location
      Finally, check that the preview.vm file is in the "plugins/news/templates" folder in your jar (simply open the jar in any zip viewer). If it isnt there then adjust the deployment path or your location in the result body.

  4. May 02, 2006

    vincent chen says:

    Thanks, Dan. After removed white space and changed the action name, it works. My...

    Thanks, Dan. After removed white space and changed the action name, it works.
    My action config now is:

    <package name="news" extends="default" namespace="/plugins/news">
                <default-interceptor-ref name="defaultStack" />
    
                <action name="newsEdit" class="com.icsynergy.confluence.news.NewsAction">
                <result name="success" type="httpheader">
                       <param name="status">204</param>
                </result>
                <result name="preview" type="velocity">templates/preview.vm</result>
    </package>
    

    While, in the sample plugin dynamictasklist, the action config is:

        <xwork name="tasklistaction" key="tasklistaction">
            <package name="dynamictasklist" extends="default" namespace="/plugins/dynamictasklist">
                <default-interceptor-ref name="defaultStack" />
    ......
                <action name="addTask" class="com.atlassian.confluence.extra.dynamictasklist.TaskListAction" method="addTask">
                     <result name="success" type="velocity">/templates/extra/dynamictasklist/status.vm</result>
                </action>
    

    In my case, the actual action URL is built by ActionNameSpace+ResultURL, while in dynamictasklist plugin it is ResultURL. Why is it diffrent?

    1. May 02, 2006

      David Peterson [CustomWare] says:

      In dynamictasklist the .vm file path starts with '/'. That is a signal for the X...

      In dynamictasklist the .vm file path starts with '/'. That is a signal for the XWork engine to start from the top of the webapp's (in this case Confluence's) context path. If you want the same result, just add '/' to the start of your result URL.

      1. May 03, 2006

        vincent chen says:

        The problem might be the white space? It seems that the result entry should not ...

        The problem might be the white space? It seems that the result entry should not have any whitespace if the result type is velocity. If the first character is not "/", then XWork will prefix the namespace string to the result URL.

  5. Oct 23, 2006

    Menso Heus says:

    The livesearch plugin doesn't seem to work for me anymore after upgrading from 2...

    The livesearch plugin doesn't seem to work for me anymore after upgrading from 2.1.5 to 2.2.9. Very sad, because me and my colleagues love it

     I'm not a java expert but this does pop up in the logs:

    2006-10-23 21:47:59,920 ERROR [getaheadplugin.dwr.impl.SignatureParser] error Parameter mismatch parsing signatures section in dwr.xml on line:
    +SearchDWR.doSearch(List<String>, List<String>, Map<String,String>, List<String>, int)
    2006-10-23 21:48:10,796 WARN [getaheadplugin.dwr.impl.DefaultConverterManager] warn Missing type info for doSearch(0<0>). Assuming this is a map with String
    +keys. Please add to <signatures> in dwr.xml
    2006-10-23 21:48:10,821 WARN [getaheadplugin.dwr.impl.DefaultConverterManager] warn Missing type info for doSearch(1<0>). Assuming this is a map with String
    +keys. Please add to <signatures> in dwr.xml
    2006-10-23 21:48:10,822 WARN [getaheadplugin.dwr.impl.DefaultConverterManager] warn Missing type info for doSearch(2<0>). Assuming this is a map with String
    +keys. Please add to <signatures> in dwr.xml
    2006-10-23 21:48:10,823 WARN [getaheadplugin.dwr.impl.DefaultConverterManager] warn Missing type info for doSearch(2<1>). Assuming this is a map with String
    +keys. Please add to <signatures> in dwr.xml
    2006-10-23 21:48:10,824 WARN [getaheadplugin.dwr.impl.DefaultConverterManager] warn Missing type info for doSearch(3<0>). Assuming this is a map with String
    +keys. Please add to <signatures> in dwr.xml
    2006-10-23 21:48:10,825 WARN [getaheadplugin.dwr.impl.DefaultConverterManager] warn Missing type info for doSearch(4<0>). Assuming this is a map with String
    +keys. Please add to <signatures> in dwr.xml
    

    If anyone can advise me on how to fix this, please let me know!

    1. Oct 26, 2006

      David Loeng says:

      Hi Menso, Where did you download your livesearch plugin from? I checked the ...

      Hi Menso,

      Where did you download your livesearch plugin from?

      I checked the latest source for the livesearch plugin within Confluence source code and it is not using DWR for its AJAX requests.

      Can you provide us with the livesearch plugin jar you are using?

      Please put your reply in a support request at http://support.atlassian.com and we'll handle it there.

      Cheers,
      Dave

    2. Oct 27, 2006

      Dan Hardiker says:

      Those messages are generated by the Advanced Search plugin - and can be ignored ...

      Those messages are generated by the Advanced Search plugin - and can be ignored as the assumptions it makes are correct. In a later release a <signatures> section may be added to the dwr xml.

      This would not stop the livesearch plugin from working.

  6. Nov 03, 2006

    Matt Zukowski says:

    The LiveSearchAction plugin is kind of useless as an example, since most of the ...

    The LiveSearchAction plugin is kind of useless as an example, since most of the implementation is actually done in SiteSearchAction (the source code for which is not availalbe in the examples directory). Is there something else I can look at as an example of how to implement an Action?

    1. Nov 22, 2006

      Matt Ryall says:

      If you mean "how to implement an Action class", that's really easy. A Confluence...

      If you mean "how to implement an Action class", that's really easy. A Confluence action has three characteristics:

      1. It extends com.atlassian.confluence.core.ConfluenceActionSupport.
      2. It has an execute() method that returns a result String. The method gets called when the action URL gets a request, and the result String is matched against the results in atlassian-plugin.xml to forward to a Velocity template. Predefined results are constants in ActionSupport - SUCCESS, ERROR, INPUT, etc.
      3. It has setFoo() methods called by Spring to inject dependencies and by Webwork to set query parameters, and getBar() methods called by Velocity when you write "$action.bar".

      An extremely short example looks like this:

      public class TestAction extends ConfluenceActionSupport
      {
          private PageManager pageManager;
          private long pageId;
      
          public String execute() {
              return SUCCESS;
          }
          
          public String getPageCreator() {
              return pageManager.getPage(pageId).getCreatorName();
          }
      
          public void setPageManager(PageManager pageManager) {
              this.pageManager = pageManager;
          }
      
          public void setPageId(long pageId) {
              this.pageId = pageId;
          }
      }
      

      Accessing this action via test.action?pageId=12345 will run the execute() method, forward to the Velocity template mapped to the 'success' result, and allow you to write $action.pageCreator in Velocity to retrieve the page creator for the page with the given pageId.

      There are hundreds of actions in the Confluence source code, if you want to see more complicated examples. The mapping from Actions to Velocity in Confluence is done via the xwork.xml file.

      1. Aug 07

        Anonymous says:

        when I call the action I know how to call test.action, but how to I get the extr...

        when I call the action I know how to call test.action, but how to I get the extra ?pageId=12345appended to the action from the VM file

  7. Aug 02, 2007

    Peter Chapman says:

    I want to add a Action-conversion.properties file for my action.  Where do ...

    I want to add a Action-conversion.properties file for my action.  Where do I put this file and what kind of configuration do I need to do in either the plugin config file or the pom file?

    1. Aug 03, 2007

      Tony Cheah Tong Nyee says:

      Hi Peter, Could you please clarify further on what you are trying to achieve? ...

      Hi Peter,

      Could you please clarify further on what you are trying to achieve?

      Cheers,
      Tony

    2. May 25

      Stefan Kleineikenscheidt says:

      Hi Peter, I also tried this, and here is the result of my analysis: I think th...

      Hi Peter,

      I also tried this, and here is the result of my analysis:

      I think this is not possible, if you want to use the plugin deployment, as XWork will try to load your conversion class using the WebappClassLoader, which will not find the class within your plugin JAR. (I got {{ClassNotFoundException}}s)

      However, it should work if you install your plugin in WEB-INF/lib. In this case MyAction-conversion.properties should be in the same directory as MyAction.class.

      @Tony: The conversion.properties files are used to set complex properties on the action class as described here: http://wiki.opensymphony.com/display/WW/Type+Conversion

      Or does anybody know workarounds for this??

      Cheers,
      -Stefan

  8. Oct 29, 2007

    john jimenez says:

    Can you overwrite the values in xworks.xml with values in a plugin?  For ex...

    Can you overwrite the values in xworks.xml with values in a plugin?  For example is there a way to do this?
    <atlassian-plugin name='List Search Macros' key='confluence.extra.livesearch'>
    ...

    <xwork name="my.login" key="my.login">
    <package name="my.login" extends="default"> <!-- no namespace should mean "/" -->

    <default-interceptor-ref name="defaultStack" />

    <action name="livesearch" class="com.atlassian.confluence.user.actions.LoginAction">
    <result name="success" type="velocity">/my/login-with-my-custom-stuff-in-here.vm</result>
    <result name="error" type="velocity">/my/login-error.vm</result>
    </action>

    </package>
    </xwork>
    </atlassian-plugin>

    I may also want to create my own custom actions that forward to custom vm files that overload base confluence actions (through a plugin). 

    1. Oct 29, 2007

      Roberto Dominguez says:

      Yeah, you can do that but you have to define the same extends and namespace. Wh...

      Yeah, you can do that but you have to define the same extends and namespace.

      When overloading the base confluence action make sure you implement the appropriate interfaces if you want reproduce the very same behaviour:

      i.e.:

      public class MyPageAction extends WhateverConfluencesPageAction implements PageAware {
      ...
      }
      

      That said, overload the actions only if is absofreakinglutly necessary... it can get messy if you want to interact with other plugins that might want do the same...

    2. Oct 30, 2007

      Mei Yan Chan says:

      Hi John, I presume that you would like to use the methods and attributes for sp...

      Hi John,

      I presume that you would like to use the methods and attributes for specific class in the xwork.xml. In order to do so, you require to override (extends) the necessary class.

      Alternatively,I would advice you to direct your questions to our forum and mailing list as there might be other user/developers who have already implemented it and should be able to share their ideas with you.

      Regards,
      Mei

  9. May 22

    Anonymous says:

    Hi, I have been asked to implement a label aggregation component for confluence...

    Hi,

    I have been asked to implement a label aggregation component for confluence. When a user clicks on a label, this usually points to a default page (/label/theLabel). I need to be able to override that landing page with something of my own. Should I be looking into webworks/XWorks to achieve this? Any help here would be very welcome.

     -Kevin

    1. May 22

      Shannon Krebs - Adaptavist says:

      You might be better asking questions like this on the developer list/forum. You...

      You might be better asking questions like this on the developer list/forum.

      You will want to create an xwork action for your new page, unfortunately there is no easy way to override the default actions in confluence from a plugin. (It can be done if you want to edit the confluence source, but this will make updating very painful). Have a look at Dave Peterson's conveyor library which might be of some assistance.

      http://www.customware.net/repository/display/AtlassianPlugins/Confluence+Conveyor+Library

Add Comment