使用自定义标签来避免 CFM 文件与大量 HTML 标记混合?

发布于 2024-12-03 09:46:08 字数 150 浏览 0 评论 0原文

您在使用自定义标签来提高可维护性方面是否取得过成功?

使用自定义标记是否比使用基本 有任何好处?

您之前编写过任何可以提高 HTML 可维护性的自定义标记吗?

谢谢

Have you had any success with uses of custom tag for view that increase maintainability?

Does use of custom tag have any benefit of using basic <cfinclude>?

Any custom tag you have written before that increase HTML maintainability?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

比忠 2024-12-10 09:46:08

是的,是的。

自定义标签对于分离可重用的 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="[email protected]" />
    <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>

我使用的比这多,但它们都是非常特定于应用程序/对象的。几乎每次我开始将某些内容提取到包含中,或者如果我发现自己将一段显示逻辑从一个页面复制到另一个页面,我就会开始考虑如何将该代码推送到自定义标记中。

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

Yes and Yes.

Custom tags are awesome for separating out reusable HTML elements. The advantages are that they are scope-safe, and you can pass arguments into them to change their behavior, which you can't do with cfinclude. You can even create nested tags that change their behavior based on their parents. Most of my HTML layouts in ColdFusion look something like this:

<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 is obviously greatly simplified, but I can change the entire layout of a site by changing the custom tag, or even changing the custom tag folder (think dynamic this.customTagPaths for swapping out layouts.

Custom Tags don't get enough love. Embrace them, and enjoy :).

Here's another example of something I do:

<cfset arOrders = OrderService.getOrders() />

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

My OrderRow custom tag handles all of the display for displaying a row for an order in a table. This includes add/edit/delete buttons, calculations that have to happen, conditions that must be me to change the display. I can display an order row anywhere I want in an admin area. On the customer details page, on a page showing all orders in a certain time period. It makes no difference. My users know that any place they see a row describing an order, it will look just as they expect it to.

Here are a few more concrete examples of small custom tags I use across multiple applications.

cf_jquery

This includes jQuery and jQueryUI in a page, but only if no other template in the application has already added jQuery on this request. This allows me to build multiple jQuery parts to a page, and no matter what order I call them in, I'll always know that jQuery has been added to the head of the document only once.

<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>

I even build tags for small information that I know will be used throughout the application in multiple places, like this cf_contact tag:

<cfif thisTag.ExecutionMode EQ "end">
    <cfparam name="Attributes.Phone" default="xxx.xxx.xxxx" />
    <cfparam name="Attributes.Email" default="[email protected]" />
    <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>

Why make a tag for something so small? Why not? If I style all my contact information the same throughout an application (and I should, so users can easily identify things), then I can make a tag for it just as easily as I can make an include. If I decide I want some other programmatic behavior to happen in there, my app is already set up to use it.

cf_timeblock

This custom tag shows a set of select lists for choosing a time block (hh:mm tt). I use this all over an application dealing with scheduling, so I have a tag that will allow me to display a block for a time, and I can send in which values should be pre-selected (I'm missing validation for the attributes, but just pretend it's there for now):

<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>

I use tons more than this, but they're all very application/object specific. Just about any time I start to pull something out into an include, or if I find myself copying a piece of display logic from one page to another, I start thinking about how I can push that code into a custom tag.

Here are a few more examples of custom tag libraries that I find useful.

亣腦蒛氧 2024-12-10 09:46:08

Dan 的其他出色工作中缺少的一个例子是自定义标签必须迭代封闭内容的非常强大但未充分利用的功能:

<!--- 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>

我对使用自定义标签提出的一个警告是,我听说它们很容易泄漏内存(我不能证实这一点),因此,如果在流量大的站点上使用它们,我会在使用它们之前对它们进行彻底的负载测试。

One example missing from Dan's otherwise excellent efforts is the very powerful but under-utilised capabilities custom tags have to iterate over enclosed content:

<!--- 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>

The one caveat I would offer for using custom tags is that I have heard they are prone to leaking memory (I cannot substaniate this), so if using them on a heavy-traffic site, I'd load test them thoroughly before going live with them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文