diff --git a/apps/admin/kaffy/lib/kaffy/resource_query.ex b/apps/admin/kaffy/lib/kaffy/resource_query.ex
index 35757b11..54482be7 100644
--- a/apps/admin/kaffy/lib/kaffy/resource_query.ex
+++ b/apps/admin/kaffy/lib/kaffy/resource_query.ex
@@ -2,6 +2,7 @@ defmodule Kaffy.ResourceQuery do
@moduledoc false
import Ecto.Query
+ import Ecto.Query.API, only: [field: 2]
def list_resource(conn, resource, params \\ %{}) do
per_page = Map.get(params, "limit", "100") |> String.to_integer()
diff --git a/apps/app/assets/package-lock.json b/apps/app/assets/package-lock.json
index 6c6beedd..7321b8a7 100644
--- a/apps/app/assets/package-lock.json
+++ b/apps/app/assets/package-lock.json
@@ -11238,7 +11238,7 @@
}
},
"../../../deps/phoenix_live_view": {
- "version": "0.16.0",
+ "version": "0.16.3",
"license": "MIT"
},
"node_modules/stylehacks": {
diff --git a/apps/app/lib/app_web/templates/layout/_social.html.eex b/apps/app/lib/app_web/templates/layout/_social.html.eex
new file mode 100644
index 00000000..6f3cbb5c
--- /dev/null
+++ b/apps/app/lib/app_web/templates/layout/_social.html.eex
@@ -0,0 +1,28 @@
+<%= live_title_tag title(@view_module, @view_template, assigns) %>
+
+<%= tag :meta, itemprop: "name", content: title(@view_module, @view_template, assigns) %>
+<%= tag :meta, itemprop: "description", content: excerpt(@view_module, @view_template, assigns) %>
+<%= tag :meta, name: "description", content: excerpt(@view_module, @view_template, assigns) %>
+
+
+<%= tag :meta, name: "twitter:card", content: "summary_large_image" %>
+<%= tag :meta, name: "twitter:title", content: title(@view_module, @view_template, assigns) %>
+<%= tag :meta, name: "twitter:description", content: excerpt(@view_module, @view_template, assigns) %>
+
+
+
+
+<%= tag :meta, property: "og:title", content: title(@view_module, @view_template, assigns) %>
+<%= tag :meta, property: "og:type", content: "article" %>
+<%= tag :meta, property: "og:description", content: excerpt(@view_module, @view_template, assigns) %>
+<%= tag :meta, property: "og:site_name", content: Legendary.I18n.t!("en", "site.title") %>
+<%= modified_tag(@view_module, @view_template, assigns) %>
+<%= published_tag(@view_module, @view_template, assigns) %>
+
+
+
+
+
+
+
+
diff --git a/apps/app/lib/app_web/templates/layout/root.html.leex b/apps/app/lib/app_web/templates/layout/root.html.leex
index d5b583bf..bbcd96a3 100644
--- a/apps/app/lib/app_web/templates/layout/root.html.leex
+++ b/apps/app/lib/app_web/templates/layout/root.html.leex
@@ -5,7 +5,7 @@
<%= csrf_meta_tag() %>
- <%= live_title_tag title(@view_module, @view_template, assigns) %>
+ <%= render "_social.html", assigns %>
"/>
diff --git a/apps/app/lib/app_web/views/layout_view.ex b/apps/app/lib/app_web/views/layout_view.ex
index 27d26082..26a6668a 100644
--- a/apps/app/lib/app_web/views/layout_view.ex
+++ b/apps/app/lib/app_web/views/layout_view.ex
@@ -1,15 +1,47 @@
defmodule AppWeb.LayoutView do
use AppWeb, :view
+ def title(view, template, %{post: post}), do: "#{post.title} | #{title(view, template, nil)}"
+
def title(_, _, _) do
Legendary.I18n.t!("en", "site.title")
- end
+ end
- def excerpt(_, _, _) do
- Legendary.I18n.t!("en", "site.excerpt")
- end
+ def excerpt(_, _, %{post: post}) do
+ post.excerpt
+ end
- def feed_tag(_, _, _, _) do
- nil
- end
+ def excerpt(_, _, _) do
+ Legendary.I18n.t!("en", "site.excerpt")
+ end
+
+ def feed_tag(_, _, _, _) do
+ nil
+ end
+
+ def modified_tag(_, _, %{post: post}) do
+ content =
+ post.modified_gmt
+ |> DateTime.from_naive!("Etc/UTC")
+ |> DateTime.to_iso8601()
+
+ tag :meta, property: "article:modified_time", content: content
+ end
+
+ def modified_tag(_, _, _) do
+ nil
+ end
+
+ def published_tag(_, _, %{post: post}) do
+ content =
+ post.date_gmt
+ |> DateTime.from_naive!("Etc/UTC")
+ |> DateTime.to_iso8601()
+
+ tag :meta, property: "article:published_time", content: content
+ end
+
+ def published_tag(_, _, _) do
+ nil
+ end
end
diff --git a/apps/app/test/app_web/views/layout_view_test.exs b/apps/app/test/app_web/views/layout_view_test.exs
index 65687848..ca03e06b 100644
--- a/apps/app/test/app_web/views/layout_view_test.exs
+++ b/apps/app/test/app_web/views/layout_view_test.exs
@@ -2,6 +2,16 @@ defmodule App.LayoutViewTest do
use AppWeb.ConnCase, async: true
import AppWeb.LayoutView
+ import Phoenix.HTML, only: [safe_to_string: 1]
+
+ alias Legendary.Content.Post
+
+ @post %Post{
+ title: "Test Post",
+ excerpt: "This is a test post.",
+ modified_gmt: ~N[2021-09-17T00:00:00],
+ date_gmt: ~N[2021-09-15T00:00:00]
+ }
describe "title/3" do
def default_title do
@@ -11,6 +21,10 @@ defmodule App.LayoutViewTest do
test "for nil" do
assert title(nil, nil, nil) =~ default_title()
end
+
+ test "for post" do
+ assert title(nil, nil, %{post: @post}) =~ "Test Post | #{default_title()}"
+ end
end
describe "excerpt/3" do
@@ -21,6 +35,10 @@ defmodule App.LayoutViewTest do
test "for nil" do
assert excerpt(nil, nil, nil) =~ default_excerpt()
end
+
+ test "for post" do
+ assert excerpt(nil, nil, %{post: @post}) =~ "This is a test post."
+ end
end
describe "feed_tag/4" do
@@ -28,4 +46,24 @@ defmodule App.LayoutViewTest do
assert feed_tag(nil, nil, nil, nil) == nil
end
end
+
+ describe "modified_tag/3" do
+ test "for a post" do
+ assert safe_to_string(modified_tag(nil, nil, %{post: @post})) =~ "2021-09-17"
+ end
+
+ test "without a post" do
+ assert modified_tag(nil, nil, nil) == nil
+ end
+ end
+
+ describe "published_tag/3" do
+ test "for a post" do
+ assert safe_to_string(published_tag(nil, nil, %{post: @post})) =~ "2021-09-15"
+ end
+
+ test "without a post" do
+ assert published_tag(nil, nil, nil) == nil
+ end
+ end
end
diff --git a/apps/core/mix.exs b/apps/core/mix.exs
index 6ccb25c7..27f2b673 100644
--- a/apps/core/mix.exs
+++ b/apps/core/mix.exs
@@ -150,6 +150,7 @@ defmodule Legendary.Core.MixProject do
{:ecto_sql, "~> 3.6"},
{:ex_prompt, "~> 0.2.0"},
{:linguist, "~> 0.3.2"},
+ {:oban, "~> 2.1"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "~> 3.0"},
{:phoenix_live_reload, "~> 1.3", only: :dev},
diff --git a/apps/core/priv/repo/migrations/20210917152529_update_oban_table.exs b/apps/core/priv/repo/migrations/20210917152529_update_oban_table.exs
new file mode 100644
index 00000000..04e8edbb
--- /dev/null
+++ b/apps/core/priv/repo/migrations/20210917152529_update_oban_table.exs
@@ -0,0 +1,13 @@
+defmodule Legendary.Core.Repo.Migrations.UpdateObanTable do
+ use Ecto.Migration
+
+ def up do
+ Oban.Migrations.up()
+ end
+
+ # We specify `version: 1` in `down`, ensuring that we'll roll all the way back down if
+ # necessary, regardless of which version we've migrated `up` to.
+ def down do
+ Oban.Migrations.down(version: 1)
+ end
+end