The template plugin comes with a number of built-in transformer implementations. As discussed in the “Concepts” section, logically speaking a transformer is a function that takes an instance and generates the standard Jenkins configuration of something (be it a builder, a job, …), thereby describing the model in terms that the rest of Jenkins understands.
This chapter walks through all the available transformer implementations.
Jelly is an XML-based template engine. Firstly, it allows you to insert arbitrary Java-like expressions in the \${… }
syntax (see JEXL for the reference of this syntax), and secondly, it allows you to use tags to do basic control-flow operations, such as conditional block, for-loop, switch/case, etc. See Jelly core tag library reference for more details.
Another benefit of Jelly is that it is guaranteed to produce a well-formed XML, and anything short of that is detected while you are defining a transformer. This reduces the chance of invalid transformer configuration.
Through these tags, Jelly can be abused as a programming language, but that is not really what Jelly is designed for (although at times this is handy.) If you start finding yourself using more Jelly tags than literal XML elements, consider using other transformers, such as Groovy template transformation, which offers more concise syntax.
During the transformation, all the attributes of the instance are available by their IDs. In addition, the following special variables are available:
- instance
- this variable refers to the instance object being transformed. This is of type com.cloudbees.hudson.plugins.modeling.Instance.
- model
- this variable refers to the model that the instance belongs to. This is of type com.cloudbees.hudson.plugins.modeling.Model.
- parent
- this variable is available for transforming models that produce Items, such as job templates and folder templates (but not builder templates.) This variable refers to the ItemGroup that represents the container of the item, such as a folder or a jenkins.model.Jenkins instance.
These variables and their methods/properties can be accessed to perform intelligent transformation.
This transformer is based on Groovy template, which is essentially a JSP in Groovy syntax + \${… }
style expression, such as the following:
<foo> <% for (int i=0; i<100; i++) { if ((i%2)==0) { %> <data>\${i}</data> <% } } %> </foo>
The benefit of this transformation is that the Groovy syntax, with its close alignment with the Java syntax, makes it easier for Java programmers to perform complex transformation.
Take care to escape dollar signs with backslashes in XML snippets you copy, so they are not misinterpreted as Groovy expressions; for example, one line copied from a folder XML configuration should read:
<properties class="hudson.model.View\$PropertyList"/>
Normally, for reasons of safety and robustness, XML metacharacters like <
in expression values are escaped before being emitted to the output. If you intend some attribute or computed value to be treated as raw XML inlined into the job configuration, wrap it in the xml function:
<outerElement>${xml(thisIsTreatedAsXmlText)}</outerElement>
In many cases one of your template attributes is actually a Jenkins component (or array of them). To embed it in a job config.xml
you must first serialize it. The Templates plugin (as of 4.0) offers a few more helper functions to make this easy. Most simply, if you have a single component like a hudson.tasks.Publisher that you want to emit, use the serialize
function:
<publishers>${serialize(publisher)}</publishers>
If you have a collection of components (including an array), for example because you let the user configure zero or more hudson.tasks.Builders, use the serializeAll function:
<builders>${serializeAll(builders)}</builders>
Finally, if you have a single component that you want to bind to a field of a more generic type, the XStream library used by Jenkins for serialization has a special syntax. To emit a component bound to that field, you need to also specify the field name. For example, to let the user configure a hudson.scm.SCM instance and bind that to the scm
field as <scm class="hudson.scm.SubversionSCM">…</scm>
, use the serializeOption function:
${serializeOption(scm, 'scm')}