By
Ray Camden
Principal Spectra Compliance Engineer
Macromedia, Inc.
Custom
tags are a great tool for code reuse and portability. By
developing a custom tag you not only make your current project
easier but future ones as well. By providing the Developer
Exchange, Macromedia provides a space for developers to
share custom tags with thousands of other programmers and
site builders.
ColdFusion
allows developers to not only develop custom tags, but to
also create tags that can wrap content, exist within other
tags, and interact with other tags. This article will deal
specifically with the ability to wrap content. As an example,
imagine a custom tag that must take a body of text and replace
any instance of an e-mail address with a hyperlink. Normally,
this isn't a problem if the content comes from a database,
as follows:
#LinkedContent#
The
only problem with this is the need to send information to
the custom tag, return it to a second variable, and then
output that variable. What if, instead of being forced to
send your text to the tag in the method above, you could
simply wrap your content with the custom tag:
#Content#
Or
even better:
#TheQuery.CommentColumn#
One
of the things I have always loved about ColdFusion is the
way it integrates with HTML. Unlike creating CGIs in Perl,
ColdFusion feels closer or more ingrained with the static
design and HTML entities of the page. With the new tag syntax,
this integration is even greater.
Creating
the CF_STYLE Custom Tag
One of the problems I used to have with designing web pages
was the constant fight to cover all possible browsers. I
wanted my sites to look good, but, being a naturally lazy
person I also wanted to accomplish this as easy as possible.
With the introduction of the 4.0 browsers and Cascading
Style Sheets (CSS), it was finally possible to create really
nice looking copy with very fine control. The only problem
was that you gave up all this control whenever a 3.0 browser
hit your site. Even now, a full 48% of the visitors to my
site use a 3.0 browser. What I really needed was an easy
way to use CSS for the 4.0 browsers and <FONT> tags
for 3.0 and lower browsers. This tool would need to work
with both with dynamic content and static content.
I knew that one solution would be to simply query the USER_AGENT
string from the browser. By doing some simple checking on
the browser version, I could determine if the visitor was
using a 4.0 or 3.0 (and lower) browser. At that point, I
wasn't sure what to do. I could create two versions of the
site and just push people using 3.0 browsers into a different
folder. But that would mean maintaining two separate versions
of the site--not something I had a lot of time to do.
I decided to go with a solution that was made possible with
the extensions to custom tags in ColdFusion. Here is the
beginning of the CF_Style custom tag. There is nothing magical
here, just simple error checking and global variable setting.
CF_Style Error: Attribute StyleDef or Class
must be defined.
CF_Style Error: Attribute FontDef must be defined.
After
declaring the variables I will be using for the rest of the
tag, I did some simple checking to make sure the user provided
the proper attributes. The tag requires that you set either
StyleDef or Class (this covers 4.0 browsers) and the attributes
FontDef (this covers 3.0 and lower browsers).
The StyleDef and Class attributes are pretty simple. CSS
allows you to define a style for each block of content (using
the attribute: val; syntax) or point to a global
style declaration (class).
The FontDef attribute is a bit more complex. I wanted a
way for the user to provide as much detail as possible but
only in one attribute. I mimicked the CSS attribute a bit
by using a syntax delimited by semicolons. The FontDef value
would refer to: FACE (Arial, Helvetica, etc.), COLOR (red,
green, blue, etc), SIZE (+2,-1,3, etc.) and a combination
of bold and italics. The attribute would be set by simply
dividing the values by semicolons. Bold and italics could
be used as the fourth item in the attribute, and would be
used in the letter 'b' or 'i' appeared. Here is an example:
FontDef="Arial,Helvetica;+1,red,bi". This would create a
font face using Arial, Helvetica, a font size of "+1", a
color of red, with bold and italics turned on. Here is the
code that parses the FontDef:
After
setting all the values and parsing the FontDef attribute,
my next task was to get the actual browser version. I did
this with some simple text parsing of the HTTP_USER_AGENT
variable:
Ok,
so far, nothing really magical. Now it's time for the fun
stuff. As I said above, the new tag syntax allows for:
…..
By
using a variable, ThisTag.ExecutionMode, you can determine
if you are either at the beginning of the tag or at the end.
In this case, if I am at the beginning of the tag, I want
to output either the <SPAN> tag for the
4.0 browsers or <FONT>(<B><I>)
tag combination for the 3.0 browsers. Conversely, when the
tag is called at the end (with the / syntax), I want to either
output </SPAN> or (</I></B>)</FONT>.
By using CFSWITCH, I can easily spit out the correct content:
STYLE="#Attributes.StyleDef#"
CLASS="#Attributes.Class#"
>
STYLE="#Attributes.StyleDef#"
CLASS="#Attributes.Class#"
>
STYLE="#Attributes.StyleDef#"
CLASS="#Attributes.Class#"
>