Templates 如何使用coldfusion构建母版页?

Templates 如何使用coldfusion构建母版页?,templates,coldfusion,logic,master-pages,Templates,Coldfusion,Logic,Master Pages,我在我们的网站上有一个小的coldfusion部分,都使用类似的js和css文件以及页面结构。代码目前对每个文件都是重复的,我想用母版页和模板将其分解并设置一些内容 Master.cfm页面: <!--- Master template, includes all necessary js and css files. Expects following variables to be defined: - pageName - name of the file to b

我在我们的网站上有一个小的coldfusion部分,都使用类似的js和css文件以及页面结构。代码目前对每个文件都是重复的,我想用母版页和模板将其分解并设置一些内容

Master.cfm页面:

<!--- Master template, includes all necessary js and css files. 
    Expects following variables to be defined:
    - pageName - name of the file to be loaded as the body of the page 
    - title - text to be used as the title of the page and as the header text in the header bar --->
<cfinclude template="_lockedPage.cfm" />

<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>#title#</title>
        ... all script and css links here ...
        <script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
        <script type="text/javascript" src="js/jquery.mobile-1.3.2.js"></script>
        ... etc ...
    </head>
    <body>
        <div data-role="page">
            <div class="headerDiv" data-role="header" data-theme="b" data-position="fixed">
                <a id="backButton" data-role="button" data-direction="reverse" data-rel="back" data-icon="arrow-l" data-iconpos="left" data-theme="a">Back</a>
                <h1><cfoutput>#title#</cfoutput></h1>
                <a href="index.cfm" data-role="button" data-icon="home" data-iconpos="left" data-theme="a">Home</a>
            </div>
            <div data-role="content" class="container">
                <cfinclude template="#pageName#.cfm" />
            </div>
        </div>
    </body>
</html>

#头衔#
... 这里的所有脚本和css链接。。。
... 等
然后一个页面示例是这样的。CustomerSearch.cfm:

<cfscript>
    title = "Customer Search";
    pageName = "_customer-search";
    include "Master.cfm";
</cfscript>

title=“客户搜索”;
pageName=“\u客户搜索”;
包括“Master.cfm”;
然后我需要一个_customer-search.cfm页面,其中包含页面的所有正文内容

这意味着,对于我们当前拥有的每个页面,我需要2个文件-定义变量并包含母版页的外部页面,以及包含单个页面内容的模板页面


这是一个良好的逻辑结构吗?还有什么可以改进的吗?

你的想法是对的,但我认为你最终会得到很多不必要的文件。您可以创建包含全局HTML的
header.cfm
footer.cfm
。每一页都将包含这些文件,内容将在这些文件之间写入

<cfset title = "Customer Search">
<cfinclude template="global_header.cfm">

<!--- This will be the content of your page. --->

<cfinclude template="global_footer.cfm">

此文件将命名为
customer\u search.cfm
。无论何时更新页眉或页脚,这都是一个全局更改


如果需要在多个页面上存在大量的业务逻辑和查询代码,那么可以考虑使用MVC框架来帮助组织和重用代码。我更喜欢(试试ColdBox Lite),但是很多人都使用它。

Application.cfc对于普通页面设计来说是一个很好的用途。基本上有一个模板和注入页面生成的内容。Dan Bracuk在另一个解决方案中对使用Application.cfc
onRequestStart()
onRequestEnd()
方法发表了评论,但我使用的方法略有不同。以下是我的一般设置:

应用程序.cfc

// This is <cfscript> but it could be regular CFML too
component {
    public function onRequest( required string targetPage ) {

        // Capture/buffer the requested pages output
        savecontent variable='LOCAL.output' {
            include ARGUMENTS.targetPage;
        }


        // Use the output as the page content
        // if the page did not specify content
        param string REQUEST.content = LOCAL.output;


        // Inject the design template
        // which should output the page content somewhere
        include '/path/to/template.cfm';
    }
}
//这是一个函数,但也可以是常规的CFML
组成部分{
公共函数onRequest(必需的字符串targetPage){
//捕获/缓冲请求的页面输出
savecontent变量='LOCAL.output'{
包括ARGUMENTS.targetPage;
}
//将输出用作页面内容
//如果页面未指定内容
param string REQUEST.content=LOCAL.output;
//注入设计模板
//应该在某个地方输出页面内容
包括“/path/to/template.cfm”;
}
}
模板.cfm

