Skip to content

HTML Helper Property

thofrey edited this page Apr 1, 2014 · 16 revisions

Table of Contents

  1. Quick Reference
  2. Overview
  3. How the Helper Can Help You Make Your Applications Run Faster
  4. Configuration
  5. Asset Timestamps
  6. Using the Helper
  7. Public Utility Methods
  8. Tips for updating code to use helper
  9. Using the HtmlHelperLoaderProperty
  10. Common Errors / Configuration Issues
  11. Planned Future Enhancements for Mach-II Integrity (1.9)

Quick Reference

<tr><td><a href="#addJavascriptBodyandthescriptcustomtag">addJavascriptBody(body:string [, outputType:string:"head", forIEVersion:string:""])</a></td></tr>
<tr><td><em>New in Mach-II 1.9</em> Allows the addition of inline content and wraps the code with an HTML script tag and CDATA to XHTML standards.</td></tr>

<tr><td><a href="#addStylesheetandthestylecustomtag">addStylesheet(href [, attributes:string/struct:StructNew(), outputType:string:"head", forIEVersion:string:""])</a></td></tr>
<tr><td>Takes a web-accessible path to a .css file and adds this file using valid HTML syntax to the head element (by default) at the end of the request.</td></tr>

<tr><td><a href="#addStylesheetBodyandthestylecustomtag">addStylesheetBody(body:string [, attributes:string/struct:StructNew(), outputType:string:"head", forIEVersion:string:""])</a></td></tr>
<tr><td><em>New in Mach-II 1.9</em> Allows the addition of inline styles and wraps the code with an HTML style tag and CDATA to XHTML standards.</td></tr>

<tr><td><a href="#addMetaandthemetacustomtag">addMeta(type:string, content:string [, outputType:string:"head"])</a></td></tr>
<tr><td>Adds an HTML meta tag into the HTML head section.</td></tr>

<tr><td><a href="#addLinkandthelinkcustomtag">addLink(type:string, href:string [, attributes:struct/string:StructNew(), outputType:string:"head"])</a></td></tr>
<tr><td>Used to output HTML links into the HTML head section such as rss feeds or icons links.</td></tr>

<tr><td><a href="#addImageandtheimagetag">addImage(src:string [, width:string:"-1", height:string:"-1", alt:string:"", attributes:string/struct:StructNew()])</a></td></tr>
<tr><td>Used to generate an HTML img tag with an asset timestamp.</td></tr>

<tr><td><a href="#addDocTypeanddoctypecustomtag">addDocType([type:string:"xhtml-1.0-strict"])</td></tr>
<tr><td>Outputs the specified doctype to the head.</td></tr>

<tr><td><a href="#addCharsetandcharsetcustomtag">addCharset([charset:string:"utf-8", outputType:string:"head"])</a></td></tr>
<tr><td>Adds an HTML meta tag with a http-equiv that will indicate the character set of the document.</td></tr>

<tr><td><a href="#addAssetPackageandtheassetcustomtag">addAssetPackage(package:string [, outputType:string:"head"])</a></td></tr>
<tr><td>Adds a group of assets (javascript and/or CSS files) to the document.</td></tr>
addJavascript(src:string/array/list [, outputType:string:"head", forIEVersion:string:""])
Takes a web-accessible path to a .js file and adds this file using valid HTML syntax to the head element (by default) at the end of the request.

Overview

As Web developers, we are readily aware that each request in our application has a number of responsibilities. In a Mach-II application, for example, each request may need to process a login filter, notify a listener to retrieve a required data set, and execute a subroutine to build a composite view. In addition to these necessary tasks, most requests have more redundant responsibilities such as including necessary javascript files, CSS files, adding meta information, links such as RSS or icons and specifying the doctype for a request.

These redundant tasks collectively fall outside the scope of custom CFML application development, and instead are necessary parts of constructing a relatively basic HTML request. The Mach-II HtmlHelperProperty provides an easy way to alleviate the headache often associated with these types of tasks by managing them in an organized way.

Specifically, the HtmlHelperProperty allows you to:

  • Add JS files to the head or output inline
  • Add CSS files to the head or output inline
  • Add meta information (title, description, keywords) to the head or output inline
  • Add a HTML image inline including a file timestamp
  • Add a HTML document type (DocType) to a layout view to the head or output inline
  • Add a HTML link to an alternate document like an RSS feed, ATOM feed or shortcut icon to the head
  • Add a character set declaration (charset) to a layout view to the head or output inline
  • Add an asset package to the document (a group of JS and/or CSS files) to the head or output inline

The HtmlHelperProperty also takes care of appending asset timestamps to the end of all JS and CSS file paths by default. By setting a far future HTTP expiry date via your webserver for all CSS and JS files, this allows browser to cache the asset file for an "indefinite" period of time. If you update the asset file, the timestamp of the asset file will change (and thus the URL to asset) causing the browser to re-download that asset. Without this, most browsers will repeatedly download the same assets over and over. Appending a timestamp to the asset's URL is is a common technique for improving front-end performance of a web application.

The HtmlHelperProperty is bundled with Mach-II 1.8 or higher.

How the Helper Can Help You Make Your Applications Run Faster

We've reviewed and research all of the Yahoo! Best Practices. Here are the items that apply to the HTML Helper:

  • Add an Expires or a Cache-Control Header -- using the helper's asset cache timestamps
  • Put Stylesheets at the Top -- using outputType="head" when using script / style methods and custom tags
  • Put Scripts at the Bottom -- we have ticket (trac-wiki) #230 "enhancement: Add option to add JS before HTML body in HtmlProperty (closed: fixed)") filed for this already
  • Minify Javascript and CSS -- we have proof of concept in the works for JS compression however, CSS compression is a bit trickier without an external library
  • Remove Duplicate Scripts -- the helper keeps track of JS / CSS files already included so duplicates includes will not happen
  • Split Components Across Domains -- we've discussed this for to split assets served by the helper across multiple sub-domains if the helper is configured as so (asset hosts -- it's been discussed on the Mach-II Developers list)

Most of the other items on the list are things either the developer has to do with their code / webserver or does not apply.

Configuration

In true Mach-II spirit, adding and using this helper property is extremely simple. In fact, including it only requires a few lines in your mach-ii.xml configuration file. Depending on how your application is setup, you can probably get away with very few lines for configuration.

    <property name="html" type="MachII.properties.HtmlHelperProperty">
        <parameters>
            <parameter name="metaTitleSuffix" value=" - Mach-II" />
            <parameter name="cacheAssetPaths" value="false" />

            <!-- OR using environments groups / names -->
            <parameter name="cacheAssetPaths">
                <struct>
                    <key name="group:development" value="false" />
                    <key name="group:staging" value="false" />
                    <key name="group:qualityAssurance" value="false" />
                    <key name="group:production" value="false" />
                    <key name="specificEnvironmentName" value="true" />
                </struct>
            </parameter>

            <!-- Defaults to ExpandPath(".") -->
            <parameter name="webrootBasePath" value="/path/to/webroot" />

            <!-- Defaults to webroot base path + "/js" -->
            <parameter name="jsBasePath" value="/path/to/webroot/js" />

            <!-- Defaults to webroot base path + "/css" -->
            <parameter name="cssBasePath" value="/path/to/webroot/css" />

            <!-- Defaults to webroot base path + "/img" -->
            <parameter name="imgBasePath" value="/path/to/webroot/img" />

            <!--- See addPackage() method documentation for information
                    on configuration the packages parameter -->
        </parameters>
    </property>

