diff --git a/app/views/base/layout.scala.html b/app/views/base/layout.scala.html
index 7492c39aba..b48726c35f 100644
--- a/app/views/base/layout.scala.html
+++ b/app/views/base/layout.scala.html
@@ -11,7 +11,7 @@ moreCss: Html = Html(""),
moreJs: Html = Html(""),
zen: Boolean = false,
playing: Boolean = false,
-openGraph: Map[Symbol, String] = Map.empty,
+openGraph: Option[lila.app.ui.OpenGraph] = None,
chessground: Boolean = true,
withLangAnnotations: Boolean = true)(body: Html)(implicit ctx: Context)
@@ -27,17 +27,13 @@ withLangAnnotations: Boolean = true)(body: Html)(implicit ctx: Context)
@cssTag("board.css")
@moreCss
-
+
@if(!robots) {
}
- @openGraph.map {
- case (key, value) => {
-
- }
- }
+ @openGraph.map(_.html)
@if(withLangAnnotations){@langAnnotations}
diff --git a/app/views/blog/layout.scala.html b/app/views/blog/layout.scala.html
index 58e5572ce6..8adf1ee11f 100644
--- a/app/views/blog/layout.scala.html
+++ b/app/views/blog/layout.scala.html
@@ -1,4 +1,4 @@
-@(title: String, side: Option[Html] = None, openGraph: Map[Symbol, String] = Map.empty)(body: Html)(implicit ctx: Context)
+@(title: String, side: Option[Html] = None, openGraph: Option[lila.app.ui.OpenGraph] = None)(body: Html)(implicit ctx: Context)
@moreCss = {
@cssTag("blog.css")
diff --git a/app/views/blog/show.scala.html b/app/views/blog/show.scala.html
index 8fcee713c4..991c669e6a 100644
--- a/app/views/blog/show.scala.html
+++ b/app/views/blog/show.scala.html
@@ -11,13 +11,12 @@
@layout(
title = s"${~doc.getText("blog.title")} | Blog",
side = side.some,
-openGraph = Map(
-'type -> "article",
-'image -> doc.getImage("blog.image", "main").??(_.url),
-'title -> ~doc.getText("blog.title"),
-'site_name -> "lichess.org",
-'url -> s"$netBaseUrl${routes.Blog.show(doc.id, doc.slug).url}",
-'description -> ~doc.getText("blog.shortlede"))) {
+openGraph = lila.app.ui.OpenGraph(
+`type` = "article",
+image = doc.getImage("blog.image", "main").map(_.url),
+title = ~doc.getText("blog.title"),
+url = s"$netBaseUrl${routes.Blog.show(doc.id, doc.slug).url}",
+description = ~doc.getText("blog.shortlede")).some) {
@doc.getText("blog.title")
@meta(doc)
diff --git a/app/views/lobby/home.scala.html b/app/views/lobby/home.scala.html
index a50cfeaace..1966054047 100644
--- a/app/views/lobby/home.scala.html
+++ b/app/views/lobby/home.scala.html
@@ -57,14 +57,12 @@ moreJs = moreJs,
moreCss = cssTag("home.css"),
underchat = underchat.some,
chessground = false,
-openGraph = Map(
-'type -> "website",
-'image -> s"${staticUrl("images/large_tile.png")}",
-'title -> "The best free, adless Chess server",
-'site_name -> "lichess.org",
-'url -> netBaseUrl,
-'description -> trans.freeOnlineChessGamePlayChessNowInACleanInterfaceNoRegistrationNoAdsNoPluginRequiredPlayChessWithComputerFriendsOrRandomOpponents.str()
-)) {
+openGraph = lila.app.ui.OpenGraph(
+image = staticUrl("images/large_tile.png").some,
+title = "The best free, adless Chess server",
+url = netBaseUrl,
+description = trans.freeOnlineChessGamePlayChessNowInACleanInterfaceNoRegistrationNoAdsNoPluginRequiredPlayChessWithComputerFriendsOrRandomOpponents.str()
+).some) {
@translationCall.map(i18n.callBox(_))
diff --git a/app/views/puzzle/layout.scala.html b/app/views/puzzle/layout.scala.html
index 0ffb7dbde9..cdbe44b11a 100644
--- a/app/views/puzzle/layout.scala.html
+++ b/app/views/puzzle/layout.scala.html
@@ -1,4 +1,4 @@
-@(title: String, evenMoreCss: Option[Html] = None, evenMoreJs: Option[Html] = None, openGraph: Map[Symbol, String] = Map.empty)(body: Html)(implicit ctx: Context)
+@(title: String, evenMoreCss: Option[Html] = None, evenMoreJs: Option[Html] = None, openGraph: Option[lila.app.ui.OpenGraph] = None)(body: Html)(implicit ctx: Context)
@moreCss = {
@cssTag("training.css")
diff --git a/app/views/puzzle/show.scala.html b/app/views/puzzle/show.scala.html
index 8ee6091b56..27c24a6c7c 100644
--- a/app/views/puzzle/show.scala.html
+++ b/app/views/puzzle/show.scala.html
@@ -58,15 +58,13 @@ trans.openings)))
@layout(
trans.training.str(),
evenMoreJs = Some(evenMoreJs),
-openGraph = Map(
-'type -> "website",
-'image -> cdnUrl(routes.Export.puzzlePng(puzzle.id).url),
-'title -> s"Chess tactic training • ${puzzle.color.name.capitalize} to play",
-'site_name -> "lichess.org",
-'url -> s"$netBaseUrl${routes.Puzzle.show(puzzle.id).url}",
-'description -> puzzle.color.fold(
+openGraph = lila.app.ui.OpenGraph(
+image = cdnUrl(routes.Export.puzzlePng(puzzle.id).url).some,
+title = s"Chess tactic training • ${puzzle.color.name.capitalize} to play",
+url = s"$netBaseUrl${routes.Puzzle.show(puzzle.id).url}",
+description = s"Tactic puzzle #${puzzle.id}: " + puzzle.color.fold(
trans.findTheBestMoveForWhite,
trans.findTheBestMoveForBlack
-).str())) {
+).str()).some) {
@miniBoardContent
}
diff --git a/app/views/qa/layout.scala.html b/app/views/qa/layout.scala.html
index 33259eb350..0862690586 100644
--- a/app/views/qa/layout.scala.html
+++ b/app/views/qa/layout.scala.html
@@ -1,4 +1,4 @@
-@(title: String, side: Option[Html] = None, openGraph: Map[Symbol, String] = Map.empty, moreJs: Html = Html(""))(body: Html)(implicit ctx: Context)
+@(title: String, side: Option[Html] = None, openGraph: Option[lila.app.ui.OpenGraph] = None, moreJs: Html = Html(""))(body: Html)(implicit ctx: Context)
@sideSection = {
diff --git a/app/views/relay/home.scala.html b/app/views/relay/home.scala.html
index edc98bd76c..136ba48200 100644
--- a/app/views/relay/home.scala.html
+++ b/app/views/relay/home.scala.html
@@ -18,12 +18,10 @@
title = "Watch Chess events",
side = side.some,
moreJs = moreJs,
-openGraph = Map(
-'type -> "website",
-'title -> "Watch chess events",
-'site_name -> "lichess.org",
-'url -> s"$netBaseUrl${routes.Relay.index.url}",
-'description -> "Real-time relay of international chess tournaments")) {
+openGraph = lila.app.ui.OpenGraph(
+title = "Watch chess events",
+url = s"$netBaseUrl${routes.Relay.index.url}",
+description = "Real-time relay of international chess tournaments").some) {
diff --git a/app/views/relay/layout.scala.html b/app/views/relay/layout.scala.html
index b8ec59be39..ee4567b141 100644
--- a/app/views/relay/layout.scala.html
+++ b/app/views/relay/layout.scala.html
@@ -1,4 +1,4 @@
-@(title: String, moreJs: Html = Html(""), side: Option[Html] = None, chat: Option[Html] = None, underchat: Option[Html] = None, chessground: Boolean = true, openGraph: Map[Symbol, String] = Map.empty)(body: Html)(implicit ctx: Context)
+@(title: String, moreJs: Html = Html(""), side: Option[Html] = None, chat: Option[Html] = None, underchat: Option[Html] = None, chessground: Boolean = true, openGraph: Option[lila.app.ui.OpenGraph] = None)(body: Html)(implicit ctx: Context)
@moreCss = {
@cssTag("relay.css")
diff --git a/app/views/relay/show.scala.html b/app/views/relay/show.scala.html
index 08252c587f..94b1488a34 100644
--- a/app/views/relay/show.scala.html
+++ b/app/views/relay/show.scala.html
@@ -44,12 +44,10 @@ chat = chat.map(c => base.chat(c, trans.chatRoom.str())),
underchat = underchat.some,
moreJs = moreJs,
chessground = false,
-openGraph = Map(
-'type -> "website",
-'title -> rel.name,
-'site_name -> "lichess.org",
-'url -> s"$netBaseUrl${routes.Relay.show(rel.id, rel.slug).url}",
-'description -> ~content.flatMap(_.short))) {
+openGraph = lila.app.ui.OpenGraph(
+title = rel.name,
+url = s"$netBaseUrl${routes.Relay.show(rel.id, rel.slug).url}",
+description = ~content.flatMap(_.short)).some) {
@content.flatMap(_.long).map { long =>
@autoLink(long)
}
diff --git a/app/views/round/layout.scala.html b/app/views/round/layout.scala.html
index 4d1f4d7f88..c8759d961d 100644
--- a/app/views/round/layout.scala.html
+++ b/app/views/round/layout.scala.html
@@ -1,4 +1,4 @@
-@(title: String, side: Html, chat: Option[Html] = None, underchat: Option[Html] = None, moreJs: Html = Html(""), openGraph: Map[Symbol, String] = Map.empty, moreCss: Html = Html(""), chessground: Boolean = true, playing: Boolean = false)(body: Html)(implicit ctx: Context)
+@(title: String, side: Html, chat: Option[Html] = None, underchat: Option[Html] = None, moreJs: Html = Html(""), openGraph: Option[lila.app.ui.OpenGraph] = None, moreCss: Html = Html(""), chessground: Boolean = true, playing: Boolean = false)(body: Html)(implicit ctx: Context)
@base.layout(
title = title,
diff --git a/app/views/round/player.scala.html b/app/views/round/player.scala.html
index f715fbfe76..6f71f1beb6 100644
--- a/app/views/round/player.scala.html
+++ b/app/views/round/player.scala.html
@@ -24,7 +24,7 @@ side = views.html.game.side(pov, (data\"game"\"initialFen").asOpt[String], tour,
chat = game.tournamentId.isEmpty.option(leftabs(pov, prefs)),
underchat = views.html.game.watchers().some,
moreJs = moreJs,
-openGraph = povOpenGraph(pov),
+openGraph = povOpenGraph(pov).some,
chessground = false,
playing = true) {
diff --git a/app/views/round/watcher.scala.html b/app/views/round/watcher.scala.html
index 3c13171aca..5748e99b67 100644
--- a/app/views/round/watcher.scala.html
+++ b/app/views/round/watcher.scala.html
@@ -21,7 +21,7 @@ side = views.html.game.side(pov, (data\"game"\"initialFen").asOpt[String], tour,
chat = base.chatDom(trans.spectatorRoom.str()).some,
underchat = views.html.game.watchers().some,
moreJs = moreJs,
-openGraph = povOpenGraph(pov),
+openGraph = povOpenGraph(pov).some,
chessground = false) {
@miniBoardContent
@cross.map { c =>
diff --git a/app/views/round/watcherBot.scala.html b/app/views/round/watcherBot.scala.html
index 653a3bb7fc..a106cf7f16 100644
--- a/app/views/round/watcherBot.scala.html
+++ b/app/views/round/watcherBot.scala.html
@@ -18,7 +18,7 @@ side = views.html.game.side(pov, initialFen, none, simul = none, relay = none, u
chat = base.chatDom(trans.spectatorRoom.str()).some,
underchat = views.html.game.watchers().some,
moreJs = moreJs,
-openGraph = povOpenGraph(pov)) {
+openGraph = povOpenGraph(pov).some) {
diff --git a/app/views/user/layout.scala.html b/app/views/user/layout.scala.html
index 39b1a2a569..ff1e677dd3 100644
--- a/app/views/user/layout.scala.html
+++ b/app/views/user/layout.scala.html
@@ -1,4 +1,4 @@
-@(title: String, side: Option[Html] = None, robots: Boolean = true, evenMoreJs: Html = Html(""), evenMoreCss: Html = Html(""), openGraph: Map[Symbol, String] = Map.empty)(body: Html)(implicit ctx: Context)
+@(title: String, side: Option[Html] = None, robots: Boolean = true, evenMoreJs: Html = Html(""), evenMoreCss: Html = Html(""), openGraph: Option[lila.app.ui.OpenGraph] = None)(body: Html)(implicit ctx: Context)
@moreCss = {
@cssTag("user-list.css")
diff --git a/app/views/user/show.scala.html b/app/views/user/show.scala.html
index d49922c4fb..402b87b963 100644
--- a/app/views/user/show.scala.html
+++ b/app/views/user/show.scala.html
@@ -63,13 +63,11 @@ title = title,
side = side.some,
robots = false,
evenMoreJs = evenMoreJs,
-openGraph = Map(
-'type -> "website",
-'image -> staticUrl("images/large_tile.png"),
-'title -> u.titleUsernameWithBestRating,
-'site_name -> "lichess.org",
-'url -> s"$netBaseUrl${routes.User.show(u.username).url}",
-'description -> describeUser(u))) {
+openGraph = lila.app.ui.OpenGraph(
+image = staticUrl("images/large_tile.png").some,
+title = u.titleUsernameWithBestRating,
+url = s"$netBaseUrl${routes.User.show(u.username).url}",
+description = describeUser(u)).some) {
@info.allTrophies.map { trophy =>