Menu icon Foundation
Add HTML Attributes to Your Inky Markup

You guys are amazing! The latest Foundation for Emails release has some awesome contributions from our community. We're super excited to keep engaging you guys to keep Foundation leading the future.  We'd love to chat more about how we people are using the new functionality and how we can better integrate features. What kind of attributes are you guys using in your emails to control your content- we'd love to see how you are using this!

Some ways we are using this:

  • valign to vertically center content to visually make it more appealing in a container.
  • dir to shift columns around to make the content work better for different screen sizes.

Thanks to Brandon Barringer (Github: brandonbarringer), you can now get that visual treatment you're looking for by vertically aligning content in columns and source ordering columns. HTML attributes can now be passed to rows and columns. Thank you Brandon. See what else is new in this update: http://zurb.us/29eMWDG

 

Brandon Barringer

responsive emailsattributeshtmlinky

You guys are amazing! The latest Foundation for Emails release has some awesome contributions from our community. We're super excited to keep engaging you guys to keep Foundation leading the future.  We'd love to chat more about how we people are using the new functionality and how we can better integrate features. What kind of attributes are you guys using in your emails to control your content- we'd love to see how you are using this!

Some ways we are using this:

  • valign to vertically center content to visually make it more appealing in a container.
  • dir to shift columns around to make the content work better for different screen sizes.

Thanks to Brandon Barringer (Github: brandonbarringer), you can now get that visual treatment you're looking for by vertically aligning content in columns and source ordering columns. HTML attributes can now be passed to rows and columns. Thank you Brandon. See what else is new in this update: http://zurb.us/29eMWDG

 

Brandon Barringer


Corey Schaaf gave the most helpful answer for this post
Corey Schaaf over 3 years ago

One of the things I like to use in my INKY markup is bgcolor on wrappers. Out of the box foundation for emails doesn't support this. But a few quick tweaks and it's awesome.  BGcolor is the only 100% way of guaranteeing background colors in outlook which is why I like this approach instead of using a class on the wrapper. Major kudos to Roy Hinkyley who suggested this. 

in node_modules/inky/lib/componentFactory.js, towards the bottom you'll see this:

// <wrapper>
   case this.components.wrapper:
     var classes = ['wrapper'];
          if (element.attr('class')) {
       classes = classes.concat(element.attr('class').split(' '));
     }
     return format('<table class="%s" align="center" ><tr><td class="wrapper-inner">%s</td></tr></table>', classes.join(' '), inner);

That builds the tables structure when it sees <wrapper>

Adding in some code to also look for the attribute bgcolor="#XXXXXX". If it finds it, it adds the value into the HTML that it outputs. If it does not find a value, it reverts to the default value from the var, which is bgcolor="". You could also put a value in there if you have a default color.

// <wrapper>
   case this.components.wrapper:
     var classes = ['wrapper'];
     var bgcolor = ""; // corey add this line
     if (element.attr('class')) {
       classes = classes.concat(element.attr('class').split(' '));
     }
     // corey added the following statement
     if (element.attr('bgcolor')) {
       bgcolor = (element.attr('bgcolor'));
     } // stop new statement

     return format('<table class="%s" align="center" bgcolor="'+bgcolor+'"><tr><td class="wrapper-inner">%s</td></tr></table>', classes.join(' '), inner);

The inky markdown can then be written like so:

<wrapper bgcolor="#b9cd98">

This same approach can be done on rows as well.  Roy Hickley's original post describes how to do this for rows which can be found here. http://foundation.zurb.com/forum/posts/39783-background-colors-in-foundation-for-email-21

Corey Schaaf over 3 years ago

One of the things I like to use in my INKY markup is bgcolor on wrappers. Out of the box foundation for emails doesn't support this. But a few quick tweaks and it's awesome.  BGcolor is the only 100% way of guaranteeing background colors in outlook which is why I like this approach instead of using a class on the wrapper. Major kudos to Roy Hinkyley who suggested this. 

in node_modules/inky/lib/componentFactory.js, towards the bottom you'll see this:

// <wrapper>
   case this.components.wrapper:
     var classes = ['wrapper'];
          if (element.attr('class')) {
       classes = classes.concat(element.attr('class').split(' '));
     }
     return format('<table class="%s" align="center" ><tr><td class="wrapper-inner">%s</td></tr></table>', classes.join(' '), inner);

