From 84724537be90ef6a22c14e4e999c5301a235758b Mon Sep 17 00:00:00 2001 From: Kevin Ansfield Date: Fri, 14 May 2021 11:57:29 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fixed=20feature=20images=20in=20?= =?UTF-8?q?emails=20appearing=20very=20wide=20in=20Outlook?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes https://github.com/TryGhost/Team/issues/675 Outlook will display images at their native resolution if no `width` attribute is supplied. Content images were fixed a while ago but feature images would still render very wide and cause horizontal scroll and text size/alignment issues. - modify `post.feature_image` and add a `post.feature_image_width` property before passing it through to the email template - for Unsplash images we assume all images are larger than 600px so we change the URL to reference a 1200px image and set the image width to 600 (to keep images on retina displays crisp) - for other images we probe the image to fetch the original dimensions and give set an image width of 600 if needed, if it's a locally-hosted image we update the URL to point at a max 1200px version - updated email template to output a `width` attribute on the feature image `` tag if it's set --- .../services/mega/post-email-serializer.js | 31 +++++++++++++++++++ core/server/services/mega/template.js | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/core/server/services/mega/post-email-serializer.js b/core/server/services/mega/post-email-serializer.js index 0e72d77fe9..92fba8e542 100644 --- a/core/server/services/mega/post-email-serializer.js +++ b/core/server/services/mega/post-email-serializer.js @@ -9,6 +9,8 @@ const api = require('../../api'); const {URL} = require('url'); const mobiledocLib = require('../../lib/mobiledoc'); const htmlToText = require('html-to-text'); +const {isUnsplashImage, isLocalContentImage} = require('@tryghost/kg-default-cards/lib/utils'); +const logging = require('../../../shared/logging'); const ALLOWED_REPLACEMENTS = ['first_name']; @@ -151,6 +153,35 @@ const serialize = async (postModel, options = {isBrowserPreview: false, apiVersi uppercaseHeadings: false }); + // Outlook will render feature images at full-size breaking the layout. + // Content images fix this by rendering max 600px images - do the same for feature image here + if (isUnsplashImage(post.feature_image)) { + // Unsplash images have a minimum size so assuming 1200px is safe + const unsplashUrl = new URL(post.feature_image); + unsplashUrl.searchParams.set('w', 1200); + + post.feature_image = unsplashUrl.href; + post.feature_image_width = 600; + } else { + const {imageSize} = require('../../lib/image'); + try { + const size = await imageSize.getImageSizeFromUrl(post.feature_image); + + if (size.width >= 600) { + // keep original image, just set a fixed width + post.feature_image_width = 600; + } + + if (isLocalContentImage(post.feature_image, urlUtils.getSiteUrl())) { + // we can safely request a 1200px image - Ghost will serve the original if it's smaller + post.feature_image = post.feature_image.replace(/\/content\/images\//, '/content/images/size/w1200/'); + } + } catch (err) { + // log and proceed. Using original feature_image without fixed width isn't fatal. + logging.error(err); + } + } + const templateSettings = { showSiteHeader: settingsCache.get('newsletter_show_header'), bodyFontCategory: settingsCache.get('newsletter_body_font_category'), diff --git a/core/server/services/mega/template.js b/core/server/services/mega/template.js index 018595f740..3760fe1068 100644 --- a/core/server/services/mega/template.js +++ b/core/server/services/mega/template.js @@ -914,7 +914,7 @@ ${ templateSettings.showBadge ? ` ${post.feature_image ? ` - + ` : ``}