Created
February 19, 2021 12:35
-
-
Save bennadel/cca97237fcefd5f8910745170bc30095 to your computer and use it in GitHub Desktop.
Using ColdFusion Custom Tags To Create An HTML Email DSL In Lucee CFML 5.3.7.47, Part IX
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h1> | |
Hello world | |
</h1> | |
<p> | |
This is an inlined code sample file. | |
</p> | |
<p> | |
This is a really long line that will have to have some sort of wrapping in order to not break the layout. And, the following line is a really long line that has no whitespace. | |
</p> | |
<p> | |
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | |
</p> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!--- Import custom tag libraries. ---> | |
<cfimport prefix="core" taglib="./core/" /> | |
<cfimport prefix="html" taglib="./core/html/" /> | |
<!--- // ------------------------------------------------------------------------- // ---> | |
<!--- // ------------------------------------------------------------------------- // ---> | |
<core:Email | |
subject="Code blocks" | |
teaser="Talking nerdy to me!"> | |
<core:Body> | |
<cfoutput> | |
<html:h1> | |
Sharing code blocks in email | |
</html:h1> | |
<html:p> | |
Let's look at some <html:code>inline code</html:code> samples. Code | |
blocks tend to use a monospace font and have a light background color. | |
If we're going to include HTML tags in our code, we have to be sure | |
to encode the brackets: | |
<html:code>#encodeForHtml( "<strong>Cool Beans</strong>" )#</html:code>. | |
</html:p> | |
<html:p> | |
We can also use pre-formatted blocks of code - these are a bit more | |
complex, because they use both | |
<html:code>#encodeForHtml( "<html:pre>" )#</html:code> and | |
<html:code>#encodeForHtml( "<html:code>" )#</html:code> tags and have | |
significantly more formatting. | |
</html:p> | |
<html:pre><html:code>#htmlEditFormat( fileRead( "./ex10/code-sample.txt" ) )#</html:code></html:pre> | |
<html:p> | |
Easy peasy, lemon squeezey! | |
</html:p> | |
</cfoutput> | |
</core:Body> | |
</core:Email> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!--- Import custom tag libraries. ---> | |
<cfimport prefix="core" taglib="../" /> | |
<!--- Define custom tag attributes. ---> | |
<cfparam name="attributes.class" type="string" default="" /> | |
<cfparam name="attributes.margins" type="string" default="small xlarge" /> | |
<cfparam name="attributes.style" type="string" default="" /> | |
<cfparam name="attributes.tabSize" type="string" default="4" /> | |
<!--- // ------------------------------------------------------------------------- // ---> | |
<!--- // ------------------------------------------------------------------------- // ---> | |
<cfswitch expression="#thistag.executionMode#"> | |
<cfcase value="start"> | |
<cfoutput> | |
<!--- | |
Since the "code" entity has some base styles, we need to unset some of | |
them for use in the "pre" tag. | |
---> | |
<core:HtmlEntityTheme entity="code"> | |
background-color: transparent ; | |
border-radius: 0px ; | |
display: block ; | |
padding: 0px ; | |
white-space: pre-wrap ; | |
word-break: break-all ; | |
</core:HtmlEntityTheme> | |
</cfoutput> | |
</cfcase> | |
<cfcase value="end"> | |
<cfoutput> | |
<!--- | |
When the email content is being rendered, all unnecessary whitespace is | |
removed. However, we don't want this to happen in the PRE tag since the | |
PRE tag is intended to maintain whitespace. As such, instead of rendering | |
the content directly, we're going to store it. Then, we're going to | |
replace it back into the body after the email has been minified. | |
---> | |
<cfset email = getBaseTagData( "cf_email" ) /> | |
<cfset email.preContentBlocks.append( thistag.generatedContent ) /> | |
<cfset preContentBlockToken = "__PRE:#email.preContentBlocks.len()#__" /> | |
<core:Styles | |
variable="tdStyle" | |
entityName="pre" | |
entityClass="#attributes.class#" | |
entityStyle="#attributes.style#"> | |
tab-size: #attributes.tabSize# ; | |
</core:Styles> | |
<core:Styles variable="nativePreStyle"> | |
Margin: 0 ; <!--- For Outlook. ---> | |
margin: 0px ; | |
padding: 0px ; | |
white-space: pre-wrap ; | |
word-break: break-all ; | |
</core:Styles> | |
<core:BlockMargins margins="#attributes.margins#"> | |
<!--- | |
CAUTION: We are using raw HTML elements here instead of the "html" | |
custom tags module so that we don't accidentally apply Theme styles | |
to this markup. | |
---> | |
<table role="presentation" width="100%" border="0" cellpadding="10" cellspacing="0"> | |
<tr> | |
<td class="#trim( 'html-entity-pre #attributes.class#' )#" style="#tdStyle#"> | |
<pre style="#nativePreStyle#">#preContentBlockToken#</pre> | |
</td> | |
</tr> | |
</table> | |
</core:BlockMargins> | |
<!--- Reset the generated content since we're overriding the output. ---> | |
<cfset thistag.generatedContent = "" /> | |
</cfoutput> | |
</cfcase> | |
</cfswitch> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cfscript> | |
// .... truncated code .... | |
/** | |
* I strip out as much white-space in the given content as possible. | |
* | |
* @content I am the email body content being minified. | |
*/ | |
public string function minifyEmailContent( required string content ) { | |
var newline = chr( 10 ); | |
var minifiedContent = trim( arguments.content ); | |
// Normalizing line-breaks and spaces. | |
minifiedContent = reReplaceAll( minifiedContent, "(?m)^[ \t]+", "" ); | |
minifiedContent = reReplaceAll( minifiedContent, "[\r\n]+", newline ); | |
// Wrap each STYLE attribute onto its own line in order to help prevent mid- | |
// style text-wrapping applied by the more stringent email clients. | |
minifiedContent = reReplaceAll( minifiedContent, "(\bstyle="")", "#newline#$1" ); | |
// Now that we've removed all the superfluous whitespace, as the last step in our | |
// minification, let's apply any PRE tag content (which is intended to contain | |
// meaningful whitespace). | |
preContentBlocks.each( | |
( preContent, i ) => { | |
minifiedContent = reReplaceAll( minifiedContent, "__PRE:#i#__", preContent ); | |
} | |
); | |
return( minifiedContent ); | |
} | |
// .... truncated code .... | |
</cfscript> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment