Template Context Item Plugin Module
Purpose of this Module Type
This module type allows you to put arbitrary context items into the context of any Using the Atlassian Template Renderer. This is useful to ensure plugin developers don't have to repeatedly create the same context each time they need to render content.
This module type is similar to the Confluence velocity-context-item module type. However, it is more powerful in the following ways:
- It can be used with any template rendering technology, not just velocity
- It allows items to be scoped in the context of the plugin that declares it, or to be in the global context of all plugins
- It allows referencing of arbitrary components, not just classes. This means you don't need to create wrapper classes if you want to put a general component (such as the SAL I18nResolver) in your context. It also means you can use Spring prototype beans if you want to use some per context stateful bean
The root element for the Template Context Items plugin module is
template-context-item. It allows the following attributes for configuration:
The key with which the context item is referenced from templates, e.g.
A reference to a component in the plugin's application context.
To reference OSGi services or host components, import the component using
The component will be looked up on each use, so prototype spring beans will be newly instantiated each time.
The class that should be instantiated and put into the context. This will be a singleton.
Note: either this or
True if the context item should be available to contexts for all plugins.
*context-key attribute is required.
Rendering templates for other plugins
When rendering templates for other plugins, you need to ensure your plugin gets the template renderer for the other plugins bundle. There are many ways to do this, and all involve getting a hold of the plugins
BundleContext. With the bundle context, you can lookup the
TemplateRenderer service, however, in most cases you won't want to do this directly, as you may encounter problems if the template renderer has not been enabled yet, or is restarted. It will usually be more appropriate to use a
ServiceTracker, and access the template renderer through that.
The following are the two best ways of getting a hold of the plugins
BundleContext, which will apply depending on your situation:
When you have a reference to the plugin's
This will be the case if you have defined a dynamic module type, from which you can access the plugins
Plugin object. In this case, you can access the
BundleContext like so:
When you expose a service that is imported by the plugin
In this case, you should expose an OSGi
ServiceFactory for your service. These work in the same way to Springs
FactoryBean's. Here's an example:
Once you have a
BundleContext, you need to create
ServiceTracker that tracks the
TemplateRenderer service in the plugins
Now you can use the service using the
getService(). The important thing that you need to worry about is handling if the service isn't available. Sometimes it may be appropriate to do no action, at other times, you may want to throw an exception:
Finally, it's important that you close the
ServiceTracker once you're finished using it. There are a number of reasons why this might happen:
- Your plugin might be brought down
- The plugin using you might be brought down
- The plugin using you might decide to unimport your service
Closing the service tracker should be done in your plugin module type descriptors disable method, or your
ServiceFactory's unget method. For example:
MyService you would then have a corresponding method that would call the
close() method on the service tracker.