2026-03-09 14:47:50 +00:00
|
|
|
defmodule BerrypodWeb.Shop.Pages.Home do
|
|
|
|
|
@moduledoc """
|
|
|
|
|
Home page handler for the unified Shop.Page LiveView.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
import Phoenix.Component, only: [assign: 2, assign: 3]
|
2026-01-17 16:19:35 +00:00
|
|
|
|
2026-04-17 16:47:43 +01:00
|
|
|
alias Berrypod.{Pages, Settings}
|
|
|
|
|
alias BerrypodWeb.Helpers.SeoHelpers
|
2026-01-17 16:19:35 +00:00
|
|
|
|
2026-03-09 14:47:50 +00:00
|
|
|
def init(socket, _params, _uri) do
|
2026-02-26 18:29:20 +00:00
|
|
|
page = Pages.get_page("home")
|
|
|
|
|
extra = Pages.load_block_data(page.blocks, socket.assigns)
|
2026-01-17 16:19:35 +00:00
|
|
|
|
2026-02-23 22:37:34 +00:00
|
|
|
base = BerrypodWeb.Endpoint.url()
|
2026-03-03 14:52:31 +00:00
|
|
|
site_name = socket.assigns.site_name
|
2026-02-23 22:37:34 +00:00
|
|
|
|
2026-04-17 16:47:43 +01:00
|
|
|
org_ld = build_organization_json_ld(socket.assigns, base, site_name)
|
|
|
|
|
json_ld = combine_json_ld([org_ld, SeoHelpers.faq_json_ld(page.blocks)])
|
2026-02-23 22:37:34 +00:00
|
|
|
|
2026-01-17 16:19:35 +00:00
|
|
|
socket =
|
|
|
|
|
socket
|
|
|
|
|
|> assign(:page_title, "Home")
|
2026-02-23 22:37:34 +00:00
|
|
|
|> assign(:og_url, base <> "/")
|
2026-04-17 16:47:43 +01:00
|
|
|
|> assign(:json_ld, json_ld)
|
2026-02-26 18:29:20 +00:00
|
|
|
|> assign(:page, page)
|
2026-04-17 16:47:43 +01:00
|
|
|
|> maybe_assign_meta_robots(page)
|
|
|
|
|
|> SeoHelpers.assign_og_image(page, base)
|
2026-02-26 18:29:20 +00:00
|
|
|
|> assign(extra)
|
2026-01-17 16:19:35 +00:00
|
|
|
|
2026-03-09 14:47:50 +00:00
|
|
|
{:noreply, socket}
|
2026-01-17 16:19:35 +00:00
|
|
|
end
|
2026-01-17 22:17:59 +00:00
|
|
|
|
2026-04-17 16:47:43 +01:00
|
|
|
# Combine multiple JSON-LD scripts into a single output (newline-separated)
|
|
|
|
|
defp combine_json_ld(ld_list) do
|
|
|
|
|
ld_list
|
|
|
|
|
|> Enum.reject(&is_nil/1)
|
|
|
|
|
|> case do
|
|
|
|
|
[] -> nil
|
|
|
|
|
[single] -> single
|
|
|
|
|
many -> Enum.join(many, "\n</script>\n<script type=\"application/ld+json\">\n")
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
defp build_organization_json_ld(assigns, base_url, site_name) do
|
|
|
|
|
business_info = Settings.get_business_info()
|
|
|
|
|
|
|
|
|
|
org_type =
|
|
|
|
|
if business_info["business_type"] == "LocalBusiness",
|
|
|
|
|
do: "LocalBusiness",
|
|
|
|
|
else: "Organization"
|
|
|
|
|
|
|
|
|
|
org = %{
|
|
|
|
|
"@context" => "https://schema.org",
|
|
|
|
|
"@type" => org_type,
|
|
|
|
|
"name" => site_name,
|
|
|
|
|
"url" => base_url <> "/"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
org
|
|
|
|
|
|> maybe_add_logo(assigns[:logo_image], base_url)
|
|
|
|
|
|> maybe_add_contact_point(business_info)
|
|
|
|
|
|> maybe_add_address(business_info)
|
|
|
|
|
|> maybe_add_same_as(assigns[:social_links])
|
|
|
|
|
|> Jason.encode!(escape: :html_safe)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
defp maybe_add_logo(org, nil, _base_url), do: org
|
|
|
|
|
|
|
|
|
|
defp maybe_add_logo(org, logo_image, base_url) do
|
|
|
|
|
logo_url = base_url <> "/image_cache/#{logo_image.id}.webp"
|
|
|
|
|
Map.put(org, "logo", logo_url)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
defp maybe_add_contact_point(org, business_info) do
|
|
|
|
|
phone = business_info["business_phone"]
|
|
|
|
|
email = business_info["business_email"]
|
|
|
|
|
|
|
|
|
|
cond do
|
|
|
|
|
present?(phone) and present?(email) ->
|
|
|
|
|
Map.put(org, "contactPoint", [
|
|
|
|
|
%{"@type" => "ContactPoint", "telephone" => phone, "contactType" => "customer service"},
|
|
|
|
|
%{"@type" => "ContactPoint", "email" => email, "contactType" => "customer service"}
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
present?(phone) ->
|
|
|
|
|
Map.put(org, "contactPoint", %{
|
|
|
|
|
"@type" => "ContactPoint",
|
|
|
|
|
"telephone" => phone,
|
|
|
|
|
"contactType" => "customer service"
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
present?(email) ->
|
|
|
|
|
Map.put(org, "contactPoint", %{
|
|
|
|
|
"@type" => "ContactPoint",
|
|
|
|
|
"email" => email,
|
|
|
|
|
"contactType" => "customer service"
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
true ->
|
|
|
|
|
org
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
defp maybe_add_address(org, business_info) do
|
|
|
|
|
street = business_info["address_street"]
|
|
|
|
|
city = business_info["address_city"]
|
|
|
|
|
country = business_info["address_country"]
|
|
|
|
|
|
|
|
|
|
if present?(street) or present?(city) or present?(country) do
|
|
|
|
|
address = %{"@type" => "PostalAddress"}
|
|
|
|
|
|
|
|
|
|
address =
|
|
|
|
|
address
|
|
|
|
|
|> maybe_put("streetAddress", street)
|
|
|
|
|
|> maybe_put("addressLocality", city)
|
|
|
|
|
|> maybe_put("addressRegion", business_info["address_region"])
|
|
|
|
|
|> maybe_put("postalCode", business_info["address_postal_code"])
|
|
|
|
|
|> maybe_put("addressCountry", country)
|
|
|
|
|
|
|
|
|
|
Map.put(org, "address", address)
|
|
|
|
|
else
|
|
|
|
|
org
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
defp maybe_add_same_as(org, nil), do: org
|
|
|
|
|
defp maybe_add_same_as(org, []), do: org
|
|
|
|
|
|
|
|
|
|
defp maybe_add_same_as(org, social_links) do
|
|
|
|
|
urls =
|
|
|
|
|
social_links
|
|
|
|
|
|> Enum.map(& &1.url)
|
|
|
|
|
|> Enum.filter(&present?/1)
|
|
|
|
|
|
|
|
|
|
if urls != [], do: Map.put(org, "sameAs", urls), else: org
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
defp maybe_put(map, _key, nil), do: map
|
|
|
|
|
defp maybe_put(map, _key, ""), do: map
|
|
|
|
|
defp maybe_put(map, key, value), do: Map.put(map, key, value)
|
|
|
|
|
|
|
|
|
|
defp present?(nil), do: false
|
|
|
|
|
defp present?(""), do: false
|
|
|
|
|
defp present?(_), do: true
|
|
|
|
|
|
|
|
|
|
defp maybe_assign_meta_robots(socket, page) do
|
|
|
|
|
meta_robots = page && page[:meta_robots]
|
|
|
|
|
|
|
|
|
|
if meta_robots && meta_robots != "index, follow" do
|
|
|
|
|
assign(socket, :meta_robots, meta_robots)
|
|
|
|
|
else
|
|
|
|
|
socket
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2026-03-09 14:47:50 +00:00
|
|
|
def handle_params(_params, _uri, socket) do
|
|
|
|
|
{:noreply, socket}
|
2026-01-17 22:17:59 +00:00
|
|
|
end
|
2026-03-09 14:47:50 +00:00
|
|
|
|
|
|
|
|
def handle_event(_event, _params, _socket), do: :cont
|
2026-01-17 16:19:35 +00:00
|
|
|
end
|