Skip to content

Commit a1f003e

Browse files
committed
rework @beacon assign
- remove the need to pass around the source - simplify building it
1 parent 8a6ccde commit a1f003e

File tree

8 files changed

+84
-90
lines changed

8 files changed

+84
-90
lines changed

lib/beacon/router.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ defmodule Beacon.Router do
250250
end)
251251
end
252252

253+
def path_params(_page_path, _path_info), do: %{}
254+
253255
@doc false
254256
# Tells if a `beacon_site` is reachable in the current environment.
255257
#

lib/beacon/template.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ defmodule Beacon.Template do
2727

2828
page ->
2929
page_module = Beacon.Loader.fetch_page_module(page.site, page.id)
30-
live_data = Beacon.Web.DataSource.live_data(site, path_info)
31-
beacon_assigns = BeaconAssigns.new(site, page, live_data, path_info, query_params, :beacon)
30+
live_data = Beacon.Web.DataSource.live_data(site, path_info, query_params)
31+
beacon_assigns = BeaconAssigns.new(page, path_info: path_info, query_params: query_params)
3232
assigns = Map.put(live_data, :beacon, beacon_assigns)
3333
env = Beacon.Web.PageLive.make_env(site)
3434

lib/beacon/web/beacon_assigns.ex

Lines changed: 12 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ defmodule Beacon.Web.BeaconAssigns do
3333
}
3434

3535
defstruct site: nil,
36-
path_params: %{},
37-
query_params: %{},
36+
path_params: nil,
37+
query_params: nil,
3838
page: %{path: nil, title: nil},
3939
private: %{
4040
page_module: nil,
@@ -53,31 +53,18 @@ defmodule Beacon.Web.BeaconAssigns do
5353
end
5454

5555
@doc false
56-
def new(site, %Beacon.Content.Page{} = page, variant_roll) do
57-
components_module = Beacon.Loader.Components.module_name(site)
58-
page_module = Beacon.Loader.Page.module_name(site, page.id)
56+
def new(%Beacon.Content.Page{} = page, metadata \\ []) do
57+
path_info = Keyword.get(metadata, :path_info, [])
58+
query_params = Keyword.get(metadata, :query_params, %{})
59+
variant_roll = Keyword.get(metadata, :variant_roll, nil)
5960

60-
%__MODULE__{
61-
site: site,
62-
private: %{
63-
components_module: components_module,
64-
page_module: page_module,
65-
variant_roll: variant_roll
66-
}
67-
}
68-
end
69-
70-
@doc false
71-
def new(site, %Beacon.Content.Page{} = page, live_data, path_info, query_params, source, variant_roll \\ nil)
72-
when is_atom(site) and is_map(live_data) and is_list(path_info) and is_map(query_params) and source in [:beacon, :admin] do
73-
%{site: ^site} = page
74-
page_module = Beacon.Loader.Page.module_name(site, page.id)
75-
live_data = Beacon.Web.DataSource.live_data(site, path_info, Map.drop(query_params, ["path"]))
61+
page_module = Beacon.Loader.Page.module_name(page.site, page.id)
62+
live_data = Beacon.Web.DataSource.live_data(page.site, path_info, Map.drop(query_params, ["path"]))
7663
path_params = Beacon.Router.path_params(page.path, path_info)
77-
page_title = Beacon.Web.DataSource.page_title(site, page, live_data, source)
78-
components_module = Beacon.Loader.Components.module_name(site)
79-
info_handlers_module = Beacon.Loader.InfoHandlers.module_name(site)
80-
event_handlers_module = Beacon.Loader.EventHandlers.module_name(site)
64+
page_title = Beacon.Web.DataSource.page_title(page, live_data)
65+
components_module = Beacon.Loader.Components.module_name(page.site)
66+
info_handlers_module = Beacon.Loader.InfoHandlers.module_name(page.site)
67+
event_handlers_module = Beacon.Loader.EventHandlers.module_name(page.site)
8168

8269
%__MODULE__{
8370
site: page.site,
@@ -95,23 +82,4 @@ defmodule Beacon.Web.BeaconAssigns do
9582
}
9683
}
9784
end
98-
99-
@doc false
100-
def update(_socket_or_assigns, _key, _value)
101-
102-
def update(%{assigns: %{beacon: _beacon}} = socket, key, value) do
103-
do_update_socket_or_assigns(socket, key, value)
104-
end
105-
106-
def update(%{beacon: _beacon} = assigns, key, value) do
107-
do_update_socket_or_assigns(assigns, key, value)
108-
end
109-
110-
def update(_socket_or_assigns, _key, _value), do: raise("expected :beacon assign in socket but none found")
111-
112-
defp do_update_socket_or_assigns(socket_or_assigns, key, value) do
113-
Phoenix.Component.update(socket_or_assigns, :beacon, fn beacon ->
114-
Map.put(beacon, key, value)
115-
end)
116-
end
11785
end