metaTitleSuffix

The metaTitleSuffix parameter is optional and if defined automatically appends the value of the parameter on the end of the passed value of the addMeta() method when calling with a type of title. For example, calling addMeta("title", "Home") could result in <title>Home - Mach-II</title'. This is especially useful to append a company or application name on to the end of every HTML title.

cacheAssetPaths

The cacheAssetPaths parameter is optional and takes a boolean. It defaults to false if not defined. This parameter enables or disables caching of the asset paths (paths passed into addJs and addCss methods) and their respective timestamps. If the cache is enabled (true), the asset tag makes fewer file system calls to compute the timestamp for the specified asset. File system interaction can be expensive and therefore can have a negative impact on application performance.

We recommend that the cache is enabled when the application is deployed to production. However, enabling the cache prevents you from modifying any asset files after the application has loaded (meaning browsers will not get an updated asset path unless you reload your Mach-II application). In order to easily develop a Mach-II application, we recommend using the `EnvironmentProperty` which sets the deployment environment and indicating the environments that the asset path cache should be enabled on:

    <property name="html" type="MachII.properties.HtmlHelperProperty">
        <parameters>
            <!-- ... other parameters ... -->
            <parameter name="cacheAssetPaths">
                <struct>
                    <key name="group:qualityAssurance,production" value="true" />
                    <key name="someProductionEnvironmentName" value="true" />
                </struct>
            </parameter>
        </parameters>
    </property>

