Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to structure a master page with coldfusion?

I have a small coldfusion section of our site that all uses similar js and css files and page structure. The code is currently repeated for each file, and I'd like to factor it out and set something up using a master page and templates.

Master.cfm page:

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

Then a page example would be something like this. CustomerSearch.cfm:

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

And then I would need a _customer-search.cfm page that would include all the body content for the page.

This means that I would need 2 files for every page that we currently have - the outer page that defines the variable and includes the master page, and the template page that has the individual page content.

Is this a good logical structure? Is there anyway to improve it?

like image 668
froadie Avatar asked Mar 20 '14 15:03

froadie


2 Answers

You have the right idea, but I think you'll end up with a lot of unnecessary files. You could instead create a header.cfm and a footer.cfm that contain your global HTML. Each page would include those files and the content would be written between.

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

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

<cfinclude template="global_footer.cfm">

This file would be named customer_search.cfm. Anytime you update the header or footer, it's a global change.

If you have a lot of business logic and query code that needs to exist on multiple pages, you might look into using an MVC framework to help you organize and reuse code. I prefer ColdBox (try ColdBox Lite), but many people use Framework/1.

like image 141
Adrian J. Moreno Avatar answered Oct 14 '22 11:10

Adrian J. Moreno


I found that using custom tags was another simple solution and in my opinion a better solution to creating a separate header.cfm and footer.cfm.

In master.cfm:

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

In each content page:

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

If you'd like to pass in variables to the master page simply add it as an attribute to the opening tag:

<cf_master Title="Content Title">

And make sure the attribute is specified in the master file:

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

The key for me was understanding the ThisTag.ExectuionMode. If you use custom tags you can either use just one tag or use an opening and closing tag. If you use an opening and closing tag then you can choose to include some content in the opening tag <cf_master>, and other content in the closing tag </cf_master>. That is why you need the if/else condition in master.cfm. In this case it is useful because then you can include a HEADER in the opening tag and a FOOTER in the closing tag.

Also, in case this isn't obvious, when you call your custom tag, it should match the name of the file where the code is stored. In my case <cf_master> matches master.cfm.

I used this page as a tutorial for custom tags: https://www.petefreitag.com/item/64.cfm

like image 24
Keven Avatar answered Oct 14 '22 12:10

Keven