Basic guide to Jelly usage in Hudson

From Eclipsepedia

Jump to: navigation, search

If you are unfamiliar with Jelly and Hudson's use of it, you may find it difficult to create configurable parameters for your plugin. This page describes some very simple examples to get you started. Objects with Descriptors

For objects with Descriptor (such as Publisher), the general steps are as follows:

  1. Define an immutable class that takes all the configuration parameters as constructor parameters. Put @DataBoundConstructor on this constructor, which tells Hudson how to instantiate it.
  2. Define getters for the configuration fields, or make the fields "public final". This allows Jelly script to read the values to populate the configuration page.
  3. Write a Jelly fragment (normally named config.jelly but see javadoc of your base class) and list all the configuration options. The most basic form of this is something like the following. The value of @field is used as a property name (so you need to either have the getPort method or a public port field) as well as the constructor parameter name.
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">
  <f:entry title="${%Port}" field="port">
    <f:textbox />
  </f:entry>
  <f:entry title="${%Host}" field="host">
    <f:textbox />
  </f:entry>
</j:jelly>

Contents

Help files

If your class has help-FIELD.html or help-FIELD.jelly, Hudson will add the Help 16.gif icon and render your help inline. You can add top-level plugin help, e.g. on the job configuration page, by providing help.html or help.jelly in the src/main/resources/path/to/plugin/PluginName directory.

Form validation

You can write doCheckFIELD method on your descriptor to add the form validation logic. Your check method would look something like this:

public FormValidation doCheckPort(@QueryParameter String value) {
  if(looksOk(value))  return FormValidation.ok();
  else                return FormValidation.error("There's a problem here");
}

You can also define additional parameters with @QueryParameter to obtain values from other nearby form fields of the specified names. This is useful if your validation depends on values on the other form fields.

Refer to stapler documentation for more details.

Default value

If you want the configuration page to have the initial default value, use @default. The first example shows the literal default value, while the second example shows the programmatically computed default value:

<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">
  <f:entry title="${%Port}" field="port">
    <f:textbox default="80" />
  </f:entry>
  <f:entry title="${%Host}" field="host">
    <f:textbox default="${descriptor.defaultHost()}/>
  </f:entry>
</j:jelly>

Other jelly variables

When using the field= mechanism shown above you see where the data really comes from. Hudson defines these variables which you may use as needed: descriptor and instance, which are the instance of your Descriptor class and instance of the class it describes, respectively (both are available in config.jelly, just descriptor in global.jelly). Objects without Descriptors

If your plugin uses an object without a Descriptor, such as ComputerListener, follow these steps to include a single text box in the configuration page that will be readable within your plugin class (the one that extends Plugin).

  1. Override the configure(StaplerRequest req, JSONObject formData) method in your plugin class. This method will be called when the user clicks the Save button in the configuration page.
  2. In your configure method, use a method like optInt to extract the value you would like the user to configure. For instance, formData.optInt("port", 3141) will get a port number if the user enters it, or the value 3141 if the user leaves it blank. Store the extracted value in a member of the plugin class.
  3. In your configure method, call save(). This will save the serializable fields of your plugin class.
  4. In the start method of your plugin class, call load(), which will reload these fields from persistent storage on startup.
  5. Create a file called config.jelly with content like this:
    <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout"
             xmlns:t="/lib/hudson" xmlns:f="/lib/form">
      <f:section title="My Plugin">
        <f:entry title="${%Port}" help="/plugin/ARTIFACT_ID_GOES_HERE/help-projectConfig.html">
          <f:textbox name="port" value="${it.port}"/>
        </f:entry>
      </f:section>
    </j:jelly>

We use it.port to refer to the current value of the parameter port (note that config.jelly for a plugin class uses it instead of instance). In the help attribute, we use the artifactId you specified when you created your plugin (see pom.xml in the root directory of your plugin if you forgot what your artifactId is).

  1. Store the file config.jelly in src/main/resources/path/to/plugin/class/config.jelly. For instance, if your plugin class is hudson.plugins.exampleplugin.MyPlugin, put the file in src/main/resources/hudson/plugins/exampleplugin/MyPlugin/config.jelly.
  2. Create a file called help-projectConfig.html containing an HTML fragment like this:
    <div>
     <p>
      Your help text goes here.
     </p>
    </div>
  1. Store it in src/main/webapp/help-projectConfig.html.
  2. Start hudson normally (using mvn hpi:run). Navigate to the configure page and observe your new section. Click the help link and observe your help text.