From 9eb56fe586c33b9d90d1b29ba8989adab804bba3 Mon Sep 17 00:00:00 2001 From: Robert Prehn Date: Fri, 17 Sep 2021 12:02:58 -0500 Subject: [PATCH 1/4] fix: Make kaffy work with newer Ecto --- apps/admin/kaffy/lib/kaffy/resource_query.ex | 1 + 1 file changed, 1 insertion(+) 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() From 4cb5e6464298bb49d918db8a7af731d108ddb0b2 Mon Sep 17 00:00:00 2001 From: Robert Prehn Date: Fri, 17 Sep 2021 12:54:02 -0500 Subject: [PATCH 2/4] fix: Migrate to latest Oban schema --- apps/core/mix.exs | 1 + .../migrations/20210917152529_update_oban_table.exs | 13 +++++++++++++ mix.lock | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 apps/core/priv/repo/migrations/20210917152529_update_oban_table.exs diff --git a/apps/core/mix.exs b/apps/core/mix.exs index 9ad3856a..30d09696 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 diff --git a/mix.lock b/mix.lock index e5a9de6d..5fa5a333 100644 --- a/mix.lock +++ b/mix.lock @@ -57,7 +57,7 @@ "nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"}, "oban": {:hex, :oban, "2.8.0", "e44b19a30e30bb983099f55d59749316ff0eaf5dfef4214e1190738176653e50", [:mix], [{:ecto_sql, ">= 3.4.3", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2954a2ac418f7cc4217c0772a3dd3a70e2966240583b97f4126a489e1300a573"}, "parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"}, - "phoenix": {:hex, :phoenix, "1.5.12", "75fddb14c720388eea93d33886166a690416a7ff8633fbd93f364355b6fe1166", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "8f0ae6734fcc18bbaa646c161e2febc46fb899eae43f82679b92530983324113"}, + "phoenix": {:hex, :phoenix, "1.5.9", "a6368d36cfd59d917b37c44386e01315bc89f7609a10a45a22f47c007edf2597", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7e4bce20a67c012f1fbb0af90e5da49fa7bf0d34e3a067795703b74aef75427d"}, "phoenix_ecto": {:hex, :phoenix_ecto, "4.3.0", "2c69a452c2e0ee8c93345ae1cdc1696ef4877ff9cbb15c305def41960c3c4ebf", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "0ac491924217550c8f42c81c1f390b5d81517d12ceaf9abf3e701156760a848e"}, "phoenix_html": {:hex, :phoenix_html, "3.0.0", "b50048ea6be552af0f19218f703b1cc6c182f569fb28f8a849056e452a2bfed5", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "373d054f29812c5ba98096762cacfc320c5e484bfb40501511e39f662c2cd1c7"}, "phoenix_html_sanitizer": {:hex, :phoenix_html_sanitizer, "1.1.0", "ea9e1162217621208ba6b2951a24abe2c06b39347f65c22c31312f9f5ac0fa75", [:mix], [{:html_sanitize_ex, "~> 1.1", [hex: :html_sanitize_ex, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}], "hexpm", "089f28f0592d58f7cf1f032b89c13e873dc73c77a2ccf3386aee976c6ff077c9"}, From 079a24bcae09a4fdff077d9a48b9e163c48a847f Mon Sep 17 00:00:00 2001 From: Robert Prehn Date: Fri, 17 Sep 2021 13:20:44 -0500 Subject: [PATCH 3/4] feat: Add social media and SEO tags to head --- apps/app/assets/package-lock.json | 2 +- .../app_web/templates/layout/_social.html.eex | 28 +++++++++++ .../app_web/templates/layout/root.html.leex | 2 +- apps/app/lib/app_web/views/layout_view.ex | 46 ++++++++++++++++--- .../test/app_web/views/layout_view_test.exs | 38 +++++++++++++++ 5 files changed, 107 insertions(+), 9 deletions(-) create mode 100644 apps/app/lib/app_web/templates/layout/_social.html.eex 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 From 11e21cd589510908c5dea15640a13e8f6e0f9c85 Mon Sep 17 00:00:00 2001 From: Robert Prehn Date: Fri, 17 Sep 2021 13:26:20 -0500 Subject: [PATCH 4/4] fix: Restore Phoenix to 1.15.12 --- mix.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.lock b/mix.lock index 5fa5a333..e5a9de6d 100644 --- a/mix.lock +++ b/mix.lock @@ -57,7 +57,7 @@ "nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"}, "oban": {:hex, :oban, "2.8.0", "e44b19a30e30bb983099f55d59749316ff0eaf5dfef4214e1190738176653e50", [:mix], [{:ecto_sql, ">= 3.4.3", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2954a2ac418f7cc4217c0772a3dd3a70e2966240583b97f4126a489e1300a573"}, "parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"}, - "phoenix": {:hex, :phoenix, "1.5.9", "a6368d36cfd59d917b37c44386e01315bc89f7609a10a45a22f47c007edf2597", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7e4bce20a67c012f1fbb0af90e5da49fa7bf0d34e3a067795703b74aef75427d"}, + "phoenix": {:hex, :phoenix, "1.5.12", "75fddb14c720388eea93d33886166a690416a7ff8633fbd93f364355b6fe1166", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "8f0ae6734fcc18bbaa646c161e2febc46fb899eae43f82679b92530983324113"}, "phoenix_ecto": {:hex, :phoenix_ecto, "4.3.0", "2c69a452c2e0ee8c93345ae1cdc1696ef4877ff9cbb15c305def41960c3c4ebf", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "0ac491924217550c8f42c81c1f390b5d81517d12ceaf9abf3e701156760a848e"}, "phoenix_html": {:hex, :phoenix_html, "3.0.0", "b50048ea6be552af0f19218f703b1cc6c182f569fb28f8a849056e452a2bfed5", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "373d054f29812c5ba98096762cacfc320c5e484bfb40501511e39f662c2cd1c7"}, "phoenix_html_sanitizer": {:hex, :phoenix_html_sanitizer, "1.1.0", "ea9e1162217621208ba6b2951a24abe2c06b39347f65c22c31312f9f5ac0fa75", [:mix], [{:html_sanitize_ex, "~> 1.1", [hex: :html_sanitize_ex, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}], "hexpm", "089f28f0592d58f7cf1f032b89c13e873dc73c77a2ccf3386aee976c6ff077c9"},