最近在琢磨金蝶 EAS BOS 的结构,顺带温习了一下 xml 配置的东西;又看到金蝶终于推出了用于移动界面的 Yun UI
,于是脑洞略开,看看能不能做一个 Yun UI
的 JSF 标签库封装。
参照 https://www.tutorialspoint.com/jsf/jsf_custom_tag.htm 的说法,最重要的步骤,是在工程的 web.xml
中,为定义了标签的文件,新建一个 context-param
标签来存放。web.xml
的代码大概是这样的:
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<!-- 重点在下面 -->
<!-- 为自定义标签单独开设的 context-param -->
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<!-- 这里指明了自定义标签文件相对于 web.xml 的存放位置 -->
<param-value>/WEB-INF/tutorialspoint.taglib.xml</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
</web-app>
然后就是写好自定义标签的声明文件,用来直接引用标签模板。按照上面的声明,我们把这个文件叫做 tutorialspoint.taglib.xml
:
<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
<!-- 在使用这些自定义标签的 JSF 页面中,需要将这些标签的 namespace 声明为下面的自定义网址 -->
<namespace>http://tutorialspoint.com/facelets</namespace>
<!-- 每个自定义标签,都需要一个单独的 tag -->
<tag>
<tag-name>buttonPanel</tag-name>
<!-- 标签对应的模板文件的存放位置 -->
<source>com/tutorialspoint/buttonPanel.xhtml</source>
</tag>
</facelet-taglib>
然后就是标签模板,用来定义这个标签真正的内容。主要用了 ui:composition
标签来封装:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets">
<h:body>
<ui:composition>
<!-- 这里定义的 buttonPanel ,实际是2个 commandButton -->
<!-- #{okLabel} 当作按钮的 value 使用,#{cancelLabel} 同理 -->
<!-- 至于是否需要把布局、样式也一并封装到 buttonPanel 待定 -->
<h:commandButton type="submit" value="#{okLabel}" />
<h:commandButton type="reset" value="#{cancelLabel}" />
</ui:composition>
</h:body>
</html>
然后在下面客户要访问的 JSF 页面中,分别声明各标签所属的 namespace
,并且为自定义标签的属性赋值,就可以愉快地使用了:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- 给自定义标签库起个名字,比如这里叫做 tp,然后将自定义标签声明为 html xmlns 的下级标签 -->
<!-- 注意与其他标签库的冲突 -->
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:tp="http://tutorialspoint.com/facelets">
<h:head>
<title>JSF tutorial</title>
</h:head>
<h:body>
<h1>Custom Tags Example</h1>
<!-- 生成的部件和定义的一样,由两个按钮组成 -->
<!-- 两个按钮上的文字分别是 OK 和 Cancel -->
<tp:buttonPanel okLabel="Ok" cancelLabel="Cancel" />
</h:body>
</html>
贴个原网址的图,后续的文章就要讲怎么移植 Yun UI ,还有解析顺序和速度的问题了。
顺带…发现 08-09年那段时间的前端开发真是百花(fa)齐放啊,或者说越是“和平年代”其实可以选/ 想的更少,估计做完这个封装,后面会转向其他方面了