Skip to content

Commit

Permalink
🐛 Fixed repeating text in plaintext version of emails (#17162)
Browse files Browse the repository at this point in the history
fixes https://github.com/TryGhost/Team/issues/3541

The email preheader, which is only present in the html version of an
email, is also included in the plaintext version of all emails. This
results in all text being duplicated twice in plaintext emails.
  • Loading branch information
SimonBackx authored Jun 29, 2023
1 parent c41694f commit e6dbc0b
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ Object {
exports[`Email Preview API Read can read post email preview with email card and replacements 3 1`] = `
Object {
"html": "
This is the actual post content...
Expand Down Expand Up @@ -735,7 +735,7 @@ exports[`Email Preview API Read can read post email preview with email card and
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "23959",
"content-length": "23925",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
Expand Down Expand Up @@ -1261,7 +1261,7 @@ Object {
exports[`Email Preview API Read can read post email preview with fields 3 1`] = `
Object {
"html": "
This is my custom excerpt!
Expand Down Expand Up @@ -1404,7 +1404,7 @@ exports[`Email Preview API Read can read post email preview with fields 4: [head
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "28790",
"content-length": "28764",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
Expand Down Expand Up @@ -1957,7 +1957,7 @@ Object {
exports[`Email Preview API Read has custom content transformations for email compatibility 3 1`] = `
Object {
"html": "
Testing links in email excerpt and apostrophes '
Expand Down Expand Up @@ -2091,7 +2091,7 @@ exports[`Email Preview API Read has custom content transformations for email com
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "23725",
"content-length": "23677",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
Expand Down Expand Up @@ -2978,7 +2978,7 @@ Object {
exports[`Email Preview API Read uses the newsletter provided through ?newsletter=slug 3 1`] = `
Object {
"html": "
Testing links in email excerpt and apostrophes '
Expand Down Expand Up @@ -3117,7 +3117,7 @@ exports[`Email Preview API Read uses the newsletter provided through ?newsletter
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "24217",
"content-length": "24169",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
Expand Down Expand Up @@ -4030,7 +4030,7 @@ Object {
exports[`Email Preview API Read uses the posts newsletter by default 3 1`] = `
Object {
"html": "
Testing links in email excerpt and apostrophes '
Expand Down Expand Up @@ -4169,7 +4169,7 @@ exports[`Email Preview API Read uses the posts newsletter by default 4: [headers
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "24217",
"content-length": "24169",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ table.body figcaption a {
exports[`Batch sending tests HTML-content Does not HTML escape feature_image_caption 2 1`] = `
Object {
"html": "
A random test post –




Expand Down Expand Up @@ -1122,7 +1122,7 @@ table.body figcaption a {
exports[`Batch sending tests Newsletter settings Hides comments button for email only posts 2 1`] = `
Object {
"html": "
Hello world




Expand Down Expand Up @@ -1737,7 +1737,7 @@ table.body figcaption a {
exports[`Batch sending tests Newsletter settings Hides comments button if comments disabled 2 1`] = `
Object {
"html": "
Hello world




Expand Down Expand Up @@ -2352,7 +2352,7 @@ table.body figcaption a {
exports[`Batch sending tests Newsletter settings Hides comments button if disabled in newsletter 2 1`] = `
Object {
"html": "
Hello world




Expand Down Expand Up @@ -2943,7 +2943,7 @@ table.body figcaption a {
exports[`Batch sending tests Newsletter settings Hides post title section if show_post_title_section is false 2 1`] = `
Object {
"html": "
Hello world




Expand Down Expand Up @@ -3530,7 +3530,7 @@ table.body figcaption a {
exports[`Batch sending tests Newsletter settings Hides post title section if show_post_title_section is false 4 1`] = `
Object {
"html": "
Hello world




Expand Down Expand Up @@ -5261,7 +5261,7 @@ table.body figcaption a {
exports[`Batch sending tests Newsletter settings Shows 3 comment buttons for published posts with feedback enabled 2 1`] = `
Object {
"html": "
Hello world




Expand Down Expand Up @@ -5958,7 +5958,7 @@ table.body figcaption a {
exports[`Batch sending tests Newsletter settings Shows 3 comment buttons for published posts without feedback enabled 2 1`] = `
Object {
"html": "
Hello world




Expand Down Expand Up @@ -6664,7 +6664,7 @@ table.body figcaption a {
exports[`Batch sending tests Newsletter settings Shows 3 latest posts 2 1`] = `
Object {
"html": "
Hello world




Expand Down Expand Up @@ -8550,7 +8550,7 @@ table.body figcaption a {
exports[`Batch sending tests Newsletter settings Shows subscription details box for canceled paid member 2 1`] = `
Object {
"html": "
Hello world




Expand Down Expand Up @@ -9220,7 +9220,7 @@ table.body figcaption a {
exports[`Batch sending tests Newsletter settings Shows subscription details box for comped members 2 1`] = `
Object {
"html": "
Hello world




Expand Down Expand Up @@ -9890,7 +9890,7 @@ table.body figcaption a {
exports[`Batch sending tests Newsletter settings Shows subscription details box for free members 2 1`] = `
Object {
"html": "
Hello world




Expand Down Expand Up @@ -10560,7 +10560,7 @@ table.body figcaption a {
exports[`Batch sending tests Newsletter settings Shows subscription details box for paid member 2 1`] = `
Object {
"html": "
Hello world




Expand Down Expand Up @@ -11230,7 +11230,7 @@ table.body figcaption a {
exports[`Batch sending tests Newsletter settings Shows subscription details box for trialing member 2 1`] = `
Object {
"html": "
Hello world




Expand Down Expand Up @@ -12516,7 +12516,7 @@ table.body figcaption a {
exports[`Batch sending tests Replacements Does replace with and without fallback in both plaintext and html for member with name 2 1`] = `
Object {
"html": "
Hello {first_name},




Expand Down Expand Up @@ -13133,7 +13133,7 @@ table.body figcaption a {
exports[`Batch sending tests Replacements Does replace with and without fallback in both plaintext and html for member without name 2 1`] = `
Object {
"html": "
Hello {first_name},




Expand Down
10 changes: 5 additions & 5 deletions ghost/core/test/integration/services/email-service/cards.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,17 @@ describe('Can send cards via email', function () {
it('Paragraphs', async function () {
const data = await sendEmail(agent, {
lexical: createLexicalJson([
createParagraphCard('Hello world.')
createParagraphCard('This is a paragraph test.')
])
});

// Remove the preheader span from the email using cheerio
splitPreheader(data);

// Check our html and plaintexct contain the paragraph
assert.ok(data.html.includes('Hello world.'));
assert.ok(data.plaintext.includes('Hello world.'));
assert.ok(data.preheader.includes('Hello world.'));
// Check only contains once in every part
assert.equal(data.html.match(/This is a paragraph test\./g).length, 1);
assert.equal(data.plaintext.match(/This is a paragraph test\./g).length, 1);
assert.equal(data.preheader.match(/This is a paragraph test\./g).length, 1);
});

it('Signup Card', async function () {
Expand Down
10 changes: 9 additions & 1 deletion ghost/email-service/test/email-renderer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1483,6 +1483,11 @@ describe('Email renderer', function () {
if (key === 'feedback_enabled') {
return true;
}

if (key === 'show_post_title_section') {
return true;
}

return false;
}
};
Expand All @@ -1498,7 +1503,10 @@ describe('Email renderer', function () {
response.plaintext.should.containEql('Test Post');
response.plaintext.should.containEql('Unsubscribe [%%{unsubscribe_url}%%]');
response.plaintext.should.containEql('http://example.com');
response.html.should.containEql('Test Post');

// Check contains the post name twice
assert.equal(response.html.match(/Test Post/g).length, 3, 'Should contain the post name 3 times: in the title element, the preheader and in the post title section');

response.html.should.containEql('Unsubscribe');
response.html.should.containEql('http://example.com');
response.replacements.length.should.eql(2);
Expand Down
4 changes: 3 additions & 1 deletion ghost/html-to-plaintext/lib/html-to-plaintext.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ const loadConverters = () => {
const emailSettings = mergeSettings({
selectors: [
// equiv hideLinkHrefIfSameAsText: true
{selector: 'a', options: {hideLinkHrefIfSameAsText: true}}
{selector: 'a', options: {hideLinkHrefIfSameAsText: true}},
// Don't include html .preheader in email
{selector: '.preheader', format: 'skip'}
]
});

Expand Down

0 comments on commit e6dbc0b

Please sign in to comment.