Description
Expected Behavior
The Pinterest social share link generated for each post should:
- Use the page title as the
description
. - Use the URL of the
featured_image
for themedia
parameter. - Properly encode all fields (e.g., no special characters causing issues).
Example of expected Pinterest share link:
For the site: https://sedward5.com/deltas-sky-breeze-an-airborne-cocktail-grounded-in-nostalgia/
https://www.pinterest.com/pin/create/button/?url=https%3A%2F%2Fsedward5.com%2Fdeltas-sky-breeze-an-airborne-cocktail-grounded-in-nostalgia%2F&media=https%3A%2F%2Fsedward5.com%2Fdeltas-sky-breeze-an-airborne-cocktail-grounded-in-nostalgia%2FIMG_2678-scaled.webp&description=Delta%20Sky%20Breeze
Current Behavior
The generated Pinterest share link incorrectly:
- Uses the page summary as the
description
, which is often verbose and unsuitable. - Uses the permalink URL as the
media
, which should be the featured image URL. - This results in an error when attempting to share on Pinterest
Example of generated link:
https://pinterest.com/pin/create/button/?&description=+Jump+to+Recipe+For+a+period+of+time%2C+and+perhaps+even+still+to+a+dedicated+few%2C+a+cocktail+known+as+the+Sky+Breeze+reigned+supreme+in+the+rarefied+atmosphere+of+Delta+Airlines+flights.+This+was+not+your+average+in-flight+drink%3B+the+Sky+Breeze+was+an+esoteric+libation+with+its+own+dedicated+following%2C+a+cocktail+cult%2C+if+you+will.%0AWhile+the+Sky+Breeze+is+based+on+a+terrestrial+cocktail%2C+something+about+sipping+it+at+30%2C000+feet+made+it+extraordinary.+A+blend+of+Sky+Vodka%2C+Mott%E2%80%99s+Cranberry+Apple+Juice%2C+and+a+can+of+Fresca%2C+it+was+a+deceptively+simple+mix+that+delivered+a+sweet%2C+fruity%2C+and+refreshing+drink+%E2%80%93+a+perfect+companion+for+the+long+haul.%0A&media=https%3A%2F%2Fsedward5.com%2Fdeltas-sky-breeze-an-airborne-cocktail-grounded-in-nostalgia%2F&url=https%3A%2F%2Fsedward5.com%2Fdeltas-sky-breeze-an-airborne-cocktail-grounded-in-nostalgia%2F
Possible Solution
Update the getShareLink.html
partial to correctly extract and encode the required fields when working with Pinterest:
- Use
.Title
for thedescription
. - Use
.Params.featured_image
for themedia
(fall back to a default if not set). Or utilize the getpartial "func/GetFeaturedImage.html"
- Properly encode URLs and descriptions.
Proposed code update:
{{- $title := $context.Title | transform.Plainify | transform.HTMLEscape -}}
{{- $description := $context.Title | transform.Plainify | transform.HTMLEscape -}}
{{- $permalink := $context.Permalink | transform.HTMLEscape -}}
{{- $media := $context.Params.featured_image | default "default-image-url" | transform.AbsURL | transform.HTMLEscape -}}
{{- $link := fmt.Printf "%s?" $setup.link -}}
{{- $link = fmt.Printf "%surl=%s" $link $permalink -}}
{{- $link = fmt.Printf "%s&media=%s" $link $media -}}
{{- $link = fmt.Printf "%s&description=%s" $link $description -}}
{{- return $link -}}
Steps to Reproduce
- Use the Pinterest share button on a post with a featured image and summary.
- Inspect the generated Pinterest URL.
- Note the issues with the description and media parameters.
- Attempt to share a post on Pinterest
The bigger picture (we need context)
-
Running MacOS 15.2
-
Also Running in CloudFlare pages.
-
hugo v0.139.3+extended+withdeploy darwin/amd64 BuildDate=2024-11-29T15:36:56Z VendorInfo=brew
-
go version go1.23.4 darwin/amd64
-
b06949e themes/gohugo-theme-ananke (v2.11.2-17-gb06949e)
Hugo Config
archetypedir = 'archetypes'
assetdir = 'assets'
baseurl = 'https://sedward5.com/'
cachedir = 'xxxxx/Library/Caches/hugo_cache'
canonifyurls = true
capitalizelisttitles = true
contentdir = 'content'
datadir = 'data'
defaultcontentlanguage = 'en'
enablerobotstxt = true
environment = 'production'
i18ndir = 'i18n'
layoutdir = 'layouts'
pluralizelisttitles = true
publishdir = 'public'
resourcedir = 'resources'
staticdir = ['static']
summarylength = 70
theme = ['gohugo-theme-ananke']
themesdir = 'themes'
timeout = '30s'
title = 'Cyber Mixology'
titlecasestyle = 'AP'
workingdir = 'xxxxx/hugo-sedward5.com'
[build]
useresourcecachewhen = 'fallback'
[build.buildstats]
[[build.cachebusters]]
source = '(postcss|tailwind).config.js'
target = '(css|styles|scss|sass)'
[caches]
[caches.assets]
dir = ':resourceDir/_gen'
maxage = -1
[caches.getcsv]
dir = ':cacheDir/:project'
maxage = -1
[caches.getjson]
dir = ':cacheDir/:project'
maxage = -1
[caches.getresource]
dir = ':cacheDir/:project'
maxage = -1
[caches.images]
dir = ':resourceDir/_gen'
maxage = -1
[caches.misc]
dir = ':cacheDir/:project'
maxage = -1
[caches.modules]
dir = ':cacheDir/modules'
maxage = -1
[deployment]
invalidatecdn = true
maxdeletes = 256
workers = 10
[frontmatter]
date = ['date', 'publishdate', 'pubdate', 'published', 'lastmod', 'modified']
expirydate = ['expirydate', 'unpublishdate']
lastmod = [':git', 'lastmod', 'modified', 'date', 'publishdate', 'pubdate', 'published']
publishdate = ['publishdate', 'pubdate', 'published', 'date']
[httpcache]
[httpcache.cache]
[httpcache.cache.for]
excludes = ['**']
[[httpcache.polls]]
disable = true
high = '0s'
low = '0s'
[httpcache.polls.for]
includes = ['**']
[imaging]
bgcolor = '#ffffff'
hint = 'photo'
quality = 75
resamplefilter = 'box'
[languages]
[languages.en]
[markup]
defaultmarkdownhandler = 'goldmark'
[markup.asciidocext]
backend = 'html5'
failurelevel = 'fatal'
noheaderorfooter = true
safemode = 'unsafe'
[markup.goldmark]
[markup.goldmark.extensions]
definitionlist = true
footnote = true
linkify = true
linkifyprotocol = 'https'
strikethrough = true
table = true
tasklist = true
[markup.goldmark.extensions.cjk]
eastasianlinebreaksstyle = 'simple'
[markup.goldmark.extensions.extras]
[markup.goldmark.extensions.extras.delete]
[markup.goldmark.extensions.extras.insert]
[markup.goldmark.extensions.extras.mark]
[markup.goldmark.extensions.extras.subscript]
[markup.goldmark.extensions.extras.superscript]
[markup.goldmark.extensions.passthrough]
[markup.goldmark.extensions.passthrough.delimiters]
[markup.goldmark.extensions.typographer]
apostrophe = '’'
ellipsis = '…'
emdash = '—'
endash = '–'
leftanglequote = '«'
leftdoublequote = '“'
leftsinglequote = '‘'
rightanglequote = '»'
rightdoublequote = '”'
rightsinglequote = '’'
[markup.goldmark.parser]
autoheadingid = true
autoheadingidtype = 'github'
wrapstandaloneimagewithinparagraph = true
[markup.goldmark.parser.attribute]
title = true
[markup.goldmark.renderer]
unsafe = true
[markup.goldmark.renderhooks]
[markup.goldmark.renderhooks.image]
[markup.goldmark.renderhooks.link]
[markup.highlight]
codefences = true
linenostart = 1
linenumbersintable = true
noclasses = true
style = 'monokai'
tabwidth = 4
[markup.tableofcontents]
endlevel = 3
startlevel = 2
[mediatypes]
[mediatypes.'application/json']
delimiter = '.'
suffixes = ['json']
[mediatypes.'application/manifest+json']
delimiter = '.'
suffixes = ['webmanifest']
[mediatypes.'application/octet-stream']
delimiter = '.'
[mediatypes.'application/pdf']
delimiter = '.'
suffixes = ['pdf']
[mediatypes.'application/rss+xml']
delimiter = '.'
suffixes = ['xml', 'rss']
[mediatypes.'application/toml']
delimiter = '.'
suffixes = ['toml']
[mediatypes.'application/wasm']
delimiter = '.'
suffixes = ['wasm']
[mediatypes.'application/xml']
delimiter = '.'
suffixes = ['xml']
[mediatypes.'application/yaml']
delimiter = '.'
suffixes = ['yaml', 'yml']
[mediatypes.'font/otf']
delimiter = '.'
suffixes = ['otf']
[mediatypes.'font/ttf']
delimiter = '.'
suffixes = ['ttf']
[mediatypes.'image/bmp']
delimiter = '.'
suffixes = ['bmp']
[mediatypes.'image/gif']
delimiter = '.'
suffixes = ['gif']
[mediatypes.'image/jpeg']
delimiter = '.'
suffixes = ['jpg', 'jpeg', 'jpe', 'jif', 'jfif']
[mediatypes.'image/png']
delimiter = '.'
suffixes = ['png']
[mediatypes.'image/svg+xml']
delimiter = '.'
suffixes = ['svg']
[mediatypes.'image/tiff']
delimiter = '.'
suffixes = ['tif', 'tiff']
[mediatypes.'image/webp']
delimiter = '.'
suffixes = ['webp']
[mediatypes.'text/asciidoc']
delimiter = '.'
suffixes = ['adoc', 'asciidoc', 'ad']
[mediatypes.'text/calendar']
delimiter = '.'
suffixes = ['ics']
[mediatypes.'text/css']
delimiter = '.'
suffixes = ['css']
[mediatypes.'text/csv']
delimiter = '.'
suffixes = ['csv']
[mediatypes.'text/html']
delimiter = '.'
suffixes = ['html', 'htm']
[mediatypes.'text/javascript']
delimiter = '.'
suffixes = ['js', 'jsm', 'mjs']
[mediatypes.'text/jsx']
delimiter = '.'
suffixes = ['jsx']
[mediatypes.'text/markdown']
delimiter = '.'
suffixes = ['md', 'mdown', 'markdown']
[mediatypes.'text/org']
delimiter = '.'
suffixes = ['org']
[mediatypes.'text/pandoc']
delimiter = '.'
suffixes = ['pandoc', 'pdc']
[mediatypes.'text/plain']
delimiter = '.'
suffixes = ['txt']
[mediatypes.'text/rst']
delimiter = '.'
suffixes = ['rst']
[mediatypes.'text/tsx']
delimiter = '.'
suffixes = ['tsx']
[mediatypes.'text/typescript']
delimiter = '.'
suffixes = ['ts']
[mediatypes.'text/x-sass']
delimiter = '.'
suffixes = ['sass']
[mediatypes.'text/x-scss']
delimiter = '.'
suffixes = ['scss']
[mediatypes.'video/3gpp']
delimiter = '.'
suffixes = ['3gpp', '3gp']
[mediatypes.'video/mp4']
delimiter = '.'
suffixes = ['mp4']
[mediatypes.'video/mpeg']
delimiter = '.'
suffixes = ['mpg', 'mpeg']
[mediatypes.'video/ogg']
delimiter = '.'
suffixes = ['ogv']
[mediatypes.'video/webm']
delimiter = '.'
suffixes = ['webm']
[mediatypes.'video/x-msvideo']
delimiter = '.'
suffixes = ['avi']
[menus]
[[menus.main]]
name = 'Home'
pageref = '/'
weight = 10
[[menus.main]]
name = 'Cocktails'
pageref = '/categories/cocktails'
weight = 20
[[menus.main]]
name = 'Security'
pageref = '/categories/security'
weight = 30
[[menus.main]]
name = 'About'
pageref = '/about'
weight = 40
[minify]
[minify.tdewolff]
[minify.tdewolff.css]
keepcss2 = true
[minify.tdewolff.html]
keepdefaultattrvals = true
keepdocumenttags = true
keependtags = true
keepspecialcomments = true
templatedelims = ['', '']
[minify.tdewolff.js]
version = 2022
[minify.tdewolff.json]
[minify.tdewolff.svg]
[minify.tdewolff.xml]
[module]
noproxy = 'none'
private = '.'
proxy = 'direct'
workspace = 'off'
[module.hugoversion]
[[module.imports]]
path = 'gohugo-theme-ananke'
[[module.mounts]]
source = 'content'
target = 'content'
[[module.mounts]]
source = 'data'
target = 'data'
[[module.mounts]]
source = 'layouts'
target = 'layouts'
[[module.mounts]]
source = 'i18n'
target = 'i18n'
[[module.mounts]]
source = 'archetypes'
target = 'archetypes'
[[module.mounts]]
source = 'assets'
target = 'assets'
[[module.mounts]]
source = 'static'
target = 'static'
[outputformats]
[outputformats.amp]
basename = 'index'
ishtml = true
mediatype = 'text/html'
path = 'amp'
permalinkable = true
rel = 'amphtml'
[outputformats.calendar]
basename = 'index'
isplaintext = true
mediatype = 'text/calendar'
protocol = 'webcal://'
rel = 'alternate'
[outputformats.css]
basename = 'styles'
isplaintext = true
mediatype = 'text/css'
notalternative = true
rel = 'stylesheet'
[outputformats.csv]
basename = 'index'
isplaintext = true
mediatype = 'text/csv'
rel = 'alternate'
[outputformats.html]
basename = 'index'
ishtml = true
mediatype = 'text/html'
permalinkable = true
rel = 'canonical'
weight = 10
[outputformats.json]
basename = 'cocktail-index'
isplaintext = true
mediatype = 'application/json'
rel = 'alternate'
[outputformats.markdown]
basename = 'index'
isplaintext = true
mediatype = 'text/markdown'
rel = 'alternate'
[outputformats.robots]
basename = 'robots'
isplaintext = true
mediatype = 'text/plain'
rel = 'alternate'
root = true
[outputformats.rss]
basename = 'index'
mediatype = 'application/rss+xml'
nougly = true
rel = 'alternate'
[outputformats.sitemap]
basename = 'sitemap'
mediatype = 'application/xml'
rel = 'sitemap'
ugly = true
[outputformats.webappmanifest]
basename = 'manifest'
isplaintext = true
mediatype = 'application/manifest+json'
notalternative = true
rel = 'manifest'
[outputs]
home = ['html', 'json']
page = ['html']
rss = ['rss']
section = ['html', 'rss']
taxonomy = ['html', 'rss']
term = ['html', 'rss']
[page]
nextprevinsectionsortorder = 'desc'
nextprevsortorder = 'desc'
[pagination]
pagersize = 10
path = 'page'
[params]
author = 'Steve Edwards'
custom_css = ['css/custom.css', 'css/print-recipe.css']
custom_js = ['js/print_recipe.js']
site_logo = 'logo.svg'
subtitle = 'sedward5.com'
[params.ananke]
show_recent_posts = true
[params.ananke.social]
icon_path = 'ananke/socials/%s.svg'
[params.ananke.social.bluesky]
username = 'sedward5'
[params.ananke.social.facebook]
username = 'cyber-mixology'
[params.ananke.social.follow]
networks = ['facebook', 'bluesky', 'linkedin', 'github']
[params.ananke.social.github]
username = 'sedward5'
[params.ananke.social.linkedin]
username = 'sedward5'
[[params.ananke.social.networks]]
color = '#1185fe'
icon = 'bluesky'
label = 'Bluesky'
link = 'https://bsky.app/intent/compose'
profile = 'https://bsky.app/profile/%s'
slug = 'bluesky'
[params.ananke.social.networks.particles]
text = 'permalink'
[[params.ananke.social.networks]]
icon = 'envelope'
label = 'Email'
link = 'mailto:'
slug = 'email'
[params.ananke.social.networks.particles]
body = 'permalink'
subject = 'title'
[[params.ananke.social.networks]]
color = '#3b5998'
icon = 'facebook'
label = 'Facebook'
link = 'https://facebook.com/sharer/sharer.php'
profile = 'https://www.facebook.com/%s'
slug = 'facebook'
[params.ananke.social.networks.particles]
u = 'permalink'
[[params.ananke.social.networks]]
color = '#6cc644'
icon = 'github'
label = 'GitHub'
profile = 'https://github.com/%s/'
slug = 'github'
[[params.ananke.social.networks]]
color = '#FC6D26'
icon = 'gitlab'
label = 'GitLab'
profile = 'https://gitlab.com/%s/'
slug = 'gitlab'
[[params.ananke.social.networks]]
color = '#ff4000'
icon = 'hacker-news'
label = 'Hacker News'
link = 'https://news.ycombinator.com/submitlink'
profile = 'https://news.ycombinator.com/user?id=%s'
slug = 'hackernews'
[params.ananke.social.networks.particles]
t = 'description'
u = 'permalink'
[[params.ananke.social.networks]]
color = '#e1306c'
icon = 'instagram'
label = 'Instagram'
profile = 'https://www.instagram.com/%s/'
slug = 'instagram'
[[params.ananke.social.networks]]
color = '#3d76ff'
icon = 'keybase'
label = 'Keybase'
profile = 'https://keybase.io/%s'
slug = 'keybase'
[[params.ananke.social.networks]]
color = '#0077b5'
icon = 'linkedin'
label = 'LinkedIn'
link = 'https://www.linkedin.com/shareArticle'
profile = 'http://linkedin.com/in/%s'
slug = 'linkedin'
[params.ananke.social.networks.particles]
params = 'mini=true'
source = 'permalink'
summary = 'description'
title = 'title'
url = 'permalink'
[[params.ananke.social.networks]]
color = '#0077b5'
icon = 'medium'
label = 'Medium'
profile = 'https://medium.com/@%s/'
slug = 'medium'
[[params.ananke.social.networks]]
color = '#6364FF'
icon = 'mastodon'
label = 'Mastodon'
slug = 'mastodon'
[[params.ananke.social.networks]]
color = '#e60023'
icon = 'pinterest'
label = 'Pinterest'
link = 'https://pinterest.com/pin/create/button/'
profile = 'https://www.pinterest.com/%s/'
slug = 'pinterest'
[params.ananke.social.networks.particles]
description = 'description'
media = 'permalink'
url = 'permalink'
[[params.ananke.social.networks]]
color = '#ff4500'
icon = 'reddit'
label = 'Reddit'
link = 'https://reddit.com/submit/'
profile = 'https://www.reddit.com/user/%s/'
slug = 'reddit'
[params.ananke.social.networks.particles]
params = 'resubmit=true'
title = 'title'
url = 'permalink'
[[params.ananke.social.networks]]
color = '#ff6f1a'
icon = 'rss'
label = 'RSS'
slug = 'rss'
[[params.ananke.social.networks]]
color = '#E01E5A'
icon = 'slack'
label = 'Slack'
slug = 'slack'
[[params.ananke.social.networks]]
color = '#f48024'
icon = 'stack-overflow'
label = 'Stack Overflow'
profile = 'https://stackoverflow.com/users/%s'
slug = 'stackoverflow'
[[params.ananke.social.networks]]
color = '#0088cc'
icon = 'telegram'
label = 'Telegram'
link = 'https://telegram.me/share/url'
profile = 'https://t.me/%s'
slug = 'telegram'
[params.ananke.social.networks.particles]
text = 'description'
url = 'permalink'
[[params.ananke.social.networks]]
color = '#fe2c55'
icon = 'tiktok'
label = 'TikTok'
profile = 'https://www.tiktok.com/@%s'
slug = 'tiktok'
[[params.ananke.social.networks]]
color = '#35465c'
icon = 'tumblr'
label = 'Tumblr'
link = 'https://www.tumblr.com/widgets/share/tool'
profile = 'https://www.tumblr.com/blog/%s'
slug = 'tumblr'
[params.ananke.social.networks.particles]
canonicalurl = 'permalink'
caption = 'description'
content = 'description'
params = 'posttype=link'
sharesource = 'source'
title = 'title'
[[params.ananke.social.networks]]
color = '#1da1f2'
icon = 'twitter'
label = 'Twitter'
link = 'https://twitter.com/intent/tweet/'
profile = 'https://twitter.com/%s'
slug = 'twitter'
[params.ananke.social.networks.particles]
text = 'description'
url = 'permalink'
[[params.ananke.social.networks]]
color = '#25d366'
icon = 'whatsapp'
label = 'WhatsApp'
link = 'whatsapp://send'
linkintext = true
slug = 'whatsapp'
[params.ananke.social.networks.particles]
text = 'description'
[[params.ananke.social.networks]]
color = '#026466'
icon = 'xing'
label = 'Xing'
link = 'https://www.xing.com/app/user'
profile = 'https://www.xing.com/profile/%s'
separator = ';'
slug = 'xing'
[params.ananke.social.networks.particles]
params = 'op=share'
title = 'title'
url = 'permalink'
[[params.ananke.social.networks]]
color = '#000000'
icon = 'x-twitter'
label = 'X'
link = 'https://twitter.com/intent/tweet/'
profile = 'https://x.com/%s'
slug = 'x-twitter'
[params.ananke.social.networks.particles]
text = 'description'
url = 'permalink'
[[params.ananke.social.networks]]
color = '#cd201f'
icon = 'youtube'
label = 'YouTube'
profile = 'https://www.youtube.com/@%s'
slug = 'youtube'
[params.ananke.social.share]
icons = true
networks = ['email', 'facebook', 'bluesky', 'linkedin']
sharetext = true
[permalinks]
[privacy]
[privacy.disqus]
[privacy.googleanalytics]
[privacy.instagram]
[privacy.twitter]
[privacy.vimeo]
[privacy.youtube]
[related]
threshold = 80
[[related.indices]]
name = 'keywords'
type = 'basic'
weight = 100
[[related.indices]]
name = 'date'
type = 'basic'
weight = 10
[[related.indices]]
name = 'tags'
type = 'basic'
weight = 80
[security]
[security.exec]
allow = ['^(dart-)?sass(-embedded)?$', '^go$', '^git$', '^npx$', '^postcss$', '^tailwindcss$']
osenv = ['(?i)^((HTTPS?|NO)PROXY|PATH(EXT)?|APPDATA|TE?MP|TERM|GO\w+|(XDG_CONFIG)?HOME|USERPROFILE|SSH_AUTH_SOCK|DISPLAY|LANG|SYSTEMDRIVE)$']
[security.funcs]
getenv = ['^HUGO_', '^CI$']
[security.http]
methods = ['(?i)GET|POST']
urls = ['.*']
[server]
[[server.redirects]]
from = '**'
status = 404
to = '/404.html'
[services]
[services.disqus]
[services.googleanalytics]
id = 'xxxxx'
[services.instagram]
[services.rss]
limit = -1
[services.twitter]
[sitemap]
filename = 'sitemap.xml'
priority = -1
[taxonomies]
category = 'categories'
tag = 'tags'
Activity