Basic layout HTML
Below is a general _layout.cfm
example. All layout files should include all of the following:
HTML5 doctype
Enforce standards mode and more consistent rendering in every browser possible with this simple doctype at the beginning of every HTML page.
<!DOCTYPE html>
<html lang="en">
...
</html>
Meta tags
To ensure proper rendering and touch zooming on mobile, include the viewport meta tag.
<meta name="viewport" content="width=device-width, initial-scale=1">
Favicons
As mentioned on https://evilmartians.com/chronicles/how-to-favicon-in-2021-six-files-that-fit-most-needs we don't need a lot of images for favicons.
<link rel="icon" href="/favicon.ico" sizes="any"><!--- 32×32 --->
<link rel="icon" href="/icon.svg" type="image/svg+xml"> <!--- square image with about 20px of padding --->
<link rel="apple-touch-icon" href="/apple-touch-icon.png"><!--- 180×180 --->
<link rel="manifest" href="/manifest.webmanifest">
manifest.webmanifest:
// manifest.webmanifest
{
"icons": [
{ "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" },
{ "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" }
]
}
If all else fails, we can use this generator: https://realfavicongenerator.net/
CSS and JavaScript includes
Per HTML5 spec, typically there is no need to specify a type
when including CSS and JavaScript files because text/css
and text/javascript
are their respective defaults.
Note: avoid @import
Compared to <link>
s, @import
is slower, adds extra page requests, and can cause other unforeseen problems. Avoid them and instead opt for multiple <link>
elements.
Page content
Page content gives the client the ability to update content (such as header images, links, footer text, etc.) that do not fall within the #fusebox.layout#
content area on the page. Read further documentation here.
Partial includes
Elements that are repeated in multiple layout files (such as the main navigation and page footer) are saved in a separate file and included with <cfinclude>
.
Content insertion
The <cfouput>#fusebox.layout#</cfoutput>
goes wherever the content will be going. This is where the client will be adding Perpetua created content to the page.
Containers
Our template css includes a .container
class to center content within a section.
<div class="[section-name] wide">
<div class="container">
</div>
</div>
By default, the container applies width: 1000px;
and uses horizontal margin
s to center it.
Example subpage Layout File
<!DOCTYPE html>
<html>
<!--- get page content --->
<cfinclude template="#request.dir_globals#/qry_page_content_inheritance.cfm">
<head>
<cfset request._css_array = [
"/css/_grid.css",
"/css/_subpage.css",
"/css/_subpagemodule.css",
"/css/_cb_layout.css"
]>
<cfset request._js_array = [
"/js/_globals.js",
"/js/_subpage.js"
]>
<cfinclude template="/_partials/_global_head.cfm">
</head>
<body>
<!--- pulls in the Perpetua Administration bar, if they are logged in --->
<cfinclude template="#request.dir_base#/images_ADMIN/#adminSkin#/topmenu.cfm">
<div id="mainContainer" class="main-container">
<div class="site-header wide">
<cfinclude template="/_partials/_top.cfm">
<div class="hero wide" style="--background-image: url('<cfoutput>#pcValue("pcItem_1_1_1")#</cfoutput>'); --background-position: center 25%;">
<cfif val(request.sessionScope.LoggedIn)>
<a style="right: 20px; top: auto; bottom: 20px;z-index: 3001;" class="pc-edit cb-tools" href="javascript:openAdminWindow('<cfoutput>#variables.basehref#Admin/index.cfm/fuseaction/pages.dynamic_page_content/pageID/#Attributes.pageid#/nodeid/1/index.html</cfoutput>',900,680);">
<span class="icon-pencil"> Edit</span>
<span class="edit-desc"> Header Image</span>
</a>
</cfif>
<div class="floating wow fadeIn">
<div class="floating-content">
<h1>
<cfoutput>#qry_pageinfo.fldTitle#</cfoutput>
</h1>
</div>
</div>
</div>
</div>
<div id="content" class="fullWidth">
<cfoutput>#fusebox.layout#</cfoutput>
</div>
<div id="subpageModules" class="wide">
</div>
<cfinclude template="/_partials/_bottom.cfm">
</div>
<cfparam name="request._js_array_globals" default="[]">
<cfparam name="request._js_array" default="[]">
<cfset ArrayAppend(request._js_array_globals, request._js_array, true)>
<cfloop array="#request._js_array#" index="request._js_file">
<script src="<cfoutput>#Application.fileAutoTimestamp.cacheBuster(request._js_file)#</cfoutput>"></script>
</cfloop>
</body>
</html>