That builds the tables structure when it sees <wrapper>

Adding in some code to also look for the attribute bgcolor="#XXXXXX". If it finds it, it adds the value into the HTML that it outputs. If it does not find a value, it reverts to the default value from the var, which is bgcolor="". You could also put a value in there if you have a default color.

// <wrapper>
   case this.components.wrapper:
     var classes = ['wrapper'];
     var bgcolor = ""; // corey add this line
     if (element.attr('class')) {
       classes = classes.concat(element.attr('class').split(' '));
     }
     // corey added the following statement
     if (element.attr('bgcolor')) {
       bgcolor = (element.attr('bgcolor'));
     } // stop new statement

     return format('<table class="%s" align="center" bgcolor="'+bgcolor+'"><tr><td class="wrapper-inner">%s</td></tr></table>', classes.join(' '), inner);

The inky markdown can then be written like so:

<wrapper bgcolor="#b9cd98">

This same approach can be done on rows as well.  Roy Hickley's original post describes how to do this for rows which can be found here. http://foundation.zurb.com/forum/posts/39783-background-colors-in-foundation-for-email-21

Brandon Barringer over 3 years ago

Its funny, when I originally wrote this, my main need for attributes was for integration into Email Management Systems such as Mailchimp. It's great to see that people are finding all sorts of fantastic uses for this feature. 

Rafi Benkual over 3 years ago

Brandon - This is really interesting! So you are passing in attributes like mc:edit="header" to create content editable sections. I'm assuming your building templates and loading them into Mailchimp so that your team can quickly edit and send from the template?

Is there any weird things that you have to account for when doing this? Like Mailchimp styles for links and text getting in the way?

 

Rafi Benkual over 3 years ago

Corey -

This is a really good example as well! I thought the inliner should handle this, maybe that is one avenue to solve it. Adding it manually works but I'm thinking of ways to streamline this stuff ;)

Maybe it's a case for Inky to be able to parse CSS at some point and add the bgcolor attribute if a background color CSS property applies?

