diff --git a/lib/service/metadata/actor.ex b/lib/service/metadata/actor.ex index e0fc59dc7..90046c361 100644 --- a/lib/service/metadata/actor.ex +++ b/lib/service/metadata/actor.ex @@ -20,14 +20,24 @@ defimpl Mobilizon.Service.Metadata, for: Mobilizon.Actors.Actor do [ Tag.tag(:meta, property: "og:title", content: Actor.display_name_and_username(group)), - Tag.tag(:meta, property: "og:url", content: group.url), + Tag.tag(:meta, + property: "og:url", + content: + Endpoint + |> Routes.page_url( + :actor, + Actor.preferred_username_and_domain(group) + ) + |> URI.decode() + ), Tag.tag(:meta, property: "og:description", content: group.summary), Tag.tag(:meta, property: "og:type", content: "profile"), Tag.tag(:meta, property: "profile:username", content: Actor.preferred_username_and_domain(group) ), - Tag.tag(:meta, property: "twitter:card", content: "summary") + Tag.tag(:meta, property: "twitter:card", content: "summary"), + Tag.tag(:meta, property: "twitter:site", content: "@joinmobilizon") ] |> maybe_add_avatar(group) |> add_group_schema(group) @@ -50,8 +60,22 @@ defimpl Mobilizon.Service.Metadata, for: Mobilizon.Actors.Actor do @spec add_group_schema(list(Tag.t()), Actor.t()) :: list(Tag.t()) defp add_group_schema(tags, %Actor{} = group) do + breadcrumbs = %{ + "@context" => "https://schema.org", + "@type" => "BreadcrumbList", + "itemListElement" => [ + %{ + "@type" => "ListItem", + "position" => 1, + "name" => Actor.display_name(group) + } + ] + } + tags ++ [ + ~s{} + |> HTML.raw(), ~s{} |> HTML.raw() ] end diff --git a/lib/service/metadata/event.ex b/lib/service/metadata/event.ex index 6dede3f2a..0e361f41d 100644 --- a/lib/service/metadata/event.ex +++ b/lib/service/metadata/event.ex @@ -1,9 +1,12 @@ defimpl Mobilizon.Service.Metadata, for: Mobilizon.Events.Event do alias Phoenix.HTML alias Phoenix.HTML.Tag + alias Mobilizon.Actors.Actor alias Mobilizon.Addresses.Address alias Mobilizon.Events.{Event, EventOptions} + alias Mobilizon.Web.Endpoint alias Mobilizon.Web.JsonLD.ObjectView + alias Mobilizon.Web.Router.Helpers, as: Routes import Mobilizon.Service.Metadata.Utils, only: [process_description: 2, strip_tags: 1, datetime_to_string: 2, render_address: 1] @@ -35,9 +38,64 @@ defimpl Mobilizon.Service.Metadata, for: Mobilizon.Events.Event do ] end + breadcrumbs = + if event.attributed_to do + [ + %{ + "@context" => "https://schema.org", + "@type" => "BreadcrumbList", + "itemListElement" => [ + %{ + "@type" => "ListItem", + "position" => 1, + "name" => Actor.display_name(event.attributed_to), + "item" => + Endpoint + |> Routes.page_url( + :actor, + Actor.preferred_username_and_domain(event.attributed_to) + ) + |> URI.decode() + }, + %{ + "@type" => "ListItem", + "position" => 2, + "name" => event.title + } + ] + } + ] + else + [] + end + + breadcrumbs = + breadcrumbs ++ + [ + %{ + "@context" => "https://schema.org", + "@type" => "BreadcrumbList", + "itemListElement" => [ + %{ + "@type" => "ListItem", + "position" => 1, + "name" => "Events", + "item" => "#{Endpoint.url()}/search" + }, + %{ + "@type" => "ListItem", + "position" => 2, + "name" => event.title + } + ] + } + ] + tags ++ [ Tag.tag(:meta, property: "twitter:card", content: "summary_large_image"), + ~s{} + |> HTML.raw(), ~s{} |> HTML.raw() ] end diff --git a/lib/service/metadata/instance.ex b/lib/service/metadata/instance.ex index 776a613d9..3372b5821 100644 --- a/lib/service/metadata/instance.ex +++ b/lib/service/metadata/instance.ex @@ -20,18 +20,20 @@ defmodule Mobilizon.Service.Metadata.Instance do description = Utils.process_description(Config.instance_description()) title = "#{Config.instance_name()} - Mobilizon" - instance_json_ld = """ - + + instance_json_ld = """ + """ [ diff --git a/lib/service/metadata/post.ex b/lib/service/metadata/post.ex index db3486eba..a0de60ae5 100644 --- a/lib/service/metadata/post.ex +++ b/lib/service/metadata/post.ex @@ -1,9 +1,12 @@ defimpl Mobilizon.Service.Metadata, for: Mobilizon.Posts.Post do alias Phoenix.HTML alias Phoenix.HTML.Tag + alias Mobilizon.Actors.Actor alias Mobilizon.Medias.{File, Media} alias Mobilizon.Posts.Post + alias Mobilizon.Web.Endpoint alias Mobilizon.Web.JsonLD.ObjectView + alias Mobilizon.Web.Router.Helpers, as: Routes import Mobilizon.Service.Metadata.Utils, only: [process_description: 2, strip_tags: 1] def build_tags(%Post{} = post, locale \\ "en") do @@ -21,9 +24,35 @@ defimpl Mobilizon.Service.Metadata, for: Mobilizon.Posts.Post do ] |> maybe_add_post_picture(post) + breadcrumbs = %{ + "@context" => "https://schema.org", + "@type" => "BreadcrumbList", + "itemListElement" => [ + %{ + "@type" => "ListItem", + "position" => 1, + "name" => Actor.display_name(post.attributed_to), + "item" => + Endpoint + |> Routes.page_url( + :actor, + Actor.preferred_username_and_domain(post.attributed_to) + ) + |> URI.decode() + }, + %{ + "@type" => "ListItem", + "position" => 2, + "name" => post.title + } + ] + } + tags ++ [ Tag.tag(:meta, property: "twitter:card", content: "summary_large_image"), + ~s{} + |> HTML.raw(), ~s{} |> HTML.raw() ] end diff --git a/lib/web/views/json_ld/object_view.ex b/lib/web/views/json_ld/object_view.ex index f4de971fc..9f16009b2 100644 --- a/lib/web/views/json_ld/object_view.ex +++ b/lib/web/views/json_ld/object_view.ex @@ -11,13 +11,30 @@ defmodule Mobilizon.Web.JsonLD.ObjectView do @spec render(String.t(), map()) :: map() def render("group.json", %{group: %Actor{} = group}) do - %{ + res = %{ "@context" => "http://schema.org", "@type" => "Organization", "url" => group.url, "name" => group.name || group.preferred_username, "address" => render_address(group) } + + res = + if group.banner do + Map.put(res, "image", group.banner.url) + else + res + end + + if group.physical_address do + Map.put( + res, + "address", + render_one(group.physical_address, ObjectView, "address.json", as: :address) + ) + else + res + end end def render("event.json", %{event: %Event{} = event}) do @@ -93,12 +110,27 @@ defmodule Mobilizon.Web.JsonLD.ObjectView do "@context" => "https://schema.org", "@type" => "Article", "name" => post.title, + "headline" => post.title, "author" => %{ "@type" => "Organization", - "name" => Actor.display_name(post.attributed_to) + "name" => Actor.display_name(post.attributed_to), + "url" => + Endpoint + |> Routes.page_url( + :actor, + Actor.preferred_username_and_domain(post.attributed_to) + ) + |> URI.decode() }, "datePublished" => post.publish_at, - "dateModified" => post.updated_at + "dateModified" => post.updated_at, + "image" => + if(post.picture, + do: [ + post.picture.file.url + ], + else: ["#{Endpoint.url()}/img/mobilizon_default_card.png"] + ) } end diff --git a/test/service/metadata/instance_test.exs b/test/service/metadata/instance_test.exs index e39c67e87..89adc955c 100644 --- a/test/service/metadata/instance_test.exs +++ b/test/service/metadata/instance_test.exs @@ -10,7 +10,9 @@ defmodule Mobilizon.Service.Metadata.InstanceTest do description = Utils.process_description(Config.instance_description()) assert Instance.build_tags() |> Utils.stringify_tags() == - "