Web UI Extensions
Developing a Page Extension
In TeamCity page extension is a plugin written for a specific extension point and extending existing web page functionality. In most cases page extensions only provide some additional information and a simple UI that does not require communication with the server.
TeamCity contains a number of pages that can be extended in such a way. These pages provide one or more extension points which are contained in the PlaceId class. There are also two special extension points ALL_PAGES_HEADER
and ALL_PAGES_FOOTER
. These extension points allow you to insert your plugin content on every page (except external pages not requiring authentication like login) in the header and/or footer.
To write a page extension:
Choose an extension point.
Implement interface
jetbrains.buildServer.web.openapi.PageExtension4.5.1
(or you can use/extendjetbrains.buildServer.web.openapi.SimplePageExtension4.5.1
class).Attach the implemented interface to a chosen extension point (ask Spring to provide you
jetbrains.buildServer.web.openapi.PagePlaces4.5.1
interface):pagePlaces.getPlaceById(PlaceId.SOME_EXTENSION_POINT).addPageExtension(myExtension)
The jetbrains.buildServer.web.openapi.PageExtension4.5.1
interface has the following important methods that require your attention:
getIncludeUrl
is a mandatory method. You must specify itsincludeUrl
parameter — an URL that is used to retrieve your extension content. This URL must point to a JSP file or to a DevelopCustomController.isAvailable(HttpServletRequest)
method is called to determine whether page extension content should be shown or not.fillModel(Map, HttpServletRequest)
method is required when you want to pass some parameters to your JSP. The method will be called before actual JSP is shown and a map of parameters will be passed to it. You can add parameters to this map and then in JSP you will be able to retrieve them by their names from the request scope.
jetbrains.buildServer.web.openapi.SimplePageExtension4.5.1
class requires jetbrains.buildServer.web.openapi.PagePlaces4.5.1
interface as parameter, plus jetbrains.buildServer.web.openapi.PlaceId4.5.1
specification. Given that PlaceId
is specified, you can call method register()
to register this extension. You can also use SimplePageExtension
class to specify your extension in Spring xml descriptor, because it has setters for all main parameters.
Developing a Custom Tab
A number of extension points in TeamCity are custom tab extensions. For example, PlaceId.BUILD_RESULTS_TAB
identifies custom tab on build results page.
To add your own tab you can extend SimplePageExtension
and additionally implement jetbrains.buildServer.web.openapi.CustomTab4.5.1
interface with two new methods:
CustomTab.getTabId()
returns unique identifier of the tab among all of the tabs in this extension point.CustomTab.getTabTitle()
returns title to show in the tab.
Processing of custom tabs has some differences from usual DevelopPageExtention:
If
jetbrains.buildServer.web.openapi.PageExtensionisAvailable(javax.servlet.http.HttpServletRequest)4.5.1
method returns false then tab will not be shown and user will not be able to switch to it. So if your tab should always be visible return true in this method.
PageExtension.fillModel(Map, HttpServletRequest)
method is called only if the tab is selected by the user.
In all other respects custom tabs are processed as usual DevelopPageExtention.
Developing a Custom Controller
Sometimes page extensions provide interaction with user and require communication with server. For example, your page extension can show a form with a "Submit" button. In this case in addition to writing your own page extension, you should provide a controller which will process requests from such forms, and use path to this controller in the form action attribute (the path is a part of URL without context path and query string).
To register your controller:
use
jetbrains.buildServer.web.openapi.WebControllerManagerregisterController(java.lang.String, org.springframework.web.servlet.mvc.Controller)4.5.1
method with the following arguments:First argument of this method (String) is a path to which the controller will be bound. The path must end with ".html" suffix, for example:
/myplugin/mycontroller.html
.Second argument (Controller) is the controller itself.
To simplify things your controller can extend our jetbrains.buildServer.controllers.BaseController4.5.1
class and implement BaseController.doHandle(HttpServletRequest, HttpServletResponse)
method.
With the custom controller you can provide completely new pages. Links to such pages you can add by means of DevelopPageExtention.
Obtaining paths to JSP files
Plugin resources are unpacked to <TeamCity web application>/plugins
directory when server starts. However to construct paths to your JSP or images in Java it is recommended to use jetbrains.buildServer.web.openapi.PluginDescriptor4.5.1
. This descriptor can be obtained as any other Spring service.
In JSP files to construct paths to your resources you can use ${teamcityPluginResourcesPath}. This attribute is provided by TeamCity automatically, you can use it like this:
<img src="${teamcityPluginResourcesPath}your_image.gif" height="16" width="16" border="0">
Classes and interfaces from TeamCity web open API
Class / Interface | Description |
---|---|
| A list of page place identifiers / extension points |
| A single page place associated with PlaceId, allows to add / remove extensions |
| Page extension interface |
| Base class for page extensions |
| Custom tab extension interface |
| Maintains a collection of page places and allows to locate PagePlace by PlaceId |
| Maintains a collection of custom controllers, allows to register custom controllers |
| Base class for controllers |