第五十章 开发自定义标签 - 使用Rule类
使用Rule类
规则编译器为每个被编译的规则定义生成一个类。 匹配规则时执行的正是这段代码。 这意味着
- 规则可以更强大
- 可以直接将规则创建为类,并且
- 可以在
Studio
中查看和编辑规则类。
生成的规则类的结构
当从.csr
文件编译规则时,创建的规则类包含一个RenderStartTag
方法,如果在规则定义中指定了编译时代码,则包含一个或多个CompilerMethod
方法。 如果<csr:children>
或<csr:default>
标记在规则定义中,RenderEndTag
方法也会被添加到类中。 虽然CompilerMethod
方法包含要在编译时执行的代码,但RenderStartTag
和RenderEndTag
方法都由一系列Write
方法组成,用于直接写入CSP
页面类的代码表达式。 所使用的Write
方法的类型取决于表达式。 写方法在。%CSP.AbstractAtom
中定义,并将在本章后面讨论。
下面是一个属于<csr:if>
规则的规则类。 它包含一个RenderStartTag
和RenderEndTag
方法,并有CompilerMethod
的两个实例。 下面将进一步详细解释每一种方法。
Import User Class %csr.csp.IF Extends %CSP.RuleBlock { Parameter CSRURL = "w:/csp/rules/Control.csr"; Method CompilerMethod1() [ Language = cache ] { Do ..NewBlock() Set ..NextLabel=..GetNewLabel() Do ..WriteServer( " If '(" _ $$UnEscapeHTML^%cspQuote(..GetAttribute("condition","0")) _ ") Goto " _ ..NextLabel _" ;{" ) } Method CompilerMethod2() [ Language = cache ] { New comment Set comment=" ;}" If ..EndLabel'="" Do ..WriteServer(..EndLabel_comment) Set comment="" If ..NextLabel'="" Do ..WriteServer(..NextLabel_comment) Do ..RemoveBlock() } Method RenderEndTag() As %Status { New element Set element=##this Set %statuscode=$$$OK Do ..CompilerMethod2() Quit:$$$ISERR(%statuscode) %statuscode Quit $$$OK } Method RenderStartTag() As %Status { New element Set element=##this Set %statuscode=$$$OK Do ..CompilerMethod1() Quit:$$$ISERR(%statuscode) %statuscode Quit $$$PROCESSCHILDREN } } 复制代码
RenderStartTag
方法
RenderStartTag
方法在呈现CSP
页面中的开始标记时被调用。RenderStartTag
将代码写入呈现该元素的例程构建器对象中。 在<csr:action>
的主体中,出现在<csr:children>
标记之前的文本将使用一系列不同的写方法写入例程构建器对象,具体取决于要写入的文本类型。
例如,以下代码:
<csr:action> <script language="Cache" runat=server> Set myfile="c:\temp.txt" Open myfile:("FR":100) Use myfile:() Read var1 Close myfile </script> </csr:action> 复制代码
结果是在编译时在创建的规则类中生成以下RenderStartTag
方法:
Method RenderStartTag() As %Status { New element Set element=##this Do ..WriteCSPServer(" Set myfile=""c:\temp.txt""",0) Do ..WriteCSPServer(" Open myfile:(""FR"":100)",1) Do ..WriteCSPServer(" Use myfile:() ",1) Do ..WriteCSPServer(" Read var1",1) Do ..WriteCSPServer(" Close myfile",1) Quit $$$SKIPCHILDREN } 复制代码
RenderStartTag
方法可以包含其他语句,这取决于规则定义的结构。 如果在操作中指定了<script runat=compiler>
标记,导致创建了CompilerMethod
方法,则在RenderStartTag
方法的开头使用以下命令调用CompilerMethod
方法(在CompilerMethod1
实例中显示):
Set %statuscode=$$$OK Do ..CompilerMethod1() Quit:$$$ISERR(%statuscode) %statuscode 复制代码
除了不同的Write
方法和对CompilerMethod
方法的调用之外,RenderStartTag
方法还可以包含其他命令,这取决于<csr:action>
定义中是否使用了一个或多个csr
标记。
Quit语句 <csr:children>
如果<csr:children>
标签在.csr文件中,那么生成的RenderStartTag
方法的最后一行是:
Quit $$$PROCESSCHILDREN 复制代码
这表明在RenderStartTag
方法完成后应该处理子元素。RenderEndTag
方法也被显式地写入类,并写入<csr:children>
标记被调用之后出现的语句(默认情况下,RenderEndTag
方法什么也不做)。
Quit语句 <csr:default>
如果在动作定义中使用<csr:default>
标签,生成的RenderStartTag
方法包含以下命令:
Do ..RenderDefaultStartTag() Quit $$$PROCESSCHILDREN 复制代码
CompilerMethod[n]()
Method
如果为一个或多个<script>
标记指定了runat=compiler
,则CompilerMethod
方法将从.csr
文件生成。 它可以在RenderStartTag
方法的任何位置调用,这取决于<script runat=compiler>
语句的位置。 带有编译时代码的多个<script>
标记生成多个CompilerMethod
方法(CompilerMethod1()
、CompilerMethod2()
等)。 与其他两个方法不同,.csr
文件中的编译时ObjectScript
语句被逐行复制到该方法的主体中。
例如,考虑.csr
规则文件中的以下编译时代码:
<script language="Cache" runat=compiler> SET ^client(2,1,1)=..InnerText() </script> 复制代码
编译.csr
文件时,在关联规则类中生成如下方法:
Method CompilerMethod1() [ Language = cache ] { SET ^client(2,1,1)=..InnerText() } 复制代码
RenderEndTag Method
如果<csr:children>
或<csr:default>
标记在.csr
文件规则定义中,则在规则类中生成RenderEndTag
方法。 它在呈现结束标记时被调用。 在<csr:children>
标记之后出现的任何语句都将在此方法中写入例程构建器,类似于RenderStartTag
方法。
下面是取自条形图的一个规则定义示例。CSP
示例页面中的csr
示例。 注意表声明中<csr:children>
标记的位置。
<csr:rule name="iscbarchart" match="isc:barchart" language="any"> <csr:action> <table bgcolor='##(..GetAttribute("BGCOLOR"))##' border=0 cellspacing=0 style='border: ##(..GetAttribute("BORDER","solid blue"))##;'><tr> <csr:children> </tr></table> </csr:action> </csr:rule> 复制代码
编译之后,生成一个iscbarchart
规则类,并调用处理RenderStartTag
方法的Quit
语句中的子类。 规则文件中<csr:children>
标签后的HTML
是用RenderEndTag
方法编写的:
Import User Class csr.csp.iscbarchart Extends %CSP.Rule { Parameter CSRURL = "w:/csp/samples/barchart.csr"; Method RenderEndTag() As %Status { New element Set element=##this Do ..WriteText("",1) Do ..WriteCSPText("</tr></table>",0) Quit $$$OK } Method RenderStartTag() As %Status { New element Set element=##this Do ..WriteText("",1) Do ..WriteCSPText( "<table bgcolor='##(..GetAttribute(""BGCOLOR""))##' border=0 cellspacing=0" ,1) Do ..WriteCSPText( " style='border: ##(..GetAttribute(""BORDER"",""solid blue""))##;'><tr>" ,0) Quit $$$PROCESSCHILDREN } }