lib/beacon/web/controllers/api/page_json.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ defmodule Beacon.Web.API.PageJSON do
2323
defp data(%Page{} = page) do
2424
path_info = for segment <- String.split(page.path, "/"), segment != "", do: segment
2525
live_data = Beacon.Web.DataSource.live_data(page.site, path_info, %{})
26-
beacon_assigns = BeaconAssigns.new(page.site, page, live_data, path_info, %{}, :admin)
26+
beacon_assigns = BeaconAssigns.new(page, path_info: path_info)
2727

2828
assigns =
2929
live_data

lib/beacon/web/data_source.ex

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ defmodule Beacon.Web.DataSource do
33

44
require Logger
55

6-
def live_data(site, path_info, params \\ %{}) when is_atom(site) and is_list(path_info) and is_map(params) do
7-
Beacon.apply_mfa(site, Beacon.Loader.fetch_live_data_module(site), :live_data, [path_info, params])
6+
def live_data(site, path_info, query_params) when is_atom(site) and is_list(path_info) and is_map(query_params) do
7+
Beacon.apply_mfa(site, Beacon.Loader.fetch_live_data_module(site), :live_data, [path_info, query_params])
88
end
99

10-
def page_title(site, page, live_data, source) do
11-
%{path: path, title: title} = page_assigns = page_assigns(site, page, source)
10+
def live_data(_site, _path_info, _query_params), do: %{}
11+
12+
def page_title(%Beacon.Content.Page{} = page, live_data) do
13+
%{path: path, title: title} = page_assigns = page_assigns(page)
1214

1315
with {:ok, page_title} <- Beacon.Content.render_snippet(title, %{page: page_assigns, live_data: live_data}) do
1416
page_title
@@ -19,7 +21,7 @@ defmodule Beacon.Web.DataSource do
1921
2022
will return the original unmodified page title
2123
22-
site: #{site}
24+
site: #{page.site}
2325
title: #{title}
2426
page path: #{path}
2527
@@ -36,13 +38,14 @@ defmodule Beacon.Web.DataSource do
3638
# TODO: revisit this logic to evaluate meta_tags for unpublished pages
3739
def meta_tags(assigns) do
3840
%{beacon: %{site: site, private: %{page_module: page_module, live_data_keys: live_data_keys}}} = assigns
39-
%{site: ^site, id: page_id} = Beacon.apply_mfa(site, page_module, :page_assigns, [[:site, :id]])
41+
%{site: ^site} = page_assigns = Beacon.apply_mfa(site, page_module, :page_assigns, [])
42+
4043
live_data = Map.take(assigns, live_data_keys)
4144

4245
assigns
4346
|> Beacon.Web.Layouts.meta_tags()
4447
|> List.wrap()
45-
|> Enum.map(&interpolate_meta_tag(&1, %{page: page_assigns(site, page_id, :beacon), live_data: live_data}))
48+
|> Enum.map(&interpolate_meta_tag(&1, %{page: page_assigns, live_data: live_data}))
4649
end
4750

4851
defp interpolate_meta_tag(meta_tag, values) when is_map(meta_tag) do
@@ -57,16 +60,21 @@ defmodule Beacon.Web.DataSource do
5760
end
5861
end
5962

60-
# only published pages will have the title evaluated for beacon
61-
defp page_assigns(site, page, :beacon) do
62-
Beacon.apply_mfa(site, Beacon.Loader.fetch_page_module(site, page.id), :page_assigns, [])
63+
# return the page assigns from unpublished page assigns,
64+
# either saved in the database or page in-memory (for new pages)
65+
# this fallback is here mostly to support beacon_live_admin visual editor,
66+
# which makes use of the `@beacon` assign when creating or editing pages
67+
defp page_assigns(%Beacon.Content.Page{id: nil} = page) do
68+
unpublished_page_assigns(page)
6369
end
6470

