Skip to end of metadata
Go to start of metadata

XNAT Plugin Developers can add new templates, styles, and scripts to the XNAT UI. Developers can also overwrite existing Velocity templates in core XNAT. However, one plugin should not attempt to overwrite another plugin's templates or scripts. Since plugins are loaded without a specified order, plugins that attempt to overwrite each other – or that both attempt to overwrite the same core XNAT template files – will behave erratically.

Here is a guide on best practices for adding or customizing User Interface elements to XNAT through plugins.

As a best practice, and to avoid possible conflicts with JavaScript, CSS, and image files in other plugins, it's recommended that plugin-specific files be placed in subfolders named for your plugin, like:

  • /src/main/resources/META-INF/resources/scripts/{plugin-name}/your-script.js
  • /src/main/resources/META-INF/resources/images/{plugin-name}/your-image.png
  • /src/main/resources/META-INF/resources/style/{plugin-name}/your-stylesheet.css

UI File Locations in the Plugin Repo

File typeLocation in core xnat-web repoLocation in XNAT plugin repo
Velocity Templates: Screens

/src/main/webapp/base-templates/screens

/src/main/webapp/xdat-templates/screens

/src/main/webapp/xnat-templates/screens

/src/main/webapp/templates/screens

/src/main/resources/META-INF/resources/templates/screens
Scripts/src/main/webapp/scripts

/src/main/resources/META-INF/resources/scripts

Images/src/main/webapp/images/src/main/resources/META-INF/resources/images
CSS Styles/src/main/webapp/style/src/main/resources/META-INF/resources/style

Adding new dependencies to the HTML <head>

The HeaderIncludes.vm template file in core XNAT contains the following Velocity macro:

#addGlobalCustomScreens("header")

This means that any .vm file placed inside the /src/main/resources/META-INF/resources/templates/screens/header directory will be parsed in the HTML head.

For example, to add the jQuery UI tools, you could place the following Javascript and CSS dependencies into a new vm file at /src/main/resources/META-INF/resources/templates/screens/header/plugin-name-jQueryUI.vm in your plugin directory:

<!-- imports jQuery UI javascript and base CSS theme -->
<script type="text/javascript" src="https://code.jquery.com/ui/1.12.1/jquery-ui.js" async></script>
<link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
These dependencies will now be available on any page in XNAT.

Adding a Menu Item to the Top Nav


The DefaultTop.vm navigation template file in core XNAT contains the following Velocity macro:

#addGlobalCustomScreens("topBar")

This means that any .vm file or set of folders placed inside the /src/main/resources/META-INF/resources/templates/screens/topBar directory will be parsed into the top navigation for any page using the DefaultTop navigation. (By default, every page that logged-in users see within XNAT should be using this navigation.)

In the core xnat-web repo, you can see the following VM files in this directory:

Each VM file, such as Administer.vm, contains a menu item and a second Velocity macro to parse the contents of its related subdirectory, like so:

<li><a href="#adminbox">Administer</a>
    <ul>
        #addGlobalCustomScreens("topBar/Administer")
    </ul>
</li>
This means that you can add a new menu item to the Administer menu by placing a new .vm file in the /src/main/resources/META-INF/resources/templates/screens/topBar/Administer folder in your plugin repo, and that new menu item will display for logged-in site admins. 


Adding an Actions Menu Item to a report page

The Actions Menu HTML in XNAT 1.7 and earlier is formatted to work with YUI 2 code.


There are two methods you can use to add an Action to a given report page – through the Data Type Administration UI, which must be done by an XNAT administrator, or in the code through crafty placement of Velocity files. The latter is preferred if you want to hard-code the presence of an action.

In core XNAT, the Actions menu in the Project page is nearly entirely hard-coded. You can find the following files in /xnat-templates/screens:

The folder name "xnat_projectData" is a URL-friendly conversion of the xsiType "xnat:projectData". If you are modifying the actions box for a custom data type, your root folder should be named just like your xsiType, with an underscore in place of the colon.

Each .vm file in this subdirectory contains a list item that gets parsed as an Actions menu item, such as DownloadImages.vm:

<li class="yuimenuitem">
 <a class="yuimenuitemlabel" href="$link.setAction("ProjectDownloadAction").addPathInfo('project',$project.getId())">Download Images</A>
</li>
You can place your own menu item – or a menu containing multiple items – into a Velocity file in your plugin in the appropriate directory: /src/main/resources/META-INF/resources/templates/screens/{xnat_xsiType}/actionsBox

Displaying user interface extension points

Each of the customizations described above uses one of XNAT's UI extension points. XNAT provides many of these extension points throughout its user interface. You can configure XNAT to display these extension points by setting the uiDebugExtensionPoints site configuration property to true. This requires a call to the XNAT REST API:

Turning on debug mode for UI extension points
$ curl -u admin:admin -X POST -H "Content-Type: text/plain" --data "true" https://xnat.miskatonic.edu/xapi/siteConfig/uiDebugExtensionPoints

Use the same REST call with "false" to turn debug extension point display off.

When the UI extension point display is turned on, it's turned on for all users currently using XNAT. It's intended for development purposes and shouldn't be turned on for production deployments unless absolutely necessary.

The screen shot below shows XNAT with debug extension points displayed, with a file placed in the path templates/screens/xnat_projectData/report/preData/project_resources.vm that displays a simple message.

 

Creating new report and edit screens for your data type

See: XNAT Data Type Development.