fix page settings section and blocks not showing in editor
All checks were successful
deploy / deploy (push) Successful in 1m16s

Two bugs fixed:

1. Page Settings section wasn't appearing for system pages because
   Defaults.for_slug didn't return all required fields (type,
   meta_description, published, etc). Also changed page_renderer
   to use bracket notation for safer field access.

2. Blocks weren't loading when navigating directly to ?edit=page
   because the PageEditorHook's handle_params ran before Shop.Page
   assigned @page. Added pending page mode mechanism: hook sets a
   flag when edit mode is requested but @page is nil, then Shop.Page
   calls maybe_enter_pending_page_mode after @page is assigned.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
jamey 2026-03-29 20:30:36 +01:00
parent 9a506357eb
commit 04ce28ca29
5 changed files with 44 additions and 13 deletions

View File

@ -8,7 +8,19 @@ defmodule Berrypod.Pages.Defaults do
""" """
@doc "Returns the default page definition for the given slug." @doc "Returns the default page definition for the given slug."
def for_slug(slug), do: %{slug: slug, title: title(slug), blocks: blocks(slug)} def for_slug(slug) do
%{
slug: slug,
title: title(slug),
blocks: blocks(slug),
type: "system",
published: true,
meta_description: nil,
show_in_nav: false,
nav_label: nil,
nav_position: nil
}
end
@doc "Returns default definitions for all pages." @doc "Returns default definitions for all pages."
def all do def all do

View File

@ -641,10 +641,8 @@ defmodule BerrypodWeb.ShopComponents.SiteEditor do
class="site-editor-nav-item" class="site-editor-nav-item"
data-item-id={item.id} data-item-id={item.id}
> >
<% <% # Determine if this item links to a known page (by URL match or page_id)
# Determine if this item links to a known page (by URL match or page_id) is_page_link = item.page_id != nil or MapSet.member?(@page_urls, item.url) %>
is_page_link = item.page_id != nil or MapSet.member?(@page_urls, item.url)
%>
<form <form
class="site-editor-nav-item-form" class="site-editor-nav-item-form"
phx-change={@event_prefix <> "update_nav_item"} phx-change={@event_prefix <> "update_nav_item"}

View File

@ -237,6 +237,9 @@ defmodule BerrypodWeb.Shop.Page do
# Must run after handle_params since Content pages set @page there. # Must run after handle_params since Content pages set @page there.
socket = maybe_sync_editing_blocks(socket) socket = maybe_sync_editing_blocks(socket)
# If edit mode was requested via URL but @page wasn't available yet, enter it now
socket = BerrypodWeb.PageEditorHook.maybe_enter_pending_page_mode(socket)
{:noreply, socket} {:noreply, socket}
end end

View File

@ -81,6 +81,21 @@ defmodule BerrypodWeb.PageEditorHook do
{:cont, socket} {:cont, socket}
end end
@doc """
Called by Shop.Page after @page is assigned. If edit mode was requested via
URL but couldn't be entered because @page wasn't available yet, enters it now.
"""
def maybe_enter_pending_page_mode(socket) do
if socket.assigns[:editor_pending_page_mode] && socket.assigns[:page] &&
!socket.assigns.editing do
socket
|> assign(:editor_pending_page_mode, false)
|> enter_edit_mode()
else
socket
end
end
# ── handle_params: track current path and restore editor state ──── # ── handle_params: track current path and restore editor state ────
defp handle_editor_params(params, uri, socket) do defp handle_editor_params(params, uri, socket) do
@ -164,7 +179,8 @@ defmodule BerrypodWeb.PageEditorHook do
if socket.assigns[:page] do if socket.assigns[:page] do
enter_edit_mode(socket) enter_edit_mode(socket)
else else
socket # Page not yet loaded - mark that we need to enter edit mode when it is
assign(socket, :editor_pending_page_mode, true)
end end
end end
end end

View File

@ -374,18 +374,20 @@ defmodule BerrypodWeb.PageRenderer do
form = assigns.form || %{} form = assigns.form || %{}
is_custom = assigns.page[:type] == "custom" is_custom = assigns.page[:type] == "custom"
page = assigns.page
assigns = assigns =
assigns assigns
|> assign(:is_custom, is_custom) |> assign(:is_custom, is_custom)
|> assign(:form_title, form["title"] || assigns.page.title || "") |> assign(:form_title, form["title"] || page[:title] || "")
|> assign(:form_slug, form["slug"] || assigns.page.slug || "") |> assign(:form_slug, form["slug"] || page[:slug] || "")
|> assign(:form_meta, form["meta_description"] || assigns.page.meta_description || "") |> assign(:form_meta, form["meta_description"] || page[:meta_description] || "")
|> assign(:form_published, form_checked?(form, "published", assigns.page.published)) |> assign(:form_published, form_checked?(form, "published", page[:published]))
|> assign(:form_show_in_nav, form_checked?(form, "show_in_nav", assigns.page.show_in_nav)) |> assign(:form_show_in_nav, form_checked?(form, "show_in_nav", page[:show_in_nav]))
|> assign(:form_nav_label, form["nav_label"] || assigns.page.nav_label || "") |> assign(:form_nav_label, form["nav_label"] || page[:nav_label] || "")
|> assign( |> assign(
:form_nav_position, :form_nav_position,
form["nav_position"] || to_string(assigns.page.nav_position || 0) form["nav_position"] || to_string(page[:nav_position] || 0)
) )
~H""" ~H"""