Skip to content

Instantly share code, notes, and snippets.

@bennadel
Created February 14, 2021 15:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bennadel/3aede84fa91e949003245f345501357f to your computer and use it in GitHub Desktop.
Save bennadel/3aede84fa91e949003245f345501357f 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 VI
<!--- Import custom tag libraries. --->
<cfimport prefix="core" taglib="./core/" />
<cfimport prefix="ex7" taglib="./ex7/" />
<cfimport prefix="html" taglib="./core/html/" />
<!--- // ------------------------------------------------------------------------- // --->
<!--- // ------------------------------------------------------------------------- // --->
<core:Email
subject="Content projection slots"
teaser="Making complex layouts easier to reason about!">
<ex7:Body>
<html:h1>
Using content projection slots for layout
</html:h1>
<html:p>
When layouts get more complicated, we can try to keep the HTML simple by
separating the <html:strong>definition of the content</html:strong> from the
<html:strong>layout of the content</html:strong>. To do this, we can create
"slots" that aggregate data into variables that a ColdFusion custom tag can
then use within an <html:mark>encapsulated layout</html:mark>.
</html:p>
<ex7:ImageGrid>
<!---
The ImageGrid component serves two purposes: first, it can provide themes
to the child content; and second, it defines a "slots" object that can be
used for content project. In this case, all of the image rendering is
being collected into a multi-slot (Array) called "images". The ImageGrid
will then use that "images" array to render the underlying TALBE tag(s).
--
NOTE: I'm using maths for the height since these are not the natural
dimensions of the image.
--->
<core:Slot name="images" multi="true">
<html:img
src="https://bennadel-cdn.com/images/header/photos/jeremiah_lee_2.jpg"
alt="Ben Nadel and Jeremiah Lee, double-front biceps!"
width="225"
height="#round( 225 / 1120 * 570 )#"
/>
</core:Slot>
<core:Slot name="images" multi="true">
<html:img
src="https://bennadel-cdn.com/images/header/photos/jeremiah_lee_2.jpg"
alt="Ben Nadel and Jeremiah Lee, double-front biceps!"
width="225"
height="#round( 225 / 1120 * 570 )#"
/>
</core:Slot>
<core:Slot name="images" multi="true">
<html:img
src="https://bennadel-cdn.com/images/header/photos/jeremiah_lee_2.jpg"
alt="Ben Nadel and Jeremiah Lee, double-front biceps!"
width="225"
height="#round( 225 / 1120 * 570 )#"
/>
</core:Slot>
<core:Slot name="images" multi="true">
<html:img
src="https://bennadel-cdn.com/images/header/photos/jeremiah_lee_2.jpg"
alt="Ben Nadel and Jeremiah Lee, double-front biceps!"
width="225"
height="#round( 225 / 1120 * 570 )#"
/>
</core:Slot>
</ex7:ImageGrid>
<html:p>
In this case, the <html:strong><core:ImageGrid> tag</html:strong> is
proving both a Desktop and a Mobile view!
</html:p>
<html:p>
Now, the ImageGrid component slots used "multi", which means the slot was
treated as an Array. But, the default behavior for a slot is just to set a
single variable value.
</html:p>
<!---
The Links ColdFusion custom tag has two slots: "left" and "right". The
following Slot tags simply assign the generated content to those values.
--->
<ex7:Links>
<core:Slot name="left">
<html:a href="https://www.bennadel.com/">BenNadel.com</html:a> &rarr;
</core:Slot>
<core:Slot name="right">
<html:a href="https://www.bennadel.com/people/">People</html:a> &rarr;
</core:Slot>
</ex7:Links>
<html:p margins="none">
This is gonna be hella sweet, I think!
</html:p>
</ex7:Body>
</core:Email>
<!--- Import custom tag libraries. --->
<cfimport prefix="core" taglib="../core/" />
<cfimport prefix="html" taglib="../core/html/" />
<!--- // ------------------------------------------------------------------------- // --->
<!--- // ------------------------------------------------------------------------- // --->
<cfswitch expression="#thistag.executionMode#">
<cfcase value="start">
<cfoutput>
<cfset slots = {
images: []
} />
<core:HtmlEntityTheme entity="img">
border-radius: 4px 4px 4px 4px ;
</core:HtmlEntityTheme>
</cfoutput>
</cfcase>
<cfcase value="end">
<cfoutput>
<core:HtmlEntityTheme entity="td">
padding: 7px 7px 7px 7px ;
</core:HtmlEntityTheme>
<core:IfDesktopView>
<html:table width="100%" margins="none small">
<html:tr>
<html:td align="center" class="html-entity-line-height-reset">
#slots.images[ 1 ]#
</html:td>
<html:td align="center" class="html-entity-line-height-reset">
#slots.images[ 2 ]#
</html:td>
</html:tr>
<html:tr>
<html:td align="center" class="html-entity-line-height-reset">
#slots.images[ 3 ]#
</html:td>
<html:td align="center" class="html-entity-line-height-reset">
#slots.images[ 4 ]#
</html:td>
</html:tr>
</html:table>
</core:IfDesktopView>
<core:IfMobileView>
<core:MaxWidthStyles>
.ex7-image-grid img {
height: auto ;
width: 100% ;
}
</core:MaxWidthStyles>
<html:table width="100%" margins="none small" class="ex7-image-grid">
<html:tr>
<html:td align="center img-line-height-reset">
#slots.images[ 1 ]#
</html:td>
</html:tr>
<html:tr>
<html:td align="center img-line-height-reset">
#slots.images[ 2 ]#
</html:td>
</html:tr>
<html:tr>
<html:td align="center img-line-height-reset">
#slots.images[ 3 ]#
</html:td>
</html:tr>
<html:tr>
<html:td align="center img-line-height-reset">
#slots.images[ 4 ]#
</html:td>
</html:tr>
</html:table>
</core:IfMobileView>
<!--- 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