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