假设你建立了一个java类,路径为
src/main/java/org/myOrg/MyAction.java
则增加Jelly文件需要在resources文件夹中建立与类同名的目录:
src/main/resources/org/myOrg/MyAction/
并且在其中增加文件config.jelly,路径如下:
src/main/resources/org/myOrg/MyAction/config.jelly
如果你的插件中需要包含帮助文档,文档的名称为help-FIELD.html
或者help-FIELD.jelly
,路径同config.jelly
,这时在控件的右边会显示一个问号:
src/main/resources/org/myOrg/MyAction/help-FIELD.html
it
对象
Jelly文件直接绑定到了对应的类上,即Jelly页面可以调用类中的函数。为了引用Jelly页面绑定的类,Jelly文件使用it
对象。
类中的函数:
public String getMyString() {
return "Hello Jenkins!";
}
Jelly文件:
<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">
${it.myString}
</j:jelly>
这样页面上能显示出"Hello Jenkins!"
1.app Jekins实例
2.instance 正在被配置的对象
3.descriptor 对应于instance的Descriptor对象
4.h hudson.Functions的实例
页面上可以使用下列变量来产生链接: 1.rootURL jenkins实例 2.resURL 静态webapp资源,如JS或者HTML。 3.imagesURL 如同resURL但是后面增加/images
对于对象中包含Descriptor的对象,页面和数据的绑定步骤如下:
1.在类中增加一个构造函数,将所有需要的配置作为构造函数的参数。并且在构造函数上增加@DataBoundConstructor
注解,来告诉Jenkins进行实例化。
public class MyRecorder extends Recorder {
private final String url;
private final String info;
// Fields in config.jelly must names in "DataBoundConstructor"
@DataBoundConstructor
public HelloWorldBuilder(String url,String info) {
this.url = url;
this.info = info;
}
}
2.在类中增加getter方法,或者将变量设置为public final
。这样可以让Jelly脚本将数值显示到配置信息页面。
//We'll use this from the <tt>config.jelly</tt>.
public String getUrl() {
return url;
}
public String getInfo() {
return info;
}
3.在config.jelly中增加Jelly代码来显示配置选项。
<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:entry title="请求地址" field="url">
<f:textbox />
</f:entry>
<f:entry title="项目所需变量" field="info">
<f:textbox />
</f:entry>
</j:jelly>
4.帮助文件
对控件需要增加帮助信息,可以在文件中包含名称为help-FIELD.html
或者help-FIELD.jelly
的帮助文档。你也可以增加顶级的帮助文档help.html
。增加了帮助文档,会在控件的右边显示一个问号,点击能够显示提示信息。
<f:section title="My Plugin">
<f:entry title="${%Port}" help="help-port.html">
<f:textbox name="port" value="${it.port}"/>
</f:entry>
</f:section>
5.配置信息检查
在内部实现的DescriptorImpl类中,增加doCheckFIELD()函数,来进行配置信息的检查。在参数上可以增加@QueryParameter注解来传入附近位置的数据。
public FormValidation doCheckUrl(@QueryParameter("url") String value)
throws IOException, ServletException {
if (value.length() == 0)
return FormValidation.error("Please set the url");
return FormValidation.ok();
}
6.Jelly页面的默认值 如果希望配置页面上增加初始化值,可以使用@default注解:
<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>
第一个default使用了固定值,第二个default使用了计算出来的数值作为初始化参数。
Jelly程序如下:
<f:entry title="Create test report" field="isSelected">
<f:checkbox/>
</f:entry>
<f:entry title="Name" field="name">
<f:textbox />
</f:entry>
对应的Java程序:
private final String name;
public boolean selected;
@DataBoundConstructor
public HelloWorldBuilder(String name,boolean selected) {
this.name = name;
this.selected = selected;
}
public boolean isSelected() {
return selected;
}
public String getName() {
return name;
}
当我们需要在服务器端进行数据验证,并且输入的数据需要多个参数支持时使用。例如输入用户名和密码:
<f:entry title="${%Access Key ID}" help="...">
<f:textbox field="accessId" />
</f:entry>
<f:entry title="${%Secret Access Key}" help="...">
<f:password field="secretKey" />
</f:entry>
<f:validateButton
title="${%Test Connection}" progress="${%Testing...}"
method="testConnection" with="secretKey,accessId" />
在服务器端,validateButton触发的事件默认为doTestConnection,并且传入了靠近validateButton的参数accessId和secretKey,最后这个函数需要调用FormValidation.ok
,warning
,或者 error
:
public FormValidation doTestConnection(@QueryParameter("accessId") final String accessId,
@QueryParameter("secretKey") final String secretKey) throws IOException, ServletException {
try {
... do some tests ...
return FormValidation.ok("Success");
} catch (EC2Exception e) {
return FormValidation.error("Client error : "+e.getMessage());
}
}
<f:advanced>
<f:entry title="${%Ignore Property Changes on directories}" field="advance">
<f:checkbox />
</f:entry>
</f:advanced>
对应的程序
@Exported
public boolean getAdvance(){
return advance;
}
可选块:
<table>
<f:optionalBlock field="dynamic" title="Use existing dynamic view" checked="${instance.getChecked()}">
<f:entry title="View name">
<f:textbox field="name" value="${it.checked}"/>
</f:entry>
</f:optionalBlock>
</table>
说明:这些模块的使用,可以参见: