利用自定义标记来避免混合大量HTML标记的CFM文件?

时间:2011-09-06 23:17:41

标签: coldfusion

您是否在使用自定义标记获得成功以提高可维护性?

使用自定义标记是否有使用基本<cfinclude>

的任何好处

之前编写的任何自定义标记都会增加HTML可维护性吗?

由于

2 个答案:

答案 0 :(得分:11)

是和是。

自定义标记非常适合分离可重用的HTML元素。优点是它们是范围安全的,您可以将参数传递给它们以改变它们的行为,这是cfinclude无法做到的。您甚至可以创建嵌套标签,根据父级更改其行为。我在ColdFusion中的大部分HTML布局都是这样的:

<cf_layout>
    <cf_head title="My Page>
    <!--- Some local head stuff ---->
    </cf_head>

    <cf_content>
        Lots of stuff goes here.
    </cf_content>
</cf_layout>

这显然大大简化了,但我可以通过更改自定义标记来更改网站的整个布局,甚至可以更改自定义标记文件夹(想想动态this.customTagPaths来换掉布局。

自定义标签没有得到足够的爱。拥抱他们,享受:)。

这是我做的另一个例子:

<cfset arOrders = OrderService.getOrders() />

<table>
    <cfloop array="#arOrders#" index="currentOrder">
        <cf_orderrow order="#currentOrder#" />
    </cfloop>
</table>

我的OrderRow自定义标记处理所有显示,以便在表格中显示订单的行。这包括添加/编辑/删除按钮,必须进行的计算,必须由我来改变显示的条件。我可以在管理区域中的任何地方显示订单行。在客户详细信息页面上,显示特定时间段内所有订单的页面。没什么区别。我的用户知道他们看到一行描述订单的任何地方,它看起来就像他们期望的那样。

以下是我在多个应用程序中使用的小型自定义标记的一些更具体的示例。

<强> cf_jquery

这包括页面中的jQuery和jQueryUI,但前提是应用程序中没有其他模板已经在此请求中添加了jQuery。这允许我为一个页面构建多个jQuery部分,无论我调用它们的顺序如何,我都会知道jQuery只被添加到文档的头部一次。

<cfif thisTag.ExecutionMode EQ "end" AND (NOT StructKeyExists(Request, "JQueryInited") OR Request.JQueryInited EQ False)>
    <cfparam name="Attributes.IncludeUI" default="False" />
    <cfparam name="Request.jQueryUIInited" default="False" />
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
    <cfif Attributes.IncludeUI AND Request.jQueryUIInited IS False>
        <link href="/shared/css/smoothness/jquery-ui-1.8.11.custom.css" rel="stylesheet" />
        <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js"></script>
        <cfset Request.jQueryUIInited = True />
    </cfif>
    <cfset Request.JQueryInited = True />
</cfif>

我甚至为小知识构建标签,我知道这些标签会在多个地方的整个应用程序中使用,例如cf_contact标记:

<cfif thisTag.ExecutionMode EQ "end">
    <cfparam name="Attributes.Phone" default="xxx.xxx.xxxx" />
    <cfparam name="Attributes.Email" default="me@you.com" />
    <cfparam name="Attributes.EmailName" default="Email Support" />
    <h2 style="font: bold 12px Verdana, Geneva, Arial, Helvetica, sans-serif; margin-bottom: 0;">Contact Us</h2>
    <p style="text-align: left; margin-top: 0;"><cfoutput>#Attributes.Phone#</cfoutput><br />
    <cfoutput><a href="mailto:#Attributes.Email#">#Attributes.EmailName#</a></cfoutput></p>
</cfif>

为什么要为这么小的东西制作标签?为什么不?如果我在整个应用程序中将所有联系信息设置为相同(我应该,因此用户可以轻松识别内容),那么我可以像制作包含一样轻松地为其制作标签。如果我决定在那里发生其他一些编程行为,我的应用程序已经设置为使用它。

<强> cf_timeblock

此自定义标记显示一组用于选择时间块的选择列表(hh:mm tt)。我在处理调度的应用程序中使用这个,所以我有一个标签,允许我显示一段时间,我可以发送应该预先选择的值(我缺少对属性的验证,但只是假装它现在在那里):

<cfif thisTag.ExecutionMode EQ "end">
    <cfsilent>
        <!--- Get Time Blocks --->
        <cfset TimeBlocks = Application.DAO.getTimeQueries() />
    </cfsilent>
    <select name="hour" style="width: auto; float: none;">
        <cfoutput query="TimeBlocks.Hours">
            <option value="#TimeBlocks.Hours.Value#"<cfif TimeBlocks.Hours.Value EQ Attributes.Hour> selected="selected"</cfif>>
                #TimeBlocks.Hours.Value#
            </option>
        </cfoutput>
    </select>:<select name="min" style="width: auto; float: none;">
        <cfoutput query="TimeBlocks.Mins">
            <option value="#TimeBlocks.Mins.Value#"<cfif TimeBlocks.Mins.Value EQ Attributes.Min> selected="selected"</cfif>>
                #TimeBlocks.Mins.Value#
            </option>
        </cfoutput>
    </select>
    <select name="mer" style="width: auto; float: none;">
        <cfoutput query="TimeBlocks.Mer">
            <option value="#TimeBlocks.Mer.Value#"<cfif TimeBlocks.Mer.Value EQ FORM.mer> selected="selected"</cfif>>
                #TimeBlocks.Mer.Value#
            </option>
        </cfoutput>
    </select>
</cfif>

我使用的吨比这更多,但它们都是特定于应用程序/对象的。几乎在任何时候我开始将某些内容写入包含内容,或者如果我发现自己将一个显示逻辑从一个页面复制到另一个页面,我开始考虑如何将该代码推送到自定义标记中。

以下是我认为有用的自定义标记库的一些示例。

答案 1 :(得分:2)

丹的优秀努力中缺少的一个例子是自定义标签必须迭代封闭内容的功能非常强大但利用不足的功能:

<!--- loop.cfm --->
<cfif (THISTAG.ExecutionMode EQ "Start")>
    <cfparam name="attributes.index" type="variablename">
    <cfparam name="attributes.iterations" type="integer">

    <cfset variables.index = 1>
    <cfset caller[attributes.index] = variables.index>
<cfelse>
    <cfset variables.index = variables.index + 1>
    <cfif variables.index lte attributes.iterations>
        <cfset caller[attributes.index] = variables.index>
        <cfexit method="loop">
    <cfelse>
        <cfexit method="exittag">
    </cfif>
</cfif>

<!--- testLoop.cfm --->
<cf_loop iterations="10" index="i">
    <cfoutput>[#i#]</cfoutput>Hello World<br />
</cf_loop>

我要提供的使用自定义标签的一个警告是,我听说它们容易泄漏内存(我无法理解这一点),所以如果在交通繁忙的网站上使用它们,我会先进行彻底的测试与他们一起生活。