Skip to end of metadata
Go to start of metadata
You are viewing documentation of TeamCity 6.5.x, which is not the most recent released version of TeamCity. Please refer to the listing to choose another version.

Table of Contents

This section covers:


Hint: you can use source code of the existing plugins as a reference, for example:

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:

  1. Choose an extension point.
  2. Implement interface jetbrains.buildServer.web.openapi.PageExtension (or you can use/extend jetbrains.buildServer.web.openapi.SimplePageExtension class).
  3. Attach the implemented interface to a chosen extension point (ask Spring to provide you jetbrains.buildServer.web.openapi.PagePlaces interface):

The jetbrains.buildServer.web.openapi.PageExtension interface has the following important methods that require your attention:

  • getIncludeUrl is a mandatory method. You must specify its includeUrl parameter — an URL that is used to retrieve your extension content. This URL must point to a JSP file or to a custom controller.
  • 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.SimplePageExtension class requires jetbrains.buildServer.web.openapi.PagePlaces interface as parameter, plus jetbrains.buildServer.web.openapi.PlaceId 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.CustomTab 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 page extensions:

  • 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 page extensions.

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:

To simplify things your controller can extend our jetbrains.buildServer.controllers.BaseController 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 page extensions.

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.PluginDescriptor. 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">

Note: <c:url/> is required to construct correct URL in case if TeamCity is deployed under the non root context.

Classes and interfaces from TeamCity web open API

Class / Interface



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