Also, does bgcolor work across every email client alone or do you need to couple it with CSS (background: #333;)

Corey Schaaf over 3 years ago

@rafi In regards to your question about using bgcolor across every email client, the only issue is the six digit hex value must be used. There is the possibility that the color would not be recognized (or interpreted as the wrong color) by some clients;  mainly older versions of outlook.  So to answer your question, YES! This is the most rock solid way of making sure the background color is understood by all email clients. We've been using it in our emails and it's been tested in EmailOnAcid without any fails.  

I'm all for using inky to parse background-color:#ffffff; to bgcolor="#ffffff" if possible. Roy's example on rows just made more sense in my case to use on wrappers. Doesn't mean the fix above couldn't be used on rows and wrappers though. Or parsed by INKY in both instances. 

Brandon Barringer over 3 years ago

@Rafi Yes. That is exactly right. I have not run into any issues with the Mailchimp integrations at all. As long as one has a handle on how to properly integrate into those systems there are no problems. 

One thing I am looking to improve in the future is figuring out how to have integrations be seamless between the different providers with a single attribute.

I have built a framework for our internal team on top of Foundation for Emails that has pre-built modules that can easily be layed out with help from Panini. What I would like to do is add a single attribute in those modules, something like this:

{{#each module.content}}
<container hide repeat class="module"> 
	<row>
		<columns>
			<center>
				<a edit="module" href="{{link}}"><img width="{{imageWidth}}" src="{{imageSrc}}" alt=""></a>
			</center>
		</columns>
	</row>
</container>
{{/each}}

That will automatically swap out those custom attributes for what ever system one is trying to integrate into using some sort of flag. So for mailchimp those tags would swap out as follows:
`hide` = `mc:hideable`
`repeat` = `mc:repeatable`
`edit="module"` = `mc:edit="module"`

For other systems it would change as needed based on the flag given. 

Rafi Benkual over 3 years ago

@corey - Finding an npm package that can parse Sass would be the next step. I know this came up in trying to integrate Bulletproof buttons.

 

@Brandon - This is a great idea! How does the module.content variable work in this case?

Brandon Barringer over 3 years ago

@Rafi I use Panini to add all the content for each module so who ever is working on a new template just has to edit a JSON file that looks like this:

{
	"content": 
	[
		{
			"imageSrc": "http://placehold.it/360x250",
			"imageWidth": 580,
			"headline": "Longer Headlines Seem to Work Better Here",
			"link": "http://example.com",
			"byline": "By John Doe",
			"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec gravida semper neque, eu molestie ex varius ac. Curabitur ut quam aliquam."
		}
	]
}

This way, if there are multiple "Contents", the module would repeat itself automatically with the new content instead of having to edit and copy the html

Glenn McComb over 3 years ago

I build a lot of emails for Marketo and was struggling to get attributes on to elements to handle things much like what Mailchimp does. I was investigating customising the gulp-inline-css options to preserve an element's attributes and hit a brick wall, then I stumbled on this thread and realised the new updated solved my issues. I had some issues updating to the new version and ended up creating a new project and migrating my HTML partials and custom Sass to that project.

So, some notes on how I use attributes on HTML elements to build Marketo emails. Here's an example of some markup to create Modules and Containers in Marketo's new Email Editor 2.0:

<table class="mktoContainer" id="container-name">
  <tbody>
    <tr class="mktoModule" mktoname="Module Name" id="modulename">
      <td>
        <!-- STUFF GOES HERE  -->
      </td>
    </tr>
  </tbody>
</table>

I would really like to be able to do things like this:

<container class="mktoContainer" id="container-test">
  <row class="mktoModule" mktoname="Article Block" id="article-block">
    <!-- STUFF GOES HERE -->
  </row>
</container>

... But it looks like the <container> and <row> inky elements aren't accepting custom attributes. 

On a vaguely similar note, I had a conflict with the panini / handlebars {{> includes}} syntax because Marketo's Tokens are like: {{lead.First Name:default=Sir/Madam}}. This was causing issues but I was able to get around it by using the HTML entity for curly braces: &#123;&#123;lead.First Name:default=Sir/Madam&#125;&#125.

In my previous build process (using Inky v1 and grunt) I had written some JavaScript to handle bulletproof buttons, but unfortunately Marketo's link tracking wasn't working because it didn't recognise the href="" in the <v:rect> element. It's a juggling act at times.

Really stoked to see that Zurb are committed to making Foundation For Emails work for developers.

Rafi Benkual over 3 years ago

@glenn In 2.1 - thanks to Brandon's PR the attributes should be passed through. 

I tested your code and this came outL

INPUT
<container class="mktoContainer" id="container-test">
  <row class="mktoModule" mktoname="Article Block" id="article-block">
    stuff
  </row>
</container>

OUTPUT
    <table align="center" class="container mktoContainer float-center">
      <tbody>
        <tr>
          <td>
            <table mktoname="Article Block" class="row mktoModule">
              <tbody>
                <tr>
                  stuff
                </tr>
              </tbody>
            </table>
          </td>
        </tr>
      </tbody>
    </table>

 

Another helpful feature is the handlebars raw helper: Use it like this

For Panini handlebars
{{{raw}}}stuff to be ignored{{{/raw}}}

For Inky
<raw>stuff to be ignored</raw>

Glenn McComb over 3 years ago

Cool thanks for your reply Rafi, that's super helpful. 

I had a crack with the raw helper and managed to get this one to work (note the 4 curly braces):

{{{{raw}}}}Hi {{lead.First Name:default=Sir/Madam}}{{{{/raw}}}}

I couldn't get the <raw> tag to work but the above option is a big improvement on using HTML entities which make no sense and are tricky to work with.

Regarding adding attributes to the <container> and <row> elements, I had already tried that and you're right, some of the attributes make their way through, but not the IDs unfortunately (which Marketo needs). 

Brandon Barringer over 3 years ago

@Glenn @Rafi

 

Looks like I had added `id`s to the list of ignored attributes. If that is removed, the `id`s should be passed without issue. Maybe this can be changed for the next release? I'm not sure why I had added that to the ignored attributes in the first place. 

@Glenn for now you can go into your node_modules/inky/lib/util/getAttrs.js and remove `id` from the `ignoredAttributes` array as a work around.

Full Disclosure: I have not tested the impact of removing this snippet of code, any edits to core will be overwritten if the framework is updated. I don't think it will be an issue, but you never know :-)