components-web-app / components-web-app/api-components-bundle
#[Publishable] on AbstractPage / AbstractPageData — page-level draft/live toggle
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 32
- Forks
- 8
- PR merge metrics
- No merged PRs in 30d
Description
Problem
#[Publishable] (with publishedAt) exists for components: a component can be in draft state even inside a published page. There is no equivalent for pages themselves.
Currently, the only "draft" signal for a page is the absence of a Route. This works before publication, but once a page is live (route exists), there is no way to take it offline without deleting the route — losing URL history and any redirects pointed at it.
Desired behaviour
AbstractPage(base ofPageandAbstractPageData) gets apublishedAt: ?\DateTimeInterfacecolumn via#[Publishable](or a new#[PublishablePage]attribute if there are conflicts with the existing component-level implementation)- Unpublished pages (
publishedAt: null) are invisible to unauthenticated users via the existing voter infrastructure (AbstractRoutableVoter,RouteVoter) - Admins can still access and edit unpublished pages via the entity IRI (same as draft components today)
RouteVotergates public route resolution by the target page'spublishedAtstate- The
resource_manifestendpoint respects the same gate
Things to consider
#[Publishable]today lives on components; its voter logic (PublishableVoter?) would need to be checked / extended for page-level entitiesPage.isTemplatepages should probably always be accessible to admins regardless ofpublishedAt(template pages are never public-facing)- Draft page data entities with an existing Route — the route should resolve to 404/403 for public traffic, not 500
- Interaction with
cascadeChildPathsand the children endpoint: should unpublished children be hidden from the public children list? - Migration: existing pages have no
publishedAt— default tonull(draft) or tonow()(treat existing pages as already published)? Likelynow()for backwards compatibility
Acceptance criteria
-
AbstractPageand/orAbstractPageDatagain apublishedAtcolumn - Unauthenticated
GET /_/routes/{path}to a page withpublishedAt: nullreturns 403/404 - Admin
GET /_/resource_manifest/{uuid}for an unpublished page works forROLE_ADMIN - Behat scenarios cover: public access denied, admin access allowed, publish via PATCH
- Backwards-compatible migration (existing pages treated as published)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with AbstractPage and AbstractPageData, then trace the existing component-level #[Publishable] implementation and voter logic, including AbstractRoutableVoter and RouteVoter. Check route resolution and the resource_manifest endpoint, plus interactions with templates and child paths. Add Behat coverage for public denial, admin access, publishing via PATCH, and a backwards-compatible migration for existing pages.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php, symfony
- Domain
- api, authorization, backend, database, testing
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100