<!DOCTYPE html>
<cfparam name="REQUEST.title"   type="string" /><!--- required --->
<cfparam name="REQUEST.head"    type="string" default="" />
<cfparam name="REQUEST.content" type="string" /><!--- required --->
<html>
    <head>
        <title><cfoutput>#REQUEST.title#</cfoutput></title>
        <link rel="stylesheet" href="path/to/common.css" />
        <script src="path/to/common.js"></script>
        <cfoutput>#REQUEST.head#</cfoutput>
    </head>
    <body>
        <header>...</header>
        <cfoutput>#REQUEST.content#</cfoutput>
        <footer>...</footer>
    </body>
</html>
<cfset REQUEST.title = "My Page Title" />


<cfsavecontent variable="REQUEST.head">
    <!-- page specific head elements here -->
</cfsavecontent>


<!-- Regular page code/HTML output here -->
<!--- or you could use another <cfsavecontent> block --->
<!--- to save specific output sections --->
<p>Hello World</p>

#请求.标题#
#请求#
...
#请求内容#
...
每页。cfm

<!DOCTYPE html>
<cfparam name="REQUEST.title"   type="string" /><!--- required --->
<cfparam name="REQUEST.head"    type="string" default="" />
<cfparam name="REQUEST.content" type="string" /><!--- required --->
<html>
    <head>
        <title><cfoutput>#REQUEST.title#</cfoutput></title>
        <link rel="stylesheet" href="path/to/common.css" />
        <script src="path/to/common.js"></script>
        <cfoutput>#REQUEST.head#</cfoutput>
    </head>
    <body>
        <header>...</header>
        <cfoutput>#REQUEST.content#</cfoutput>
        <footer>...</footer>
    </body>
</html>
<cfset REQUEST.title = "My Page Title" />


<cfsavecontent variable="REQUEST.head">
    <!-- page specific head elements here -->
</cfsavecontent>


<!-- Regular page code/HTML output here -->
<!--- or you could use another <cfsavecontent> block --->
<!--- to save specific output sections --->
<p>Hello World</p>

你好,世界

通过这种方式,您可以将模板全部保存在一个文件中,这在所见即所得庄园中进行设计时更容易。它还允许每个页面设置设计模板中使用的变量,因为请求的页面是在包含设计模板之前执行的


而且,由于默认情况下将为所有页面调用Application.cfc
onRequest()
,因此无需在每个页面上使用
模板。如果存在不应包含设计模板的.cfm页面,例如PDF输出,那么您需要添加一些逻辑以仅转储输出而不包含设计模板。

我发现使用自定义标记是另一个简单的解决方案,在我看来,创建单独的header.cfm和footer.cfm是更好的解决方案

在master.cfm中:

<cfif ThisTag.ExecutionMode EQ 'start'>
  [HEADER]
<cfelse>
  [FOOTER]
<cfif>

[标题]
[页脚]
在每个内容页中:

<cf_master>
  [CONTENT GOES HERE]
</cf_master>

[内容如下]
如果要将变量传递到母版页,只需将其作为属性添加到开始标记:

<cf_master Title="Content Title">

并确保在主文件中指定了该属性:

<cfparam name="Attributes.Title" default=""/>
<head>
  <title><cfoutput>#Attributes.Title#</cfoutput></title>
</head>

#属性。标题#
对我来说,关键是理解ThisTag.ExectuionMode。如果使用自定义标记,则可以仅使用一个标记,也可以使用开始和结束标记。如果使用开始和结束标记,则可以选择在开始标记中包含一些内容,在结束标记中包含其他内容。这就是为什么需要master.cfm中的if/else条件。在这种情况下,它很有用,因为这样可以在开始标记中包含页眉,在结束标记中包含页脚

另外,如果这不明显,当您调用自定义标记时,它应该与存储代码的文件名匹配。在我的例子中,
匹配
master.cfm


我将此页面用作自定义标记的教程:

可以从onRequestStart()和onRequestEnd()调用这两个全局文件的include。@DanBracuk是的,它们可以,但是您不能以所述的方式更改每个页面的标题。谢谢,这样可以。但感觉不到压抑;页眉中将有在页脚中关闭的开始标记。“页脚”将只包含“`”。但它确实消除了对额外文件的需要……”“Application.cfc对于普通页面设计非常有用”。不,真的不是。建议在CFM文件中包含特定于页面的CSS和JS?非常糟糕的建议。正确的建议应该是“使用像FW/1这样的轻量级框架”。我不同意你的观点。ColdFusion可以用于基本应用程序,在这些应用程序中,像FW/1这样的框架只是矫枉过正,增加了不必要的复杂性。至于特定于页面的CSS/JS,我已经更新了我的答案,以展示一种更全局的方法。我的答案仍然是一个有效的选项,由用户决定哪一个最适合他们的情况。请不要因为你自己的开发风格而投反对票,不要因为它不可行而投反对票