Created
February 23, 2021 12:11
-
-
Save bennadel/5b64949eeb8dc89ceeb0f4f0810e15d5 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 XI
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/" /> | |
<cfimport prefix="ex12" taglib="./ex12/" /> | |
<!--- // ------------------------------------------------------------------------- // ---> | |
<!--- // ------------------------------------------------------------------------- // ---> | |
<core:Email | |
subject="Providing values" | |
teaser="Borrowing more inversion of control ideas from Angular!"> | |
<!--- | |
The Provide tag sets up key-value pairs that are accessible to other ColdFusion | |
custom tags in the Email. This is just another way to provide data to lower-level | |
rendering abstractions. This approach will be useful for deeply-nested tags that | |
would otherwise require "prop drilling" in order to get data down several layers | |
of rendering. For example: | |
<ex12:Body> => <ex12:FooterLinks> => <html:a> | |
In order to get URLs down to the "footer links" component WITHOUT having to first | |
provide them to the "body" component as an intermediary, we can "provide" them | |
and then the "footer links" component can just reach for them directly. | |
---> | |
<core:Provide name="siteUrl" value="https://www.bennadel.com/" /> | |
<core:Provide name="aboutUrl" value="https://www.bennadel.com/about" /> | |
<core:Provide name="peopleUrl" value="https://www.bennadel.com/people" /> | |
<ex12:Body> | |
<html:h1> | |
Providing deep values | |
</html:h1> | |
<html:p> | |
In <html:mark>Example 8</html:mark>, we looked at various ways to encapsulate | |
rendering details: | |
</html:p> | |
<html:ul> | |
<html:li>Using CFInclude.</html:li> | |
<html:li>Using tag attributes.</html:li> | |
<html:li>Using tag generated content.</html:li> | |
<html:li>Using multi-slot projection.</html:li> | |
</html:ul> | |
<html:p> | |
Now, I'd like to borrow <html:em>yet another</html:em> idea from Angular: | |
<html:mark>Providers</html:mark>. A provider just creates a key-value pair | |
that is subsequently accessible to every other ColdFusion custom tag in | |
the email rendering. | |
</html:p> | |
</ex12: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
<cfscript> | |
// Define custom tag attributes. | |
param name="attributes.name" type="string"; | |
param name="attributes.value" type="any"; | |
// ------------------------------------------------------------------------------- // | |
// ------------------------------------------------------------------------------- // | |
switch ( thistag.executionMode ) { | |
case "start": | |
getBaseTagData( "cf_email" ).providers[ attributes.name ] = attributes.value; | |
// Make sure this tag has NO BODY. | |
exit method = "exitTag"; | |
break; | |
} | |
</cfscript> |
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
<cfswitch expression="#thistag.executionMode#"> | |
<cfcase value="end"> | |
<cfoutput> | |
<cfset email = getBaseTagData( "cf_email" ) /> | |
<!--- | |
In order to access the defined providers, I just have to reach up into | |
the base "email" tag and grab the Providers struct. The same way I do | |
for the theme data. | |
---> | |
<cfset theme = email.theme /> | |
<cfset providers = email.providers /> | |
<!--- ... truncated ... ---> | |
<html:table width="#theme.width#" class="ex12-body"> | |
<html:tr> | |
<html:td colspan="3" class="ex12-body-top-border"> | |
<br /> | |
</html:td> | |
</html:tr> | |
<html:tr> | |
<html:td width="60" class="ex12-body-gutter"> | |
<br /> | |
</html:td> | |
<html:td class="ex12-body-content"> | |
#thistag.generatedContent# | |
</html:td> | |
<html:td width="60" class="ex12-body-gutter"> | |
<br /> | |
</html:td> | |
</html:tr> | |
<html:tr> | |
<html:td colspan="3" align="center" class="ex12-body-footer"> | |
Questions? | |
<html:a href="#providers.siteUrl#">I'm here to help.</html:a> | |
</html:td> | |
</html:tr> | |
</html:table> | |
<ex12:FooterLinks /> | |
<!--- Reset the generated content since we're overriding the output. ---> | |
<cfset thistag.generatedContent = "" /> | |
</cfoutput> | |
</cfcase> | |
</cfswitch> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment