Fix TwitterCard meta tags

TwitterCard meta tags are supposed to use the attributes "name" and "content".
OpenGraph tags use the attributes "property" and "content".

Twitter itself is smart enough to detect broken meta tags and discover the TwitterCard
using "property" and "content", but other platforms that only implement parsing of TwitterCards
and not OpenGraph may fail to correctly detect the tags as they're under the wrong attributes.

> "Open Graph protocol also specifies the use of property and content attributes for markup while
> Twitter cards use name and content. Twitter’s parser will fall back to using property and content,
> so there is no need to modify existing Open Graph protocol markup if it already exists." [0]

[0] https://developer.twitter.com/en/docs/twitter-for-websites/cards/guides/getting-started
This commit is contained in:
Mark Felder 2022-12-19 14:40:08 -05:00 committed by XxXCertifiedForkliftDriverXxX
parent 2a290cb331
commit 997551bac9
2 changed files with 49 additions and 50 deletions

View file

@ -20,12 +20,12 @@ def build_tags(%{activity_id: id, object: object, user: user}) do
[
title_tag(user),
{:meta, [property: "twitter:description", content: scrubbed_content], []}
{:meta, [name: "twitter:description", content: scrubbed_content], []}
] ++
if attachments == [] or Metadata.activity_nsfw?(object) do
[
image_tag(user),
{:meta, [property: "twitter:card", content: "summary"], []}
{:meta, [name: "twitter:card", content: "summary"], []}
]
else
attachments
@ -37,20 +37,19 @@ def build_tags(%{user: user}) do
with truncated_bio = Utils.scrub_html_and_truncate(user.bio) do
[
title_tag(user),
{:meta, [property: "twitter:description", content: truncated_bio], []},
{:meta, [name: "twitter:description", content: truncated_bio], []},
image_tag(user),
{:meta, [property: "twitter:card", content: "summary"], []}
{:meta, [name: "twitter:card", content: "summary"], []}
]
end
end
defp title_tag(user) do
{:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []}
{:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []}
end
def image_tag(user) do
{:meta, [property: "twitter:image", content: MediaProxy.preview_url(User.avatar_url(user))],
[]}
{:meta, [name: "twitter:image", content: MediaProxy.preview_url(User.avatar_url(user))], []}
end
defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
@ -60,10 +59,10 @@ defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
case Utils.fetch_media_type(@media_types, url["mediaType"]) do
"audio" ->
[
{:meta, [property: "twitter:card", content: "player"], []},
{:meta, [property: "twitter:player:width", content: "480"], []},
{:meta, [property: "twitter:player:height", content: "80"], []},
{:meta, [property: "twitter:player", content: player_url(id)], []}
{:meta, [name: "twitter:card", content: "player"], []},
{:meta, [name: "twitter:player:width", content: "480"], []},
{:meta, [name: "twitter:player:height", content: "80"], []},
{:meta, [name: "twitter:player", content: player_url(id)], []}
| acc
]
@ -74,10 +73,10 @@ defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
# workaround.
"image" ->
[
{:meta, [property: "twitter:card", content: "summary_large_image"], []},
{:meta, [name: "twitter:card", content: "summary_large_image"], []},
{:meta,
[
property: "twitter:player",
name: "twitter:player",
content: MediaProxy.url(url["href"])
], []}
| acc
@ -90,14 +89,14 @@ defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
width = url["width"] || 480
[
{:meta, [property: "twitter:card", content: "player"], []},
{:meta, [property: "twitter:player", content: player_url(id)], []},
{:meta, [property: "twitter:player:width", content: "#{width}"], []},
{:meta, [property: "twitter:player:height", content: "#{height}"], []},
{:meta, [property: "twitter:player:stream", content: MediaProxy.url(url["href"])],
{:meta, [name: "twitter:card", content: "player"], []},
{:meta, [name: "twitter:player", content: player_url(id)], []},
{:meta, [name: "twitter:player:width", content: "#{width}"], []},
{:meta, [name: "twitter:player:height", content: "#{height}"], []},
{:meta, [name: "twitter:player:stream", content: MediaProxy.url(url["href"])],
[]},
{:meta,
[property: "twitter:player:stream:content_type", content: url["mediaType"]], []}
{:meta, [name: "twitter:player:stream:content_type", content: url["mediaType"]],
[]}
| acc
]
@ -123,8 +122,8 @@ defp maybe_add_dimensions(metadata, url) do
!is_nil(url["height"]) && !is_nil(url["width"]) ->
metadata ++
[
{:meta, [property: "twitter:player:width", content: "#{url["width"]}"], []},
{:meta, [property: "twitter:player:height", content: "#{url["height"]}"], []}
{:meta, [name: "twitter:player:width", content: "#{url["width"]}"], []},
{:meta, [name: "twitter:player:height", content: "#{url["height"]}"], []}
]
true ->

View file

@ -22,10 +22,10 @@ test "it renders twitter card for user info" do
res = TwitterCard.build_tags(%{user: user})
assert res == [
{:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
{:meta, [property: "twitter:description", content: "born 19 March 1994"], []},
{:meta, [property: "twitter:image", content: avatar_url], []},
{:meta, [property: "twitter:card", content: "summary"], []}
{:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []},
{:meta, [name: "twitter:description", content: "born 19 March 1994"], []},
{:meta, [name: "twitter:image", content: avatar_url], []},
{:meta, [name: "twitter:card", content: "summary"], []}
]
end
@ -47,11 +47,11 @@ test "it uses summary twittercard if post has no attachment" do
result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
assert [
{:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
{:meta, [property: "twitter:description", content: "pleroma in a nutshell"], []},
{:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"],
{:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []},
{:meta, [name: "twitter:description", content: "pleroma in a nutshell"], []},
{:meta, [name: "twitter:image", content: "http://localhost:4001/images/avi.png"],
[]},
{:meta, [property: "twitter:card", content: "summary"], []}
{:meta, [name: "twitter:card", content: "summary"], []}
] == result
end
@ -73,15 +73,15 @@ test "it uses summary as description if post has one" do
result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
assert [
{:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
{:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []},
{:meta,
[
property: "twitter:description",
name: "twitter:description",
content: "Public service announcement on caffeine consumption"
], []},
{:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"],
{:meta, [name: "twitter:image", content: "http://localhost:4001/images/avi.png"],
[]},
{:meta, [property: "twitter:card", content: "summary"], []}
{:meta, [name: "twitter:card", content: "summary"], []}
] == result
end
@ -123,11 +123,11 @@ test "it renders avatar not attachment if post is nsfw and unfurl_nsfw is disabl
result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
assert [
{:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
{:meta, [property: "twitter:description", content: "pleroma in a nutshell"], []},
{:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"],
{:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []},
{:meta, [name: "twitter:description", content: "pleroma in a nutshell"], []},
{:meta, [name: "twitter:image", content: "http://localhost:4001/images/avi.png"],
[]},
{:meta, [property: "twitter:card", content: "summary"], []}
{:meta, [name: "twitter:card", content: "summary"], []}
] == result
end
@ -179,26 +179,26 @@ test "it renders supported types of attachments and skips unknown types" do
result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
assert [
{:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
{:meta, [property: "twitter:description", content: "pleroma in a nutshell"], []},
{:meta, [property: "twitter:card", content: "summary_large_image"], []},
{:meta, [property: "twitter:player", content: "https://pleroma.gov/tenshi.png"], []},
{:meta, [property: "twitter:player:width", content: "1280"], []},
{:meta, [property: "twitter:player:height", content: "1024"], []},
{:meta, [property: "twitter:card", content: "player"], []},
{:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []},
{:meta, [name: "twitter:description", content: "pleroma in a nutshell"], []},
{:meta, [name: "twitter:card", content: "summary_large_image"], []},
{:meta, [name: "twitter:player", content: "https://pleroma.gov/tenshi.png"], []},
{:meta, [name: "twitter:player:width", content: "1280"], []},
{:meta, [name: "twitter:player:height", content: "1024"], []},
{:meta, [name: "twitter:card", content: "player"], []},
{:meta,
[
property: "twitter:player",
name: "twitter:player",
content: Router.Helpers.o_status_url(Endpoint, :notice_player, activity.id)
], []},
{:meta, [property: "twitter:player:width", content: "800"], []},
{:meta, [property: "twitter:player:height", content: "600"], []},
{:meta, [name: "twitter:player:width", content: "800"], []},
{:meta, [name: "twitter:player:height", content: "600"], []},
{:meta,
[
property: "twitter:player:stream",
name: "twitter:player:stream",
content: "https://pleroma.gov/about/juche.webm"
], []},
{:meta, [property: "twitter:player:stream:content_type", content: "video/webm"], []}
{:meta, [name: "twitter:player:stream:content_type", content: "video/webm"], []}
] == result
end
end