【问题标题】:How to structure a master page with coldfusion?如何使用冷融合构建母版页?
【发布时间】:2014-03-20 15:18:50
【问题描述】:

我的网站有一个小的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>

然后页面示例将是这样的。 CustomerSearch.cfm:

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

然后我需要一个包含页面所有正文内容的 _customer-search.cfm 页面。

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

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

【问题讨论】:

    标签: templates coldfusion logic master-pages


    【解决方案1】:

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

    <cfset title = "Customer Search">
    <cfinclude template="global_header.cfm">
    
    <!--- This will be the content of your page. --->
    
    <cfinclude template="global_footer.cfm">

    这个文件将被命名为customer_search.cfm。每当您更新页眉或页脚时,它都是全局更改。

    如果您有大量业务逻辑和查询代码需要存在于多个页面上,您可能会考虑使用 MVC 框架来帮助您组织和重用代码。我更喜欢ColdBox(试试ColdBox Lite),但很多人使用Framework/1

    【讨论】:

    • 可以从 onRequestStart() 和 onRequestEnd() 调用两个全局文件的包含。
    • @DanBracuk 是的,他们可以,但是您不能以所述方式更改每个页面的标题。
    • 谢谢,这样可以。感觉不像被包含在内;页眉中将有打开的标签,在页脚中关闭。而“页脚”将只包含`
    【解决方案2】:

    我发现使用自定义标签是另一种简单的解决方案,并且在我看来是创建单独的 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。如果您使用自定义标签,您可以只使用一个标签,也可以使用一个开始和结束标签。如果您使用开始和结束标签,那么您可以选择在开始标签&lt;cf_master&gt; 中包含一些内容,在结束标签&lt;/cf_master&gt; 中包含其他内容。这就是为什么您需要 master.cfm 中的 if/else 条件。在这种情况下,它很有用,因为您可以在开始标签中包含 HEADER,在结束标签中包含 FOOTER。

    另外,如果这不明显,当您调用自定义标签时,它应该与存储代码的文件的名称相匹配。在我的情况下,&lt;cf_master&gt; 匹配 master.cfm

    我将此页面用作自定义标签的教程:https://www.petefreitag.com/item/64.cfm

    【讨论】:

      【解决方案3】:

      Application.cfc 可以很好地用于常见页面设计。基本上只有一个模板并注入页面生成的内容。 Dan Bracuk 在另一个解决方案中评论了关于使用 Application.cfc onRequestStart()onRequestEnd() 方法,但我使用它略有不同。这是我的一般设置:

      Application.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';
          }
      }
      

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

      每个页面.cfm

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

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

      而且,每个页面都不需要&lt;cfinclude&gt; 模板,因为默认情况下,所有页面都会调用 Application.cfc onRequest()。如果存在不应包含设计模板的 .cfm 页面,例如 PDF 输出,则您需要添加一些逻辑以仅转储输出而不包含设计模板。

      【讨论】:

      • “Application.cfc 非常适合用于常见页面设计”。不,真的不是。并建议在 CFM 文件中包含特定于页面的 CSS 和 JS?非常糟糕的建议。正确的建议应该是“使用像 FW/1 这样的轻量级框架”。投反对票。
      • 我不同意你的观点。 ColdFusion 可用于基本应用程序,其中 FW/1 等框架只是矫枉过正并增加了不必要的复杂性。至于特定于页面的 CSS/JS,我已经更新了我的答案以展示一种更全球化的方法。我的回答仍然是一个有效的选择,由用户决定哪个最适合他们的情况。请不要因为你自己的开发风格而投反对票,因为这不是一个可行的解决方案。
      • “像FW/1这样的框架只是矫枉过正”表明你不知道FW/1——它很简单;可以说,开销/结构对您在此处所做的事情不太复杂,但具有显着优势,即其他人不需要弄清楚您在做什么,因为 FW/1 提供了一个标准.
      • @PeterBoughton 很公平,我对 FW/1 的了解并不多,但我个人认为除了我对最基本应用程序的回答之外,没有什么需要。如果开发人员认为他们的项目将从框架中受益,那么一定要使用框架。但是建议框架总是需要的只是荒谬的。而且我的解决方案很容易理解是怎么回事,看一下Application.cfc的onRequest()方法就行了。
      • 重点是:还有许多其他开发人员感觉和你一模一样。他们每个人都有自己的版本,他们认为这是一种易于理解的简单结构。这些中的每一个都是一个框架 - 尽管没有记录和非标准化。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多