In the example above, the asset path caching is only enabled on qualityAssurance and production environments. This is denoted by using the group: prefix in the key name and this can take a list of environment group names. Remember, each environment is assigned to a general environment group. Sometimes, you will need to explicitly set a particular environment by name (not a group. An example of an concrete environment by name is demonstrated by the someProductionEnvironmentName which would have caching turned off. This can also take a list of environment names such as <key name="someEnvironmentName,anotherEnvironementName" value="false"/>. By default if an environment is not defined, the caching will be disabled (false).

The resolution order environments names and groups when using environments:

  • by explicit environment name
  • by environment group
  • by default value (if provided - not applicable for HtmlHelperProperty)
  • thrown exception

webrootBasePath

Defines the web root of your application. By default, the value of this parameter is the result of ExpandPath('.') which should be the location of your Application.cfc. If you define a custom path, the helper will automatically apply ExpandPath to the path. ` If your Mach-II application lives in a directory off the root of your web domain, the webrootBasePath should point to the rootof your web domain not the root of your application. For example if your application lives at http://www.example.com/coolApp, your webrootBasePath should resolve to the directory where example.com exists. Your jsBasePath, cssBasePath and imgBasePath will be something like /coolApp/js, /coolApp/css and /coolApp/img respectively.

jsBasePath

Defines the path to where your javascript assets are located. By default, this value of this parameter is the webrootBasePath + /js. If you define a custom path, this path is relative from the value of webrootBasePath. For example, if your javascript files are located in http://www.example.com/assets/js, then set the value of this parameter to /assets/js.

This parameter is used for resolving paths that are passed to the addJs() method using the shorthand syntax and to compute the timestamp value of the file (by reading the data off the disk).

cssBasePath

Defines the path to where your cascading style sheet assets are located. By default, this value of this parameter is the webrootBasePath + /css. If you define a custom path, this path is relative from the value of webrootBasePath. For example, if your CSS files are located in http://www.example.com/assets/css, then set the value of this parameter to /assets/css.

This parameter is used for resolving paths that are passed to the addCss() method using the shorthand syntax and to compute the timestamp value of the file (by reading the data off the disk).

imgBasePath

Defines the path to where your image assets are located. By default, this value of this parameter is the webrootBasePath + /img. If you define a custom path, this path is relative from the value of webrootBasePath. For example, if your image files are located in http://www.example.com/assets/img, then set the value of this parameter to /assets/img.

This parameter is used for resolving paths that are passed to the addImage() method using the shorthand syntax and to compute the timestamp value of the file (by reading the data off the disk).

assetPackages

See addAssetPackage() method for additional information on what an asset package is, how to configure them and how to leverage asset packages in your application.

Thoughts on Path Configuration

The HtmlHelperProperty cannot be configured to use assets (JS/CSS) that are mapping using virtual directories such as in IIS. This is because any CFML engine does not know the that virtual directories exist because those mappings are outside of the context of the CFML engine (i.e. wrong layer of application server architecture stack). All paths are computed from the root of your domain or the value that exists in the webRootBasePath if you provide an absolute path from the root or using the JS and CSS base paths if using a relative path.

Some people have asked for an enhancement to support virtual paths however the addition of this "feature" is more of a philosophical discussion in the terms of ideal application deployment situation versus actual engineering of the "feature". Most people use virtual directory so they can access shared assets (think JS/CSS files) across many application or domains. While in theory this seems to simplify your deployment, you are actually introducing possible side effects or problems for yourself in the future. This is because in one application you might decide to update assets that are shared across multiple application via a virtual directory because you need feature "XYZ". However, because you upgraded those assets you have unknowingly broken another application because it relied on a deprecated feature or undocumented feature available in that set of assets. This is the the law of unintended consequences for using this shortcut.

This is why we recommend that an application should be able to be deployed as a whole instead deploying major part of it (without shared assets) and relying on virtual directories being available for it to function. You may ask the question of "well, I was using virtual directories to simply the duplication of code through shared assets and how do I solve that?" The simple answer is to use your version control system (such as svn:external in Subversion) to virtually include an entire or part of an external repository into your application's repository (you should be using version control anyways). This way you can version in separate directories different releases of a group of assets (think something like /Prototype/1.5 and /Prototype/1.6) and that way your application will be able to get the version it needs. If you want to upgrade it, it should happen with the oversight of a developer doing it explicitly instead of an "auto-upgrade" occurs if you just dump new versions of Prototype in a virtual directory. Another option if you sharing assets such as major javascript frameworks (Prototype, Dojo, JQuery, etc) is to use Google AJAX Libraries API.

Asset Timestamps

The HtmlHelperProperty also takes care of appending asset timestamps to the end of all images (via addImage), JS (via addJavascript) and CSS (via addStylesheet) file paths by default. By setting a far future HTTP expiry date headers via your webserver for all image, CSS and JS files, this allows browser to cache the asset file for an "indefinite" period of time. There are several benefits to browser caching since the browser does not have to request the same files repeatedly:

  • Fewer HTTP requests after the browser cache has been primed which improves front-end performance of your application
  • Reduced load on your server
  • Reduced bandwidth usage

One trade off is when you update the asset file. The timestamp of the asset file will change (and thus the URL to asset) causing the browser to re-download that asset. Without this, most browsers will repeatedly download the same assets over and over. Appending a timestamp to the asset's URL is a common technique for improving front-end performance of a web application. Asset timestamps are expressed as the number of seconds from Unix epoch (which is January 1, 1970 00:00:00 UTC) and look like `/path/to/mypic.jpg?1234578803.

It is the responsibility of the web server you use to set the far-future for assets if you want to leverage this future. Example configuration for Apache that sets the expiration date for all CSS and JS assets one year in the future:

    ExpiresActive On
    <FilesMatch "\.(js|css)$">
        ExpiresDefault "access plus 1 year"
    </FilesMatch>

Warnings About Asset Timestamps

All assets must have the same timestamp on all webservers if you are using this feature in a clustered environment. If they do not have the same timestamp, the timestamp appended to the end of the asset path will differ from server to server and therefore the cache will be ineffective because the full URLs for assets will differ. A few points of advice using asset timestamps on a clustered architecture:

  • If you are deploying code via FTP, be sure to use your FTP client to save to "preserve file timestamps" when deploying your code base.
  • Synchronize the clocks on each server using a program such as the NTP daemon on Linux.
  • Deploy all code to network attached storage device (NAS) instead of individual servers.

Also, if you are using Mach-II Caching, any asset timestamps will be cached as well so be careful if you are using Mach-II caching in which there are assets that change frequently. This is usually not a common problem, however changes to assets will require you to flush Mach-II cached items if you want the timestamps (and therefore the newer versions) on the files to be re-downloaded by the browser.

Using the Helper

Since the HtmlHelperProperty is merely another Mach-II property, calling a method inside a Mach-II view is as easy as pie by getting the property from the Mach-II property manager and calling the desired method:

Via Methods

Source code:

    <cfoutput>#getProperty("html").addDocType()#</cfoutput>

Output:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

N.B. The addDocType method outputs the doctype and does not have any option to append the doctype to head since the doctype resides above the HTML head section.

Via View Custom Tag Library

As with any custom tag library, you must import it at the top of each page that uses the tag library. This only has to be done once per page, but all example in this documentation will consistently show how to import the tag library.

Source Code

    <cfimport prefix="view" taglib="/MachII/customtags/view" />
    <view:doctype />

Output:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

addJavascript() and the script custom tag

This method/tag takes a web-accessible path to a .js file and adds this file using valid HTML syntax to the head element at the end of the request. It would also check to see if that element was already added to head so duplicates are not added in case the .js file was added the head earlier in the request. The path argument would take a string (single path), list (multiple js files) or an array. The outputType argument would either output the values directly or if false it would use the Mach-II method addHTMLHeadElement() (which basically wraps <cfhtmlhead>) to output the values at the end of the request. By default, the output is appended to the HTML head area.

Adding an entire library could be as easy as providing a list/array of full paths or names. By default if you do not pass a full path (i.e. /js/prototype.js), the helper will automatically look for the javascript file in the jsBasePath location as defined in the configuration of the helper. Also, it is not required to provided a file extension in which the helper will append .js to any javascript asset that does not have a file extension. Essentially, both the first and second lines of the example below will produce the same output.

Using the addJavascript() method call

Source Code:

    <!-- Using full paths -->
    <cfset getProperty("html").addJavascript("/js/prototype.js,/js/effects.js,/js/lightwindow.js") />

    <!-- Using shorthand paths -->
    <cfset getProperty("html").addJavascript("prototype,effects,lightwindow") />

Output:

    <script type="text/javascript" src="/js/prototype.js?1233233140"></script>
    <script type="text/javascript" src="/js/effects.js?1194373101"></script>
    <script type="text/javascript" src="/js/lightwindow.js?1233063280"></script>

Using the script tag

The script tag can also be used to include external javascript files.

Source Code:

    <!-- Using full paths -->
    <view:script src="/js/prototype.js,/js/effects.js,/js/lightwindow.js" />
    <!-- Using shorthand paths -->
    <view:script src="prototype,effects,lightwindow" />

Output (both examples above produce the same output in the HTML head section by default):

    <script type="text/javascript" src="/js/prototype.js?1233233140"></script>
    <script type="text/javascript" src="/js/effects.js?1194373101"></script>
    <script type="text/javascript" src="/js/lightwindow.js?1233063280"></script>

A Word About Deeply nested paths

Adding javascript assets that are nested in your jsBasePath directory is simple as well. Just provider the directory relative to the jsBasePath:

    <!-- Add a js file located in /js/nested/deep/generic.js -->
    <cfset getProperty("html").addJavascript("nested/deep/generic") />

Output:

    <script type="text/javascript" src="/js/nested/deep/generic.js?"></script>

Method Arguments & Tag Attributes

Both the method arguments and tag attribute are shared and the same. The method call offers flexibility in non-view code while the tag based version is more convenient for views and non-technical people to use.

    addJavascript(src, outputType, forIEVersion)
    <view:script src="pathHere"  outputType="head|body|inline" forIEVersion="" />
Name Required Datatype / Values Description
src required string, comma-delimited list or array Web accessible paths to .js files. Paths that do not begin with / will be looked in the jsBasePath directory. Paths that do no end with .js will automatically get that file extension appended to them. When using external JS assets, use the external: keyword (ex. external:http://www.example.com/js/somefile.js). This keyword is available in 1.8.1+.
outputType optional head, body (1.9+ and OpenBD only) or inline (defaults to head) Where to output the generated code to. head will output to the HTML head area and inline will return the code to be returned (you must use #'s around the method call to output returned content or assign the return content to a variable).
forIEVersion optional string Optionally wraps the code output in an IE conditional. See above for configuration options.

addJavascriptBody() and the script custom tag

New in Mach-II 1.9

The addJavascriptBody method provides similar functionality as the addJavascript method but allows the addition of inline content rather than attaching an external javascript file. The inline code is wrapped with an HTML script tag and CDATA to XHTML standards.

Using the addJavascriptBody() method call

Source Code:

    <cfset getProperty("html").addJavascriptBody("$(document).ready(doSomething);") />

Output:

    <script type="text/javascript">
    //<![CDATA[
        $(document).ready(doSomething);
    //]]>
    </script>

Using the script tag

The script tag takes any nested javascript code and wraps the code with an HTML script tag and CDATA to XHTML standards. It then adds the code block to the HTML section via the HtmlHelperProperty or optionally outputs the code block inline.

Example for inline ad-hoc code:

    <cfimport prefix="view" taglib="/MachII/customtags/view" />

    <view:script>
        Event.observe(window, 'load', startTimer);

        function startTimer() {
            var timer = new Timer(300);
        }
    </view:script>

Example output for inline ad-hoc code (in HTML head section):

    <script type="text/javascript">
    // <![CDATA[
      Event.observe(window, 'load', startTimer);

      function startTimer() {
        var timer = new Timer(300);
      }
    // ]]>
    </script>

Method Arguments & Tag Attributes

Both the method arguments and tag attribute are shared and the same. The method call offers flexibility in non-view code while the tag based version is more convenient for views and non-technical people to use.

    addJavascriptBody(body, outputType?, forIEVersion?)
    <view:script outputType="head|body|inline" forIEVersion="">body</view:script>
Name Required Datatype / Values Description
body required string Javascript content to be positioned within a script tag
outputType optional head, body (1.9+ and OpenBD only) or inline (defaults to head) Where to output the generated code to. head will output to the HTML head area and inline will return the code to be returned (you must use #'s around the method call to output returned content or assign the returned content to a variable).
forIEVersion optional string Optionally wraps the code output in an IE conditional. See above for configuration options.

See support for IE conditionals in the script tag for usage.

addStylesheet() and the style custom tag

This method takes a web-accessible path to a .css file and adds this file using valid HTML syntax to the head element at the end of the request. It would check and eliminate duplicates in a similar fashion to how addJavascript() works. The outputType argument would either output the values directly or if false it would use the Mach-II method addHTMLHeadElement() (which basically wraps <cfhtmlhead>) to output the values at the end of the request. By default, the output is appended to the HTML head area.

By default if you do not pass a full path (i.e. /css/basic.js), the helper will automatically look for the CSS file in the cssBasePath location as defined in the configuration of the helper. Also, it is not required to provided a file extension in which the helper will append .css to any CSS asset that does not have a file extension. Essentially, both the first and second lines of the example below will produce the same output.

Using the addStylesheet() method call

Source Code:

    <!-- Using full paths -->
    <cfset getProperty("html").addStylesheet("/css/lightbox.css", "media=screen") />

    <!-- Using shorthand paths -->
    <cfset getProperty("html").addStylesheet("lightbox", "media=screen") />

Output:

    <link type="text/css" href="/css/lightbox.css?1194373101" rel="stylesheet" media="screen" />

The above examples in the source code section produces the same output. The difference is that one of the source code examples uses a full path and the other uses a shorthand path.

Using the style tag

The script tag takes any nested CSS code and wraps the code with an HTML style tag and CDATA the code to XTHML standards. If the href attribute is defined, it takes the data and create the appropriate HTML link tag code for the external stylesheet. Either way, the tag then adds the code block (HTML style or link to the HTML section using the Mach-II method addHTMLHeadElement() or optionally outputs the code block inline. If both ad-hoc nested CSS code and href attribute is defined, the tag creates the HTML link tag first before creating the style tag for the ad-hoc CSS.

Example for external stylesheets:

    <cfimport prefix="view" taglib="/MachII/customtags/view" />

    <!-- Using full paths -->
    <view:style href="/css/lightbox.css" media="screen" />

    <!-- Using shorthand paths -->
    <view:style href="lightbox" media="screen" />

Output for external stylesheets (both the full and shortcut path examples above produce the same output):

    <link type="text/css" href="/css/lightbox.css?1194373101" rel="stylesheet" media="screen" />

Support for IE Conditionals

The addStylesheet method and script tag supports optionally wrapping the generated style tag with IE conditions. Only IE obeys these conditionals while non-IE browsers ignore the stylesheet because the conditional is inside an HTML comment (e.g. <!-- comment -->).

IE conditionals can direct IE to load a stylesheet based on IE version with an optional operator. Here is an example of IE conditional comments in use with addStylesheet that directs IE to only load the stylesheet if the IE version 6 using the forIEVersion argument (which is in the third position):

Source Code:

    <cfset getProperty("html").addStylesheet("lightbox", "", "inline", "6") />
    <view:style href="lightbox" outputType="inline" forIEVersion="6" />

Output (both method and tag examples above produce the same output):

    <!--[if IE 6]>
    <link type="text/css" href="/css/lightbox.css?1194373101" rel="stylesheet" media="screen" />
    <![endif]-->

IE conditionals also support operators lt and gte. For example if you only want to load a stylesheet for IE greater than or equal to version 7, you would use this:

Source Code:

    <cfset getProperty("html").addStylesheet("lightbox", "", "head", "gte 7") />
    <viwe:style href="lightbox" outputType="head" forIEVersion="gte 7" />

Output (both method and tag examples above produce the same output):

    <!--[if gte IE 7]>
    <link type="text/css" href="/css/lightbox.css?1194373101" rel="stylesheet" media="screen" />
    <![endif]-->

If you want to direct all versions of IE to load the stylesheet, use the all keyword. The all keyword is specific to how the HtmlHelperProperty implements the API for conditional IE:

Source Code:

    <cfset getProperty("html").addStylesheet("lightbox", "", "head", "all") />
    <viwe:style href="lightbox" outputType="head" forIEVersion="all" />

Output (both method and tag examples above produce the same output):

    <!--[if IE]>
    <link type="text/css" href="/css/lightbox.css?1194373101" rel="stylesheet" media="screen" />
    <![endif]-->

Method Arguments & Tag Attributes

    addStylesheet(href, [attributes, outputType, forIEVersion])
    <view:style href="" media="screen" forIEVersion="lt 7" />
Name Required Datatype / Values Description
href required string, comma-delimited list or array Web accessible paths to .css files. Paths that do not begin with / will be looked in the cssBasePath directory. Paths that do no end with .css will automatically get that file extension appended to them. When using external CSS assets, use the external: keyword (ex. external:http://www.example.com/css/somefile.css). This keyword is available in 1.8.1+.
attributes optional struct or string name value pairs (`param1=value1 param2=value2`)
outputType optional head (default), body (1.9+ and OpenBD only) or inline Where to output the generated code to. head will output to the HTML head area and inline will return the code to be returned (you must use #'s around the method call to output returned content or assign the return content to a variable).
forIEVersion optional string Optionally wraps the code output in an IE conditional. See above for configuration options.

addStylesheetBody() and the style custom tag

New in Mach-II 1.9

The addStylesheetBody method provides similar functionality as the addStylesheet method but allows the addition of inline content rather than attaching an external stylesheet file. The inline code is wrapped with an HTML style tag and CDATA to XHTML standards.

Using the addStylesheetBody() method call

Source Code:

    <cfset getProperty("html").addStylesheetBody(".body { background-color: #FF0000; }") />

Output:

    <style type="text/css">
    /*<![CDATA[*/
    .body { background-color: #FF0000; }
    /*]]>*/
    </style>

Using the style tag

The script tag takes any nested CSS code and wraps the code with an HTML style tag and CDATA the code to XTHML standards. If the href attribute is defined, it takes the data and create the appropriate HTML link tag code for the external stylesheet. Either way, the tag then adds the code block (HTML style or link to the HTML section using the Mach-II method addHTMLHeadElement() or optionally outputs the code block inline. If both ad-hoc nested CSS code and href attribute is defined, the tag creates the HTML link tag first before creating the style tag for the ad-hoc CSS.

Example for ad-hoc CSS:

    <cfimport prefix="view" taglib="/MachII/customtags/view" />

    <view:style>
        .someClass { color: #000000; }
    </view:style>

Ouput for ad-hoc CSS (outputType attribute defaults to head which puts the code HTML head section):

    <style type="text/css">
    /* <![CDATA[//> */
        .someClass { color: #000000; }
    /* ]]> */
    </style>

Example for ad-hoc CSS and external stylehseets:

    <cfimport prefix="view" taglib="/MachII/customtags/view" />

    <!--- Using shortcut for hrefs --->
    <view:style href="generic01,generci02" media="screen">
        .someClass { color: #000000; }
    </view:style>

Ouput for ad-hoc CSS and external stylesheets:

    <link type="text/css" href="/css/generic01.css?1194913101" rel="stylesheet" media="screen" />
    <link type="text/css" href="/css/generic02.css?1194918807" rel="stylesheet" media="screen" />
    <style type="text/css">
    /* <![CDATA[//> */
        .someClass { color: #000000; }
    /* ]]> */
    </style>

Support for IE Conditionals

Prior to Mach-II 1.9 you needed to use the style tag for ad-hoc CSS code:

Source Code:'

    <cfimport prefix="view" taglib="/MachII/customtags/view" />

    <view:style forIEVersion="gte 7">
        .someClass { color: #000000; }
    </view:style>

Output:

    <!--[if gte IE 7]>
    <style type="text/css">
    /*<![CDATA[*/
      .someClass { color: #000000; }
    /*]]>*/
    </style>
    <![endif]-->

In Mach-II 1.9+ you can use the addJavascriptBody method:

Source Code:

    <cfset getProperty("html").addJavascriptBody(".someClass { color: #000000; }", "head", "gte 7") />

Output:

    <!---[if gte IE 7>
    <style type="text/css">
    /*<![CDATA[*/
    .someClass { color: #000000; }
    /*]]>*/
    </style>
<![endif]-->

If you want to direct all versions of IE to load the ad-hoc, use the all keyword. The all keyword is specific to how the style tag implements the API for conditional IE:

Source Code:'

    <cfimport prefix="view" taglib="/MachII/customtags/view" />

    <view:style forIEVersion="all">
        .someClass { color: #000000; }
    </view:style>

Output:

    <!--[if IE]>
    <style type="text/css">
    /* <![CDATA[//> */
        .someClass { color: #000000; }
    /* ]]> */
    </style>
    <![endif]-->

For more in-depth information, read Quirks Mode's IE Condition Comments article.

Method Arguments & Tag Attributes

    addStylesheetBody(body, [attributes, outputType, forIEVersion])
    <view:style media="screen" forIEVersion="lt 7">body</view:style>
Name Required Datatype / Values Description
body required string HTML style to be wrapped in HTML style tags.
attributes optional struct or string name value pairs (`param1=value1 param2=value2`)
outputType optional head (default), body (1.9+ and OpenBD only) or inline Where to output the generated code to. head will output to the HTML head area and inline will return the code to be returned (you must use #'s around the method call to output returned content or assign the return content to a variable).
forIEVersion optional string Optionally wraps the code output in an IE conditional. See above for configuration options.

addMeta() and the meta custom tag

This method and tag adds an HTML meta tag into the HTML head section. So in your view you can call getProperty("html").addMeta("keywords", "list,of,keywords") or getProperty("html").addMeta("title", "Title of Page"). This method or tag auto-selects if the HTML meta tag should use the name or http-equiv attribute depending on the value passed in type argument. The outputType argument would either output the values directly or if false it would use the Mach-II method addHTMLHeadElement() (which basically wraps <cfhtmlhead>) to output the values at the end of the request. By default, the output is appended to the HTML head area.

The following types will be auto-selected to use the http-equiv attribute when building a meta tag:

  • allow
  • content-encoding
  • content-language
  • content-length
  • content-type
  • date
  • expires
  • last-modified
  • location
  • refresh
  • set-cookie
  • www-authenticate

The following types will be auto-selected to use the name attribute when building a meta tag:

  • author
  • copyright
  • description
  • distribution
  • generator
  • keywords
  • progid
  • rating
  • resource-type
  • revisit-after
  • robots
  • others

If you want to explicitly indicate if the value should be of type name or http-equiv then prefix the type with (available in Mach-II 1.9+):

  • name:type
  • http-equiv:type
    <cfset getProperty("html").addMeta("http-equiv:X-UA-Compatible", "true") />

A word about the value of title for the type attribute

The type of title produces a HTML title tag. This is one exception to the addMeta() method that will not generate a HTML meta tag. If the type is title, the HtmlHelperProperty will automatically append the value set in the metaTitleSuffix parameter (is defined) when the property was configured.

Using the addMeta() method call

Using the method:

Source Code:

    <cfset getProperty("html").addMeta("title", "Title of This Page") />
    <cfset getProperty("html").addMeta("keywords", "list,of,keywords") />
    <cfset getProperty("html").addMeta("description", "I'm a very cool description and peanut butter is awesome by the way.") />
    <cfset getProperty("html").addMeta("robots", "index,follow") />
    <cfset getProperty("html").addMeta("refresh", "1830") />

Output:

    <title>Title of This Page</title>
    <meta name="keywords" content="list,of,keywords" />
    <meta name="description" content="I'm a very cool description and peanut butter is awesome by the way." />
    <meta name="robots" content="index,follow" />
    <meta http-equiv="refresh" content="1830" />

Using the meta tag

Using the custom tag:

Source Code:

    <cfimport prefix="view" taglib="/MachII/customtags/view" />

    <view:meta type="title" content="Title of This Page" />
    <view:meta type="keywords" content="list,of,keywords" />
    <view:meta type="description" content="I'm a very cool description and peanut butter is awesome by the way." />
    <view:meta type="robots" content="index,follow" />
    <view:meta type="refresh" content="1830" />

Output:

    <title>Title of This Page</title>
    <meta name="keywords" content="list,of,keywords" />
    <meta name="description" content="I'm a very cool description and peanut butter is awesome by the way." />
    <meta name="robots" content="index,follow" />
    <meta http-equiv="refresh" content="1830" />

Method Arguments & Tag Attributes

    addMeta(type, content, outputType)
    <view:meta type="" content="" outputType="" />
Name Required Datatype / Values Description
type required string The type of the meta tag (this method auto-selects if value is a meta type of http-equiv or name). You can force the usages of http-equiv or name by using type="http-equiv:value"ortype="name:value"` (forcing type in Mach-II 1.9+).
content required string The content of the meta tag.
outputType optional head (default), body (1.9+ and OpenBD only) or inline Where to output the generated code to. head will output to the HTML head area and inline will return the code to be returned (you must use #'s around the method call to output returned content or assign the return content to a variable).

addLink() and the link custom tag

This method and tag is used to output HTML links into the HTML head section such as rss feeds or icons links. This feature auto-selects the type, rel and title attributes depending on the value passed in the type argument of this method. We support type shortcuts for icon, rss, atom, html and canonical, otherwise a complete MIME type is required. By default, the outputType appends to the HTML head area.

Using the addLink() method

Source Code Using Type Shortcuts:

    <cfset getProperty("html").addLink("rss", "/path/to/rssFeed.cfm") />
    <cfset getProperty("html").addLink("atom", "/path/to/atomFeed.cfm") />
    <cfset getProperty("html").addLink("html", "/path/to/someHTML.cfm") />
    <cfset getProperty("html").addLink("icon", "/path/to/yourSiteIcon.ico") />
    <cfset getProperty("html").addLink("canonical", buildRouteUrl("home")) />

Output for Links Using Type Shortcuts:

    <link rel="alternate" type="application/rss+xml" href="/path/to/rssFeed.cfm" />
    <link rel="alternate" type="application/atom+xml" href="/path/to/atomFeed.cfm" />
    <link rel="alternate" type="text/html" href="/path/to/someHTML.cfm" />
    <link rel="shortcut icon" type="image/x-icon" href="/path/to/youtSiteIcon.ico" />
    <link rel="canonical" href="/index.cfm/home/" />

Using the link custom tag

Source Code Using Type Shortcuts:

    <cfimport prefix="view" taglib="/MachII/customtags/view" />

    <view:link type="rss" href="/path/to/rssFeed.cfm" />
    <view:link type="atom" href="/path/to/atomFeed.cfm" />
    <view:link type="html" href="/path/to/someHTML.cfm" />
    <view:link type="icon" href="/path/to/yourSiteIcon.ico" />
    <view:link type="canonical" route="home" />

N.B. The special usage of the route attribute to build a route style url similar to the a custom tag in the view library.

Output for Links Using Type Shortcuts:

    <link rel="alternate" type="application/rss+xml" href="/path/to/rssFeed.cfm" />
    <link rel="alternate" type="application/atom+xml" href="/path/to/atomFeed.cfm" />
    <link rel="alternate" type="text/html" href="/path/to/someHTML.cfm" />
    <link rel="shortcut icon" type="image/x-icon" href="/path/to/youtSiteIcon.ico" />
    <link rel="canonical" href="/index.cfm/home/" />

Warnings

As specified by the HTML specification by the W3C governing body, all HTML <link> tags must be the HTML head section. By default, the addLink method adds the output to head unless the outputType argument is changed to inline. The inline value of the outputType argument has limited usage and should only be used when inside an HTML head section directly.

Method Arguments & Tag Attributes

addLink(type, href, attributes, outputType)
<view:link type="" href="" outputType="" />
Name Required Datatype / Values Description
type required string (shortcut type or MIME type) The type of link. Supports type shortcuts icon, rss, atom and html, otherwise a complete MIME type is required. Shortcut types will automatically set the rel attribute.
href required string A the path to a web accessible location of the link file.
attributes optional struct or string name value pairs (`param1=value1 param2=value2`)
outputType optional head (default), body (1.9+ and OpenBD only) or inline Where to output the generated code to. head will output to the HTML head area and inline will return the code to be returned (you must use #'s around the method call to output returned content or assign the return content to a variable).

For the link custom tag, the following attributes are available to build urls for the href attribute:

Name Required Default Description
event required (or route / useCurrentUrl) n/a The event name to build the URL with (cannot be used with route or useCurrentUrl)
module optional current module name The module name to build the URL with (not valid with route or useCurrentUrl)
route required (or event / useCurrentUrl) n/a The route name to build the URL with (cannot be used with event or useCurrentUrl)
useCurrentUrl optional n/a Indicates to use the current URL as a basis to build the link (cannot be used with event or route)
p optional n/a Name / value pair list or struct of URL parameters to build the URL with. Can contain EL syntax for values.
q optional n/a Name / value pair list or struct of query string parameters to append to the end of a route (only valid with route). Can contain EL syntax for values.
x optional n/a Name / value pair list or struct of additional non-standard attribute to insert into the rendered tag output

addImage() and the image tag

This method and tag can be used to generate an HTML img tag with an asset timestamp. The end result is no different from a hand-coded HTML img tag accept you get the added powerfulness of asset timestamps (read about asset timestamps above). Unlike the other methods in the helper or other custom tags, you cannot output the generated code produced by this method into the HTML head since that is not allowable by the W3C specification for HTML nor would it be useful.

Using the addImage() method

Source Code:

    #getProperty("html").addImage("MichaelJackson.jpg", 150, 120, "The King of Pop")#

Output:

    <img src="/img/MichaelJackson.jpg?1234767140" width="150" height="120" alt="The King of Pop" />

Using the img custom tag

Source Code:

    <cfimport prefix="view" taglib="/MachII/customtags/view" />
    <view:img src="MichaelJackson.jpg" width="150" height="120" alt="The King of Pop" />

Output:

    <img src="/img/MichaelJackson.jpg?1234767140" width="150" height="120" alt="The King of Pop" />

Image Auto-Dimensions "Magic"

N.B. This functionality was added after Mach-II 1.8 Beta 1 was released. Use the BER or a newer release if available.

We're not done with the magic of the HTML helper yet. One of the largest annoyances with HTML img tags is having to know the height and width of the image (provided you care about giving this information to the browser for performance). No longer do you have to constantly look you the image dimensions. If you want to use auto-dimensions, just don't provide a height or width when using addImage and the helper will look that up for you automatically. Be aware this functionality only works with image types of GIF, PNG and JPG.

Source Code (both the method and tag produce the same output):

    #getProperty("html").addImage("PeterFarrellIsLazy.jpg", "", "", "Because he hates having to remember image dimensions")#
    <view:img src="PeterFarrellIsLazy.jpg" alt="Because he hates having to remember image dimensions" />

Notice that we are not providing a height or width.

Output:

    <img src="/img/PeterFarrellIsLazy.jpg?1234767140" width="300" height="450" alt="Because he hates having to remember image dimensions" />

Both the method and tag reads the height and width for the image automatically for us since we did not provide it.

Warnings

The auto-dimension "magic" makes use of the java.awt.* Java package to perform reading the image metadata. Many server environments these days do not support a display, a keyboard or a mouse as they are administered via SSH (console) over a network. These types of environments are called headless and can cause problems with Java packages like AWT because displaying/manipulating graphics assumes certain hardware like a video card / monitor. This can be solved by enabling headless mode which uses software to emulate missing hardware. If your server is not currently setup for headless mode, things like chchart or cfdocument probably will not work as they rely on the AWT package as well. The most common exception you can get is an exception type similar to this:

    java.awt.HeadlessException

They may be an additional message depending on the AWT subsystem being used.

The good news that you can enable support by adding follow property to the jvm.confg file in Adobe ColdFusion or your java properties for your application server (such as Tomcat, Jetty, JBoss, etc.):

    -Djava.awt.headless=true

We cannot shows all the ways headless support can be enabled because it depends on your server setup. There is plenty of information via Google or feel free to contact the Mach-II Google Group for more help. We wanted to document it here in case people run into any problems.

Method Arguments & Tag Attributes

    addImage(src, width, height, alt, attributes)
    <view:img src="" width="" height="" alt="" />
Name Required Datatype / Values Description
src true string A path to a web accessible image file. Shortcut paths are allowed, however file name extensions cannot be omitted (as in the addStylesheet method ) and must be specified. When using external image assets, use the external: keyword (ex. external:http://www.example.com/img/coolpeeps.jpg). This keyword is available in 1.8.1+.
width false string The width of the image in pixels or percentage if a percent sign % is defined. A value of '-1' will cause this attribute to be omitted from the generated code. Providing a zero-length string (i.e. "") will have the image dimensions read from the image file (only works with GIF, PNG and JPG image types).
height false string The height of the image in pixels or percentage if a percent sign % is defined. A value of '-1' will cause this attribute to be omitted from the generated code. Providing a zero-length string (i.e. "") will have the image dimensions read from the image file (only works with GIF, PNG and JPG image types).
alt false string The text for the 'alt' attribute and automatically HTMLEditFormats the value. If not defined, the value of alt="" will be used as this attribute is required by the W3C specification.
attributes false string/struct A struct or string (`param1=value1

For the img custom tag, the following attributes are available to build urls to dynamic images for the src attribute:

Name Required Default Description
event required (or route / useCurrentUrl) n/a The event name to build the URL with (cannot be used with route or useCurrentUrl)
module optional current module name The module name to build the URL with (not valid with route or useCurrentUrl)
route required (or event / useCurrentUrl) n/a The route name to build the URL with (cannot be used with event or useCurrentUrl)
useCurrentUrl optional n/a Indicates to use the current URL as a basis to build the link (cannot be used with event or route)
p optional n/a Name / value pair list or struct of URL parameters to build the URL with. Can contain EL syntax for values.
q optional n/a Name / value pair list or struct of query string parameters to append to the end of a route (only valid with route). Can contain EL syntax for values.
x optional n/a Name / value pair list or struct of additional non-standard attribute to insert into the rendered tag output

addDocType() and doctype custom tag

Let's be truthfully honest, you can never remember the complete doc types and there respective DTD locations can you? If you can remember all of them, we do not know why you are wasting your brain cells (provided you are not an employee of the W3C). As a nice convenience, just call getProperty("html").addDocType() in your layout to have (by default) an XHTML strict doctype outputted for you.

Using the addDocType() method

Source code (see note below on the usage of #'s around the method call instead of a cfset):

    #getProperty("html").addDocType()#

Output:'

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

If you need to output a doctype other than XHTML-Strict, you can pass in the doctype you need to method as an argument. For example if you need HTML 4.0 strict, you would call getProperty("html").addDocType("html-4.0-strict").

Using the doctype custom tag

Source code (see note below on the usage of #'s around the method call instead of a cfset):

    <cfimport prefix="view" taglib="/MachII/customtags/view" />
    <view:doctype />

Output:'

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

If you need to output a doctype other than XHTML-Strict, you can pass in the doctype you need to method as an argument. For example if you need HTML 4.0 strict, you would call <view:doctype type="html-4.0-strict" />.

Output Type Warning

Doctypes reside above the HTML head section and cannot reside at any other location within the HTML document as specified by HTML specifications by the governing W3C body. Due to the HTML specification, the only option is to output the returned content directly by wrapping the method call in #'s or to assign the returned content to a variable so you can use it later by outputting that variable.

Key Output Mach-II Version
xhtml-1.0-strict <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 1.8
xhtml-1.0-trans <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 1.8
xhtml-1.0-frame <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> 1.8
xhtml-1.1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> 1.8
html-4.0-strict <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 1.8
html-4.0-trans <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 1.8
html-4.0-frame <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"> 1.8
html-5.0 <!DOCTYPE HTML> 1.8
xhtml+rdfa-1.0 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd"> 1.9

HTML 5 Document Type

As of the time of release of Mach-II Simplicity (1.8), the HTML 5 specification as defined by the W3C was currently under proposal and therefore inherently and possibly unstable in nature. The doctype for HTML 5 is intentionally simplistic so to aid web developers to develop valid markup without the need for complicated doctype declarations.

It is unknown on which user-agents (browsers) directly support the use of HTML 5. It appears based on research as of June, 2009 that IE, Firefox, Opera and Safari all look at HTML 5 doctype and switch the content into standards mode despite the fact that none of them currently support the HTML 5 specification. Use the HTML 5 doctype at your own risk and do your own testing / research until the specification goes stable. However, considering that the all the major browsers switch into standards mode, you could be using this doctype right now and have valid code for a long time.

Method Arguments & Tag Attributes

    addDoctype(type)
    <view:doctype type="" />
Name Required Datatype / Values Description
type optional string (default xhtml-1.0-strict) The doc type to render (see table above for accepted values).

addCharset() and charset custom tag

This method and tag adds a HTML meta tag with a http-equiv that will indicate the character set of the document. By default, it will set the charset as utf-8 unless you pass in another charset as the first argument.

Using the addCharset() method

Source code:

    <cfset getProperty("html").addCharset() />
    <cfset getProperty("html").addCharset("US-ASCII") />

Output:

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII" />

Using the charset custom tag

Source code:

    <cfimport prefix="view" taglib="/MachII/customtags/view" />
    <view:charset />
    <view:charset type="US-ASCII" />

Output:

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII" />

Method Arguments & Tag Attributes

    addCharset(type)
    <view:charset type=""/>
Name Required Datatype / Values Description
type optional string (default utf-8) Sets the document charset.
outputType optional head (default), body (1.9+ and OpenBD only) or inline Where to output the generated code to. head will output to the HTML head area and inline will return the code to be returned (you must use #'s around the method call to output returned content or assign the return content to a variable).

addAssetPackage() and the asset custom tag

Asset packages are a group of assets (javascript and/or CSS files) that are to be processed as a group. An asset package is useful for javascript libraries that use multiple JS files and/or CSS files. By default, the outputType is appends to the HTML head area. Each package is given a name so it can be reference within your code:

Source code:

    <cfset getProperty("html").addAssetPackage("lightwindow") />
    <view:asset package="lightpwindow" />

N.B. You can specify a list or array of asset packages to add if you want to load multiple assets packages in a single declaration.

Output (both the method and tag produce the same output):

    <script type="text/javascript" src="/js/prototype.js?1233233140"></script>
    <script type="text/javascript" src="/js/effects.js?1194373101"></script>
    <script type="text/javascript" src="/js/lightwindow.js?1233063280"></script>
<link type="text/css" href="/css/lightbox.cfm?1194373101" rel="stylesheet" media="screen,projection" />

Configuration Example

    <property name="html" type="MachII.properties.HtmlHelperProperty">
        <parameters>
            <parameter name="assetPackages">
                <struct>
                <!-- This is the name of the asset packet you will reference in your app -->
                <key name="lightwindow">
                    <array>
                        <!-- Simple asset declarations -->
                        <element value="prototype.js,effects.js,lightwindow.js" />
                        <element value="lightwindow.css" />

                        <!-- Advanced asset declaration -->
                        <element>
                            <struct>
                            <key name="paths" value="/css/lightwindow.cfm" />
                            <key name="type" value="css" />
                            <key name="attributes" value="media=screen,projection" />
                            </struct>
                        </element>

                        <!-- Inline javascript asset declarations (Mach-II 1.9+) -->
                        <element>
                            <struct>
                            <key name="type" value="js" />
                            <key name="inline">
                                <![CDATA[
                                    myImagePreloader = new ImagePreloder();
                                    myImagePreloader.someOption = 3;
                                ]]>
                            </key>
                            </struct>
                        </element>

                        <!-- Inline style asset declarations (Mach-II 1.9+) -->
                        <element>
                            <struct>
                            <key name="type" value="css" />
                            <key name="inline">
                                <![CDATA[
                                    .someClass { background-color: #000000; }
                                ]]>
                            </key>
                            </struct>
                        </element>
                    </array>
                </key>
                </struct>
            </parameter>
        </parameters>
    </property>

The array of elements for each asset package allows a path or a group of paths. Appropriate code for each asset will be generated in the order that the assets are defined in each package. For example if you want to the the Scriptaculous effects library for Prototype, you will need to defined the core Prototype library file first. If the element is a simple value, the property auto-negotiates the type of (JS or CSS) by the file name extension. If the type cannot be determined by the file extension (as is demostrated by the lightwindow.cfm example), you will need to define a struct with keys of path and type. The attributes key is optional and is mainly used to indicate additional attributes when the type is css.

You can use shorthand syntax for defining asset paths, except you cannot leave off the file extension (unless you are using the verbose syntax for a package element) otherwise the helper will not know if the type of the asset.

Method Arguments & Tag Attributes

    addAssetPackage(package, outputType)
    <view:asset package="" outputType="" />
Name Required Datatype / Values Description
package required string/array/list A list or array of asset package names to add.
outputType optional head (default), body (1.9+ and OpenBD only) or inline Where to output the generated code to. head will output to the HTML head area and inline will return the code to be outputted.

Public Utility Methods

There are a few public utility methods available:

Methods Arguments
flushAssetPathCache none
clearAssetPathCacheByPath assetType:string, assetPath:string

flushAssetPathCache

This method flushes (clears) the entire asset path cache and is useful if you want to clear all the asset timestamps that have been cache without reloading your application. Does not clear a parent HtmlHelperProperty asset path cache. It returns void.

    <cfset getPropert("html").flushAssetPathCache() />

Arguments

None

clearAssetPathCacheByPath

Clears an asset path cache element by type and path. Returns true if removed and false if not existing. Useful if you want to programmatically clear an asset timestamp by asset path.

    <cfset getPropert("html").clearAssetPathCacheByPath("js", "proprotype") />

Arguments

Name Required Datatype / Values Description
assetType true string The type of asset (img, js and css).
assetPath true string The asset path which will be resolved to a full path as necessary.

Tips for updating code to use helper

RegEx <img> to <view:img>

A simple RegEx search and replace in your favorite text editor works wonders. Eclipse will even do mass search and replace for selected resources (many files and/or folders).

Search RegEx String:

    <img src="(.*)"(.*)/>

Replacement RegEx String:

    <view:img src="$1" $2 />

RegEx <a> to <view:a>

Search RegEx String:

    <a href="#BuildUrl\(["|'](.*?)["|']\)#"(.*?)>([\s\w\d\n\r\t[-!"#$%&'()*+,./:;<=>?@\[\\\]_`{|}~] ]*?)</a>

Replacement RegEx String:

    <view:a event="$1"$2>$3</view:a>

Using the HtmlHelperLoaderProperty

Available in Mach-II 1.9.0+

The HtmlHelperLoaderProperty is a special property used in conjunction with the HtmlHelperProperty that allows you load in addition asset packages into the main helper via XML config file includes or modules.

Any conflicts in asset package names will cause the last property to set the asset package to win. This means conflicts do not throw exceptions and ultimately override each other. This can be useful when using XML config file includes to provide custom asset packages by overriding base asset packages with the same names.

    <property name="html" type="MachII.properties.HtmlHelperLoaderProperty">
        <parameters>
            <parameter name="assetPackages">
                <struct>
                    <key name="lightwindow">
                        <array>
                            <element value="prototype.js,effects.js,otherDirectory/lightwindow.js" />
                            <!-- SIMPLE -->
                            <element value="lightwindow.css">
                            <!-- VERBOSE-->
                            <element>
                                <struct>
                                    <key name="paths" value="/css/lightwindow.cfm" />
                                    <key name="type" value="css" />
                                    <key name="attributes" value="media=screen,projection" />
                                    <key name="forIEVersion" value="gte 7" />
                                </struct>
                            </element>
                        </array>
                    </key>
                </struct>
            </parameter>
        </parameters>
    </property>

Common Errors / Configuration Issues

There are no width / height for images

This most commonly occurs because your server is not setup to run in headless mode. This causes Mach-II to be un-able to instantiate java.awt.Toolkit class. Try adding the following to your JAVA_OPTS in your application server configuration:

    -Djava.awt.headless=true

Common error messages:

    Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable.
    Could not initialize class sun.awt.X11.XToolkit

Planned Future Enhancements for Mach-II Integrity (1.9)

  • Adding JS/CSS to bottom of html body - ticket (trac-wiki) #230 "enhancement: Add option to add JS before HTML body in HtmlProperty (closed: fixed)")
  • Configurable asset hosts - ticket (trac-wiki) #340 "enhancement: Add asset hosts for HtmlHelperProperty (closed: Moved to GitHub)")
  • Improve asset packages to allow events / endpoints - ticket (trac-wiki) #431 "enhancement: Improve asset packages to allow event/module and url parameters (closed: fixed)")
  • JS/CSS file compression and concatenation - ticket (trac-wiki) #274 "enhancement: Adding Compression and File Concatenation to HtmlHelperProperty (closed: Moved to GitHub)")
  • Add support for nested "inline" JS in asset packages - ticket (trac-wiki) #469 "enhancement: Add support for nested "inline" JS in asset packages (closed: fixed)")
Clone this wiki locally