Putting it all together
Learn how to use components to create a complex email.
What can we do with components when we utilize all of their functionality at once?
Let's make a new component called fetching-data-component
.
<component>
<fetch
name="products"
url="https://raw.githubusercontent.com/BrianBock/open-data-set/master/products200.json"
>
<table>
<tr>
<th>Product</th>
<th>Image</th>
<th>Price</th>
</tr>
<tr foreach="product in products">
<td>${product.name}</td>
<td>
<a set:href="product.url"
><img
set:src="product.image"
set:alt="product.description"
width="150"
/></a>
</td>
<td>$${product.price}</td>
</tr>
</table>
</fetch>
</component>
Incorporate this into a very simple email:
<html>
<head></head>
<body>
<h1>Monthly Catalog</h1>
<fetching-data-component />
</body>
</html>
In 24 lines of simple code, we've created an email product catalog with 200 products!
You can use components inside other components.
Let's make another new component called my-button
.
<fieldset>
<input type="url" name="href" />
</fieldset>
<style>
.button {
background: slateblue;
color: white;
padding: 10px;
display: inline-block;
font-family: sans-serif;
text-decoration: none;
}
</style>
<component>
<a class="button" set:href>Buy now!</a>
</component>
Adding it to our fetching-data-component
is as easy as adding it to an email:
<component>
<fetch
name="products"
url="https://raw.githubusercontent.com/BrianBock/open-data-set/master/products200.json"
>
<table>
<tr>
<th>Product</th>
<th>Image</th>
<th>Price</th>
<th>CTA</th>
</tr>
<tr foreach="product in products">
<td>${product.name}</td>
<td>
<a set:href="product.url"
><img
set:src="product.image"
set:alt="product.description"
width="150"
/></a>
</td>
<td>$${product.price}</td>
<td><my-button set:href="product.url" /></td>
</tr>
</table>
</fetch>
</component>
<component>
<fetch name="news" url="https://www.nasa.gov/rss/dyn/Gravity-Assist.rss">
<h2>${news.rss.channel.title}</h2>
<a set:href="news.rss.channel.url"
><img
set:src="news.rss.channel.image.url"
set:alt="news.rss.channel.image.title"
width="200"
/>
</a>
<p>
<a set:href="news.rss.channel.url"> ${news.rss.channel.description}</a>
</p>
<h2>Related Stories</h2>
<fragment foreach="story in news.rss.channel.item">
<h3><a set:href="story.url"> ${story.title} </a></h3>
<p>${story.description}</p>
</fragment>
</fetch>
</component>
<html>
<head></head>
<body>
<h1>Newsletter</h1>
<newsletter-component />
</body>
</html>
Let's add a little bit more complexity. First, add a ?
before each element - this will allow the email to render even if that element does not exist. Let's look at a different RSS feed and pass it's url into the component from the email.
<fieldset>
<input type="url" name="url" />
</fieldset>
<component>
<fetch name="news" set:url>
<h1>${news?.rss?.channel?.title}</h1>
<p>${news?.rss?.channel?.description}</p>
<fragment foreach="story in news?.rss?.channel?.item">
<h3><a set:href="story?.url"> ${story?.title} </a></h3>
<a set:href="story?.url">
<img set:src="story?.enclosure?._url" set:alt="story?.title"
/></a>
<p>${story?.description}</p>
${story?.pubDate}
</fragment>
</fetch>
</component>
<html>
<head></head>
<body>
<newsletter-component
url="https://www.nasa.gov/rss/dyn/breaking_news.rss"
/>
</body>
</html>
This framework will work for any RSS feed with the same structure.
<html>
<head></head>
<body>
<newsletter-component
url="https://www.nasa.gov/rss/dyn/educationnews.rss"
/>
</body>
</html>
All emails support the basic component functionality. If you don't need to reuse a component or pass in data to it, you can incorporate it's content directly in the email (without the <component>
tags).
<html>
<head></head>
<body>
<fetch name="news" url="https://www.nasa.gov/rss/dyn/educationnews.rss">
<h1>${news?.rss?.channel?.title}</h1>
<p>${news?.rss?.channel?.description}</p>
<fragment foreach="story in news?.rss?.channel?.item">
<h3><a set:href="story?.url"> ${story?.title} </a></h3>
<a set:href="story?.url">
<img set:src="story?.enclosure?._url" set:alt="story?.title" />
</a>
<p>${story?.description}</p>
${story?.pubDate}
</fragment>
</fetch>
</body>
</html>