Add singleton home page content handling - #25
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d97430f549
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| excerpt: null, | ||
| caption: null, | ||
| contentHtml: null, | ||
| seoDescription: homePage?.seo_description, |
There was a problem hiding this comment.
Use serialized keys for home SEO overrides
The homePage passed from functions/index.jsx is produced by serializeItemForFeed, whose SEO field defs emit camelCase fields such as seoDescription and shareImage. Reading seo_description here means an admin-entered home SEO description is always ignored and the meta/JSON-LD description falls back to hero HTML or channel text; the same mismatch affects the share_image lookup below.
Useful? React with 👍 / 👎.
| if (typeDef.singleton) { | ||
| return validationError("id", "Singleton items cannot be deleted"); |
There was a problem hiding this comment.
Apply singleton protection to bulk deletes
This guard only covers the single-item delete path, but the admin/API bulk delete endpoints still call bulkDelete, which directly sets selected ids to STATUSES.DELETED without checking getType(...).singleton. When a home_page appears in the item list and is selected for a bulk delete, it can be soft-deleted despite this new protection, and / then stops loading the singleton because the home loader only includes published/unlisted statuses.
Useful? React with 👍 / 👎.
| const response = await itemRepo.list({ | ||
| queryKwargs: { | ||
| content_type: "home_page", | ||
| status__in: VISIBLE_HOME_PAGE_STATUSES, |
There was a problem hiding this comment.
Prevent unpublished home status from bypassing singleton
The editor exposes the home_page status field, so setting it to unpublished leaves the singleton row present and still blocks creating another, but this query excludes it. In that state / silently falls back to the legacy channel/recent page instead of the configured home, which is an edit path that disconnects the singleton from / without deleting it.
Useful? React with 👍 / 👎.
| family: "page", | ||
| singleton: true, | ||
| slugEditable: false, | ||
| showInTypePicker: false, |
There was a problem hiding this comment.
Expose a creation path for the singleton home page
On a fresh feed with no home_page, the normal Add New Item flow renders the type picker unless the URL already has ?type=..., and this flag filters home_page out of that picker. I found no other admin link that preselects type=home_page, so authors cannot discover or create the required singleton through the UI; only manually editing the URL works.
Useful? React with 👍 / 👎.
| ) : channel.description ? ( | ||
| <p className="home-hero__description">{channel.description}</p> |
There was a problem hiding this comment.
Honor the channel-description toggle in the hero
When a home_page has no hero rich text, this fallback renders channel.description in the hero even if show_channel_description is false. That makes the channel-description toggle ineffective for the common case where the author wants a custom hero title/image but no channel blurb; gate this fallback on the toggle or remove it for configured home pages.
Useful? React with 👍 / 👎.
| const showRecentExcerpt = homePage.recent_show_excerpt !== false; | ||
| const showRecentBadge = homePage.recent_show_badge !== false; |
There was a problem hiding this comment.
Align recent-card switches with their saved defaults
For a newly created home page these optional booleans are omitted unless the author toggles them, and the BooleanWidget renders omitted values as unchecked. Because the public renderer treats undefined as enabled for excerpt/badge, authors see both switches off in the editor but still get excerpts and badges on / after saving without touching them.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dd09a5da06
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| publicBucketUrl = "", | ||
| canonicalUrl = "", | ||
| } = {}) { | ||
| const siteName = seoSettings.siteName || channel.title || homePage?.title || ""; |
There was a problem hiding this comment.
When an admin fills the seo_title field for the home_page, serializeItemForFeed exposes it as homePage.seoTitle, but siteSeo derives the page title only from seoSettings.siteName, channel.title, or the hero title here. In the normal case where a channel title exists, that explicit home SEO title is ignored for <title>, Open Graph, Twitter, and the WebSite JSON-LD name, unlike the record SEO builders that honor per-item seoTitle.
Useful? React with 👍 / 👎.
| name: "home_page", | ||
| family: "page", | ||
| singleton: true, | ||
| slugEditable: false, | ||
| showInTypePicker: false, |
There was a problem hiding this comment.
Exclude home pages from the legacy RSS feed
Once a home_page is registered and published, it is pulled into /rss/ because functions/rss/index.jsx still fetches every status: PUBLISHED item and FeedPublicRssBuilder legacy mode emits all items when no contentType is supplied. This means the singleton home page, despite having no RSS mapping, appears as an RSS item on sites that create the required home page, polluting podcast/feed clients with a non-feed page.
Useful? React with 👍 / 👎.
| ); | ||
| const keywords = mergeKeywords([], seoSettings.keyTerms); | ||
| const publisher = publisherNode(seoSettings, channel, publicBucketUrl); | ||
| const noindex = homePage?.noindex === true || homePage?.status === "unlisted" || homePage?.status === STATUSES.UNLISTED; |
There was a problem hiding this comment.
Keep noindexed home pages out of the sitemap
When a home_page is marked noindex or made unlisted, this emits robots noindex for /, but functions/sitemap.xml.jsx still unconditionally adds the root URL before it looks at item-level indexability. In that home-page noindex/unlisted scenario, crawlers get the same URL advertised in the sitemap that the page asks them not to index, so the sitemap needs to consult the singleton's noindex/status before emitting ${origin}/.
Useful? React with 👍 / 👎.
…age link - AdminNavApp: sidebar nav now opens by default on desktop (was hardcoded collapsed, requiring an extra click every admin page load); mobile still starts collapsed as a drawer - AdminNavApp: add a "Home Page" sidebar link for the PR #25 home_page singleton, which previously had no entry point in the admin UI. Looks up the existing home_page item via /admin/ajax/items on mount and links straight to its editor, or to the create flow (?type=home_page) if none exists yet - AdminImageUploaderApp: drop the long comma-separated list of accepted file extensions from the upload box (was overflowing the box); the box now just prompts to click/drag, with "Or choose from uploaded" below
No description provided.