Skip to content

[6.x] Allow Live Preview while creating entries - #15648

Open
matsantosz wants to merge 3 commits into
statamic:6.xfrom
matsantosz:live-preview-on-create
Open

matsantosz wants to merge 3 commits into
statamic:6.xfrom
matsantosz:live-preview-on-create

Conversation

@matsantosz

Copy link
Copy Markdown

When you're creating an entry, the Live Preview button doesn't show up. You have to save first and only then can you preview, which is a bit awkward when you're writing a brand new page and just want to see how it looks. On our side this happens all the time with landing pages, and people end up saving throwaway drafts only to get to the preview.

The backend already supports this. The create form gets a livePreviewUrl pointing at collections.entries.preview.create, and that route builds an unsaved entry and returns a token (there's already a test for it in PreviewEntryTest). What was missing was the button itself, plus one bug further down the line: when the preview page loads, EntryRepository::substitute() calls Blink::forget($item->id()), and since a new entry has no id yet, the request fails with a TypeError.

This PR:

  • shows the Live Preview button on the create form by dropping the isCreating check
  • makes substitute() skip the id based substitution when the entry has no id. The entry is still substituted by its URI, which is how the preview request finds it anyway.

I added a test that previews an entry that was never saved and checks that the page renders with its values. Without the fix it fails with the Blink TypeError.

@jasonvarga jasonvarga left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this. Tried it in a sandbox and found two problems, neither covered by the new test:

  1. Dated collections (e.g. blog) return a 500 on the create form's Live Preview. EntryPreviewController::create() passes the raw ISO date string to $entry->date(), which can't parse it (Carbon\Exceptions\InvalidFormatException).
  2. Structured collections (e.g. pages) preview the home page. An unsaved entry isn't in the tree, so Entry::uri() returns null and the preview URL resolves to /.

@matsantosz

Copy link
Copy Markdown
Author

Thanks for testing it, both were real. Fixed in the latest commit:

  1. Dated collections: the create preview now handles the date the same way storing an entry does (processed by the date field, then augmented), so the ISO string from the form no longer reaches $entry->date(). If there's no date it falls back to now.
  2. Structured collections: an unsaved entry now gets the URI it will have once saved, under its parent. I moved the URI logic store() already uses for its unique URI check into a small ResolvesEntryUri trait and reused it in the preview controller. The create form also passes parent along to the preview URL, so a child page previews at /parent/slug, a top level one at /slug, and picking the root page counts as no parent. Entry::uri() only uses that preview URI when the entry has no id yet, so saved entries aren't affected.

New tests in LivePreviewNewEntryTest go through the whole flow (post to the create preview, then load the URL it returns) for a dated collection with and without a date, and a structured collection at the top level, under a parent and with the root page as parent. Two more in CreateEntryTest check the parent ends up in the preview URL only for structured collections. Without the fix the dated one fails with the Carbon exception and the structured ones resolve to /.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants