Skip to content

Commit f4c7d8d

Browse files
committed
Fix hybrid template so that it works with Lexbor
Lexbor injects the tbody tag if it doesn't exist. That's actually also what browsers usually do, but it broke some CSS that relied on tr elements being direct descendants of table elements. This commit also simplifies the multi-column layouts which I have tested to work with Outlook 2016.
1 parent 69d2356 commit f4c7d8d

File tree

5 files changed

+145
-155
lines changed

5 files changed

+145
-155
lines changed

lib/keila/mailings/builder.ex

+2-12
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ defmodule Keila.Mailings.Builder do
187187
) do
188188
html_body =
189189
html_body
190-
|> Html.parse_document!(html_parser: Floki.HTMLParser.Mochiweb)
190+
|> Html.parse_document!()
191191
|> Html.apply_inline_styles(styles, ignore_inherit: true)
192192
|> Html.to_document()
193193

@@ -365,19 +365,9 @@ defmodule Keila.Mailings.Builder do
365365
defp maybe_put_tracking(email, _campaign, %{id: @placeholder_recipient_id}), do: email
366366

367367
defp maybe_put_tracking(email, campaign, recipient) do
368-
# NOTE: This is necessary because Lexbor seems to be breaking the block template.
369-
# So let's stick to Mochiweb except for MJML campaigns
370-
html_parser =
371-
if campaign.settings.type == :mjml and
372-
function_exported?(Floki.HTMLParser.FastHtml, :__info__, 1) do
373-
Floki.HTMLParser.FastHtml
374-
else
375-
Floki.HTMLParser.Mochiweb
376-
end
377-
378368
html =
379369
email.html_body
380-
|> Floki.parse_document!(html_parser: html_parser)
370+
|> Floki.parse_document!()
381371
|> put_click_tracking(campaign, recipient)
382372
|> put_open_tracking(campaign, recipient)
383373
|> put_tracking_pixel(campaign, recipient)
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
<tr class="block block--button">
22
<td>
33
<table align="center" role="presentation" cellspacing="0" cellpadding="0" border="0" style="margin: auto;{% unless block.data.centered %}width: 100%;{% endunless %}">
4-
<tr>
5-
<td class="button-td button-td-primary">
6-
<a class="button-a button-a-primary" href="{{block.data.url }}">{{block.data.label }}</a>
7-
</td>
8-
</tr>
4+
<tbody>
5+
<tr>
6+
<td class="button-td button-td-primary">
7+
<a class="button-a button-a-primary" href="{{block.data.url }}">{{block.data.label }}</a>
8+
</td>
9+
</tr>
10+
</tbody>
911
</table>
1012
</td>
1113
</tr>

priv/email_templates/hybrid/_block--layout.liquid

+119-127
Original file line numberDiff line numberDiff line change
@@ -1,177 +1,169 @@
11
{% case block.data.ratio %}
22
{% when "1-1" %}
33
<tr class="block block--layout cols-2">
4-
<td align="center" valign="top">
5-
<!--[if mso]>
6-
<table role="presentation" border="0" cellspacing="0" cellpadding="0" width="680">
7-
<tr>
8-
<td valign="top" width="340">
9-
<![endif]-->
10-
<div style="display:inline-block; width:100%; min-width:340px; max-width:340px; vertical-align:top;" class="stack-column col-1">
11-
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
4+
<td dir="ltr" width="100%" style="padding: 10px">
5+
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
6+
<tbody>
127
<tr>
13-
<td>
14-
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
15-
{% render "content", blocks: block.data.blocks[0].blocks %}
8+
<!-- Column : BEGIN -->
9+
<td width="50%" class="stack-column col1-" valign="top">
10+
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
11+
<tbody>
12+
<tr>
13+
<td dir="ltr" valign="top">
14+
{% render "content", blocks: block.data.blocks[0].blocks %}
15+
</td>
16+
</tr>
17+
</tbody>
1618
</table>
1719
</td>
18-
</tr>
19-
</table>
20-
</div>
21-
<!--[if mso]>
22-
</td>
23-
<td valign="top" width="340">
24-
<![endif]-->
25-
<div style="display:inline-block; width:100%; min-width:340px; max-width:340px; vertical-align:top;" class="stack-column col-2">
26-
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
27-
<tr>
28-
<td>
29-
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
30-
{% render "content", blocks: block.data.blocks[1].blocks %}
20+
<!-- Column : END -->
21+
<!-- Column : BEGIN -->
22+
<td width="50%" class="stack-column col-2">
23+
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
24+
<tbody>
25+
<tr>
26+
<td dir="ltr" valign="top" valign="top">
27+
{% render "content", blocks: block.data.blocks[1].blocks %}
28+
</td>
29+
</tr>
30+
</tbody>
3131
</table>
3232
</td>
33+
<!-- Column : END -->
3334
</tr>
34-
</table>
35-
</div>
36-
<!--[if mso]>
37-
</td>
38-
</tr>
35+
</tbody>
3936
</table>
40-
<![endif]-->
4137
</td>
4238
</tr>
4339
<!-- 2 Even Columns : END -->
4440
{% when "2-1" %}
4541
<!-- Thumbnail Right, Text Left : BEGIN -->
4642
<tr class="block block--layout cols-2">
47-
<td>
48-
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
49-
<tr>
50-
<!-- dir=rtl is where the magic happens. This can be changed to dir=ltr to swap the alignment on wide while maintaining stack order on narrow. -->
51-
<td dir="ltr" height="100%" valign="top" width="100%">
52-
<!--[if mso]>
53-
<table role="presentation" border="0" cellspacing="0" cellpadding="0" width="680" style="width: 680px;">
54-
<tr>
55-
<td valign="top" width="453" style="width: 453px;">
56-
<![endif]-->
57-
<div style="display:inline-block; max-width: 453px; min-width:453px; vertical-align:top; width:100%;" class="stack-column col-1">
58-
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
59-
{% render "content", blocks: block.data.blocks[0].blocks %}
43+
<td dir="ltr" width="100%" style="padding: 10px">
44+
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
45+
<tbody>
46+
<tr>
47+
<!-- Column : BEGIN -->
48+
<td width="66.66%" class="stack-column col1-" valign="top">
49+
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
50+
<tbody>
51+
<tr>
52+
<td dir="ltr" valign="top">
53+
{% render "content", blocks: block.data.blocks[0].blocks %}
54+
</td>
55+
</tr>
56+
</tbody>
6057
</table>
61-
</div>
62-
<!--[if mso]>
6358
</td>
64-
<td valign="top" width="227" style="width: 227px;">
65-
<![endif]-->
66-
<div style="display:inline-block; max-width: 227px; min-width:227px; vertical-align:top;" class="stack-column col-2">
67-
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
68-
{% render "content", blocks: block.data.blocks[1].blocks %}
59+
<!-- Column : END -->
60+
<!-- Column : BEGIN -->
61+
<td width="33.33%" class="stack-column col-2">
62+
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
63+
<tbody>
64+
<tr>
65+
<td dir="ltr" valign="top" valign="top">
66+
{% render "content", blocks: block.data.blocks[1].blocks %}
67+
</td>
68+
</tr>
69+
</tbody>
6970
</table>
70-
</div>
71-
<!--[if mso]>
7271
</td>
73-
</tr>
74-
</table>
75-
<![endif]-->
76-
</td>
77-
</tr>
72+
<!-- Column : END -->
73+
</tr>
74+
</tbody>
7875
</table>
7976
</td>
8077
</tr>
8178
<!-- Thumbnail Right, Text Left : END -->
8279
{% when "1-2" %}
8380
<!-- Thumbnail Left, Text Right : BEGIN -->
8481
<tr class="block block--layout cols-2">
85-
<td>
86-
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
87-
<tr>
88-
<!-- dir=rtl is where the magic happens. This can be changed to dir=ltr to swap the alignment on wide while maintaining stack order on narrow. -->
89-
<td dir="ltr" height="100%" valign="top" width="100%">
90-
<!--[if mso]>
91-
<table role="presentation" border="0" cellspacing="0" cellpadding="0" width="680" style="width: 680px;">
92-
<tr>
93-
<td valign="top" width="227" style="width: 227px;">
94-
<![endif]-->
95-
<div style="display:inline-block; max-width: 227px; min-width:227px; vertical-align:top; width:100%;" class="stack-column col-1">
96-
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
97-
{% render "content", blocks: block.data.blocks[0].blocks %}
82+
<td dir="ltr" width="100%" style="padding: 10px">
83+
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
84+
<tbody>
85+
<tr>
86+
<!-- Column : BEGIN -->
87+
<td width="33.33%" class="stack-column col1-" valign="top">
88+
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
89+
<tbody>
90+
<tr>
91+
<td dir="ltr" valign="top">
92+
{% render "content", blocks: block.data.blocks[0].blocks %}
93+
</td>
94+
</tr>
95+
</tbody>
9896
</table>
99-
</div>
100-
<!--[if mso]>
10197
</td>
102-
<td valign="top" width="453" style="width: 453px;">
103-
<![endif]-->
104-
<div style="display:inline-block; max-width: 453px; min-width:453px; vertical-align:top;" class="stack-column col-2">
105-
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
106-
{% render "content", blocks: block.data.blocks[1].blocks %}
98+
<!-- Column : END -->
99+
<!-- Column : BEGIN -->
100+
<td width="66.66%" class="stack-column col-2">
101+
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
102+
<tbody>
103+
<tr>
104+
<td dir="ltr" valign="top" valign="top">
105+
{% render "content", blocks: block.data.blocks[1].blocks %}
106+
</td>
107+
</tr>
108+
</tbody>
107109
</table>
108-
</div>
109-
<!--[if mso]>
110110
</td>
111-
</tr>
112-
</table>
113-
<![endif]-->
114-
</td>
115-
</tr>
111+
<!-- Column : END -->
112+
</tr>
113+
</tbody>
116114
</table>
117115
</td>
118116
</tr>
119117
<!-- Thumbnail Left, Text Right : END -->
120118
{% when "1-1-1" %}
121119
<!-- 3 Even Columns : BEGIN -->
122120
<tr class="block block--layout cols-3">
123-
<td align="center" valign="top">
124-
<!--[if mso]>
125-
<table role="presentation" border="0" cellspacing="0" cellpadding="0" width="680">
126-
<tr>
127-
<td valign="top" width="226">
128-
<![endif]-->
129-
<div style="display:inline-block; max-width: 226px; min-width:226px; vertical-align:top; width:100%;" class="stack-column col-1">
130-
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
121+
<td dir="ltr" width="100%" style="padding: 10px">
122+
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
123+
<tbody>
131124
<tr>
132-
<td>
133-
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
134-
{% render "content", blocks: block.data.blocks[0].blocks %}
125+
<!-- Column : BEGIN -->
126+
<td width="33.33%" class="stack-column col1-" valign="top">
127+
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
128+
<tbody>
129+
<tr>
130+
<td dir="ltr" valign="top">
131+
{% render "content", blocks: block.data.blocks[0].blocks %}
132+
</td>
133+
</tr>
134+
</tbody>
135135
</table>
136136
</td>
137-
</tr>
138-
</table>
139-
</div>
140-
<!--[if mso]>
141-
</td>
142-
<td valign="top" width="227">
143-
<![endif]-->
144-
<div style="display:inline-block; max-width: 227px; min-width:227px; vertical-align:top; width:100%;" class="stack-column col-2">
145-
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
146-
<tr>
147-
<td>
148-
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
149-
{% render "content", blocks: block.data.blocks[1].blocks %}
137+
<!-- Column : END -->
138+
<!-- Column : BEGIN -->
139+
<td width="33.33%" class="stack-column col-2">
140+
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
141+
<tbody>
142+
<tr>
143+
<td dir="ltr" valign="top" valign="top">
144+
{% render "content", blocks: block.data.blocks[1].blocks %}
145+
</td>
146+
</tr>
147+
</tbody>
150148
</table>
151149
</td>
152-
</tr>
153-
</table>
154-
</div>
155-
<!--[if mso]>
156-
</td>
157-
<td valign="top" width="226">
158-
<![endif]-->
159-
<div style="display:inline-block; max-width: 226px; min-width:226px; vertical-align:top; width:100%;" class="stack-column col-3">
160-
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
161-
<tr>
162-
<td>
163-
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
164-
{% render "content", blocks: block.data.blocks[2].blocks %}
150+
<!-- Column : END -->
151+
<!-- Column : BEGIN -->
152+
<td width="33.33%" class="stack-column col-3">
153+
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
154+
<tbody>
155+
<tr>
156+
<td dir="ltr" valign="top" valign="top">
157+
{% render "content", blocks: block.data.blocks[2].blocks %}
158+
</td>
159+
</tr>
160+
</tbody>
165161
</table>
166162
</td>
163+
<!-- Column : END -->
167164
</tr>
168-
</table>
169-
</div>
170-
<!--[if mso]>
171-
</td>
172-
</tr>
165+
</tbody>
173166
</table>
174-
<![endif]-->
175167
</td>
176168
</tr>
177169
<!-- 3 Even Columns : END -->

priv/email_templates/hybrid/default.css

+3-3
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,11 @@ body.keila--markdown-campaign .email-container {
151151
padding-top: 20px;
152152
}
153153

154-
#content > .block:first-of-type > td {
154+
#content > tbody > .block:first-of-type > td {
155155
padding-top: 20px;
156156
}
157157

158-
#content > .block:last-of-type > td {
158+
#content > tbody > .block:last-of-type > td {
159159
padding-bottom: 20px;
160160
}
161161

@@ -182,7 +182,7 @@ body.keila--markdown-campaign .email-container {
182182
padding-right: 0;
183183
}
184184

185-
#content > .block--image--flush:first-of-type > td {
185+
#content > tbody > .block--image--flush:first-of-type > td {
186186
padding-top: 0;
187187
padding-bottom: 0;
188188
}

0 commit comments

Comments
 (0)