65-
# beacon_live_admin needs the title for unpublished pages also
66-
defp page_assigns(site, page, :admin) do
67-
# new pages are not yet in the database
68-
page = if page.id, do: Beacon.Content.get_page(site, page.id), else: page
71+
defp page_assigns(%Beacon.Content.Page{} = page) do
72+
Beacon.apply_mfa(page.site, Beacon.Loader.fetch_page_module(page.site, page.id), :page_assigns, [])
73+
rescue
74+
_ -> unpublished_page_assigns(page)
75+
end
6976

77+
defp unpublished_page_assigns(page) do
7078
%{
7179
id: page.id,
7280
site: page.site,

lib/beacon/web/live/page_live.ex

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ defmodule Beacon.Web.PageLive do
3939
end
4040

4141
page = RouterServer.lookup_page!(site, path)
42-
socket = Component.assign(socket, beacon: BeaconAssigns.new(site, page, variant_roll))
42+
socket = Component.assign(socket, beacon: BeaconAssigns.new(page, variant_roll: variant_roll))
4343

4444
{:ok, socket, layout: {Beacon.Web.Layouts, :dynamic}}
4545
end
@@ -130,16 +130,14 @@ defmodule Beacon.Web.PageLive do
130130
site ->
131131
%{"path" => path_info} = params
132132

133-
if socket.assigns.beacon.site != site do
134-
if Beacon.Config.fetch!(site).mode == :live do
135-
Beacon.PubSub.unsubscribe_to_page(socket.assigns.beacon.site, path_info)
136-
Beacon.PubSub.subscribe_to_page(site, path_info)
137-
end
133+
if socket.assigns.beacon.site != site && Beacon.Config.fetch!(site).mode == :live do
134+
Beacon.PubSub.unsubscribe_to_page(socket.assigns.beacon.site, path_info)
135+
Beacon.PubSub.subscribe_to_page(site, path_info)
138136
end
139137

140138
page = RouterServer.lookup_page!(site, path_info)
141139
live_data = Beacon.Web.DataSource.live_data(site, path_info, Map.drop(params, ["path"]))
142-
beacon_assigns = BeaconAssigns.new(site, page, live_data, path_info, params, :beacon, socket.assigns.beacon.private.variant_roll)
140+
beacon_assigns = BeaconAssigns.new(page, path_info: path_info, query_params: params, variant_roll: socket.assigns.beacon.private.variant_roll)
143141

144142
socket =
145143
socket
@@ -151,7 +149,7 @@ defmodule Beacon.Web.PageLive do
151149
# TODO: remove deprecated @beacon_query_params
152150
|> Component.assign(:beacon_query_params, beacon_assigns.query_params)
153151
|> Component.assign(:beacon, beacon_assigns)
154-
|> Component.assign(:page_title, Beacon.Web.DataSource.page_title(site, page.id, live_data, :beacon))
152+
|> Component.assign(:page_title, beacon_assigns.page.title)
155153

156154
{:noreply, push_event(socket, "beacon:page-updated", %{meta_tags: Beacon.Web.DataSource.meta_tags(socket.assigns)})}
157155
end

test/beacon_web/beacon_assigns_test.exs

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,7 @@ defmodule Beacon.Web.BeaconAssignsTest do
1414
Process.put(:__beacon_site__, site)
1515
Process.flag(:error_handler, Beacon.ErrorHandler)
1616

17-
[
18-
socket: %Phoenix.LiveView.Socket{
19-
assigns: %{__changed__: %{beacon: true}, beacon: %BeaconAssigns{}}
20-
},
21-
site: site
22-
]
17+
[site: site]
2318
end
2419

2520
test "build with site", %{site: site} do
@@ -29,10 +24,10 @@ defmodule Beacon.Web.BeaconAssignsTest do
2924
} = BeaconAssigns.new(site)
3025
end
3126

32-
test "build with published page resolves page title", %{site: site} do
27+
test "build with published page resolves page title" do
3328
page = beacon_published_page_fixture(path: "/blog", title: "blog index")
3429

