Step 7 of 10 Creating HTML-free configuration UIs

Goal

Insert a UI element to modify a subject mapping.

With XNAT 1.7 there are new back-end and front-end libraries known collectively as The Spawner. The back-end Spawner service consumes YAML text files that define UI elements, resolves references to other elements, and returns JSON which is parsed by the front-end Spawner script and XNAT UI library to render the elements on the page.

Spawner file locations

There are currently two areas of XNAT where Spawner-based elements will be automatically inserted: site-level settings for site admins and project-level settings for project admins. By placing specially-named YAML files containing Spawner element definitions in specific locations in the XNAT web app, the defined elements will get picked up and automatically inserted into the UI.

Core XNAT Spawner files

In the XNAT source code, Spawner files are stored in the following directory:

  • src/main/resources/META-INF/xnat/spawner

The standard XNAT source contains a single file in this directory - site-admin-elements.yaml - which contains the elements required for rendering the main site administration page.

Plugin Spawner files

For plugins, you'll add a folder there with a name that matches your plugin's ID exactly (the value string in @XnatPlugin) - workshopPlugin in this case.

In that folder you'll add a file named site-settings.yaml for site-level admin settings, and a file named project-settings.yaml for project-level admin settings.

  • src/main/resources/META-INF/xnat/spawner/workshopPlugin/site-settings.yaml
  • src/main/resources/META-INF/xnat/spawner/workshopPlugin/project-settings.yaml

Required elements

There are a few required elements that are needed for your plugin's settings to be automatically rendered - a root element for the tabs container with the following properties:

  • kind: tabs (plural)
  • groups - map of group IDs with labels for your plugin's tabs - plugins should ideally contain just a single group
  • contents - contains child elements or references to child elements.

There also needs to be at least one tab element with the following properties:

  • kind: tab (singular)
  • label - text for the tab 'flipper'
  • group - the property name of the tab group for this tab
  • contents - the child elements (or references) that will render in the content area for this tab

Sample code

The code below is a sample of what this YAML would look like. YAML allows easy, human-friendly, creation and editing of objects. The property names shown are specific to XNAT and are used as input for the various JavaScript widget methods, which are specified in the 'kind' property.

(the code below shows a sample structure but may not be completely functional)

# the 'root' element is the main entry point for the element tree
root:
    # the root 'kind' property must be 'tabs' to inject into settings UIs
    kind: tabs
    groups:
        # create a custom tab group for your plugin
        subjectMappingTabs: Subject Mapping
    contents:
        ${subjectMappingTab}


subjectMappingTab:
    kind: tab
    # add your tab to the group defined above - REQUIRED for rendering
    group: subjectMappingTabs
    label: Subject Mapping Settings
    contents:
        ${subjectMappingTable}
        ${subjectMappingSettings}


# loads data from the specified url and displays results as a table
subjectMappingTable:
	kind: panel.dataTable
	name: subjectMapping
	label: "Subject Mappings"
    url: "/xapi/subjectmapping"

# inputs to create new mappings
subjectMappingSettings:
    kind: panel.form
    name: subjectMappingSettings
    label: "New Subject Mapping"
    method: POST
    contentType: json
    # set 'load' to false for submission-only forms
    load: false
    action: "/xapi/subjectmapping"
    contents:
		source:
			kind: panel.input.text
			name: source
			label: Source
		subjectId:
			kind: panel.input.text
			name: subjectId
			label: "Subject ID"
		recordId:
			kind: panel.input.text
			name: recordId
			label: "Record ID"

Completed!

You've added a spawner element to control your plugin's preference settings.

Go to the next step

$label.name