35-
assigns = BeaconAssigns.new(site, page, %{}, ["blog"], %{}, :beacon)
30+
assigns = BeaconAssigns.new(page, path_info: ["blog"])
3631

3732
assert %BeaconAssigns{
3833
site: @site,
@@ -43,10 +38,38 @@ defmodule Beacon.Web.BeaconAssignsTest do
4338
} = assigns
4439
end
4540

46-
test "build with path info and query params", %{site: site} do
41+
test "build with unpublished page stored in the database" do
42+
page = beacon_page_fixture(path: "/blog", title: "blog index")
43+
44+
assigns = BeaconAssigns.new(page, path_info: ["blog"])
45+
46+
assert %BeaconAssigns{
47+
site: @site,
48+
page: %{path: "/blog", title: "blog index"},
49+
private: %{
50+
live_path: ["blog"]
51+
}
52+
} = assigns
53+
end
54+
55+
test "build with new in-memory page " do
56+
page = %Beacon.Content.Page{site: @site, path: "/blog", title: "blog index"}
57+
58+
assigns = BeaconAssigns.new(page, path_info: ["blog"])
59+
60+
assert %BeaconAssigns{
61+
site: @site,
62+
page: %{path: "/blog", title: "blog index"},
63+
private: %{
64+
live_path: ["blog"]
65+
}
66+
} = assigns
67+
end
68+
69+
test "build with path info and query params" do
4770
page = beacon_published_page_fixture(path: "/blog")
4871

49-
assigns = BeaconAssigns.new(site, page, %{}, ["blog"], %{source: "search"}, :beacon)
72+
assigns = BeaconAssigns.new(page, path_info: ["blog"], query_params: %{source: "search"})
5073

5174
assert %BeaconAssigns{
5275
site: @site,
@@ -57,24 +80,24 @@ defmodule Beacon.Web.BeaconAssignsTest do
5780
} = assigns
5881
end
5982

60-
test "build with path params", %{site: site} do
83+
test "build with path params" do
6184
page = beacon_published_page_fixture(path: "/blog/:post")
6285

63-
assigns = BeaconAssigns.new(site, page, %{}, ["blog", "hello"], %{}, :beacon)
86+
assigns = BeaconAssigns.new(page, path_info: ["blog", "hello"])
6487

6588
assert %BeaconAssigns{
6689
site: @site,
6790
path_params: %{"post" => "hello"}
6891
} = assigns
6992
end
7093

71-
test "build with live data", %{site: site} do
94+
test "build with live data" do
7295
page = beacon_published_page_fixture(path: "/blog")
7396

7497
live_data = beacon_live_data_fixture(path: "/blog")
7598
beacon_live_data_assign_fixture(live_data: live_data, format: :text, key: "customer_id", value: "123")
7699

77-
assigns = BeaconAssigns.new(site, page, live_data, ["blog"], %{}, :beacon)
100+
assigns = BeaconAssigns.new(page, path_info: ["blog"])
78101

79102
assert %BeaconAssigns{
80103
site: @site,
@@ -83,9 +106,4 @@ defmodule Beacon.Web.BeaconAssignsTest do
83106
}
84107
} = assigns
85108
end
86-
87-
test "update/3", %{socket: socket} do
88-
assert %{assigns: %{beacon: %BeaconAssigns{site: "one"}}} = BeaconAssigns.update(socket, :site, "one")
89-
assert %{assigns: %{beacon: %BeaconAssigns{site: "two"}}} = BeaconAssigns.update(socket, :site, "two")
90-
end
91109
end

test/beacon_web/data_source_test.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ defmodule Beacon.Web.DataSourceTest do
2424
describe "page_title" do
2525
test "renders static content", %{site: site} do
2626
page = beacon_published_page_fixture(site: site, title: "my title")
27-
assert DataSource.page_title(page.site, page.id, %{}, :beacon) == "my title"
27+
assert DataSource.page_title(page, %{}) == "my title"
2828
end
2929

3030
test "renders snippet", %{site: site} do
3131
page = beacon_published_page_fixture(site: site, title: "{{ page.path | upcase }}")
32-
assert DataSource.page_title(page.site, page.id, %{}, :beacon) == "/HOME"
32+
assert DataSource.page_title(page, %{}) == "/HOME"
3333
end
3434
end
3535
end

0 commit comments

Comments
 (0)