-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Save meta on preview #11409
Save meta on preview #11409
Conversation
// This relies on the window being responsible to unset itself when | ||
// navigation occurs or a new preview window is opened, to avoid | ||
// unintentional forceful redirects. | ||
if ( previewLink && ! prevProps.previewLink ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uncertain about this change: despite the inline comment, I don't understand how prevProps.previewLink
is used here and I have removed it. instead, I am testing that both autosave and metabox save have completed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Works as expected in my testing. I'll defer to @aduth for the underlying JavaScript.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved from a functional perspective, see above comment. Deferring to @aduth on the JavaScript itself.
To clarify, is a meta box update meant to occur in response to the interaction of the preview button press, or is it bound to the behavior of save/autosave? This approach may be sensible for the former, but not the latter. |
the former, this alters the behavior for the preview button only and reintroduces the current (unfortunate) core behavior of saving metabox meta to the original post for previews. (see https://core.trac.wordpress.org/ticket/20299 -we can resolve this when we introduce meta revisioning to core) |
const { | ||
hasMetaBoxes, | ||
isSavingMetaBoxes, | ||
} = select( 'core/edit-post' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The editor package shouldn't know anything about the metaboxes, I don't know what this PR is trying to do exactly but we should try to hook into the saving mechanism from the edit-post
package instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you probably want to tweak this condition instead https://github.com/WordPress/gutenberg/blob/master/packages/edit-post/src/store/effects.js#L53
(Curious about the impact on revisions of all these save requests though)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know what this PR is trying to do exactly
@youknowriad
This PR is attempting to save metaboxes when a preview is triggered. That is, when the preview button is clicked, we save meta before displaying the preview so updated meta values will be included.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you probably want to tweak this condition instead
Yes thanks for the suggestion... I looked at that originally without much luck because the previewing "condition" is not being tracked. It seemed more straightforward to add metabox saving as an effect of clicking the preview button only and code wise it is maybe simpler.
to move the logic into SET_META_BOXES_PER_LOCATIONS
in effects, i think we need to track isPreviewing
to know this is a preview autosave not a regular autosave - we don't want to save metabox meta for regular autosaves, only when the user clicks preview - does that sound right? or should i instead try to add a variable to the autosave call, eg autosave( true ) would be a preview autosave?.
(Curious about the impact on revisions of all these save requests though)
no revisions are stored for meta currently in core - the meta is saved directly to the post (unfortunately). only one autosave revision is saved per post (per user).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the preview autosave is not just a regular autosave? Is there anything different in the backend or is this the actual different, the need to not trigger ant autosave but an actual save including metaboxes?
- Could we just trigger a regular save (instead of autosave) when previewing drafts?
- What should happen if we preview a published post and preview is clicked, should we save the metaboxes too? it seems like an unwanted changed could be published inadvertently?
- If it's only for drafts, then I'd be fine adding a flag tracking that we're previwing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the preview autosave is not just a regular autosave?
to match core behavior:
regular autosaves do not include saving post meta - they only save the title, excerpt and content. previews also save all meta so that previews can include changes made in meta fields which may affect how the post displays. This fixes the issue raised in #11280. it also re-introduces the issue raised in https://core.trac.wordpress.org/ticket/20299.
I would love to work on a more complete solution - - perhaps as part of phase 2 - that would add meta revisioning to the autosave, so meta values would be associated with the autosave instead of the parent post, which would fix the unwanted saving of meta values to published posts when previewing. The code to achieve this is already available in a patch on the ticket and relies on my Post Meta Revisioning plugin.
Could we just trigger a regular save (instead of autosave) when previewing drafts?
Yes, probably - however that might require more refactoring of how the preview loads its data?
What should happen if we preview a published post and preview is clicked, should we save the metaboxes too? it seems like an unwanted changed could be published inadvertently?
Absolutely right - this is a tricky situation, if we save the metaboxes unwanted changes could be saved, if we don't save the metaboxes we risk the preview not showing the correct information. That is why adding meta revisioning and using that for the preview makes so much sense - it solves both problems. Short of that, we probably want to match the existing core behavior despite the possibility of unwanted data being saved. Since this is such a long standing and well documented bug it has (sadly) become the expected state of affairs.
If it's only for drafts, then I'd be fine adding a flag tracking that we're previwing.
its for drafts and published posts, both need to save meta when previewing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
its for drafts and published posts, both need to save meta when previewing.
Gotcha, this means you're right that we need to distinguish the "preview save" from an "autosave" in the state to be able to trigger the metaboxes save in edit-post
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 will try to refactor as you suggest
I'd love to get this in but it doesn't seem ready for 4.3. |
@adamsilverstein Still able to own this through to completion, or do you need to hand it off? |
Curious, is post meta saved only to the Preview / autosave revision? If you close the editor without Publish / Update, does live post meta retain their original values? EDIT OK this might be answered already
|
On a meta note, it would be neat if linting caught this. Do you think this is technically feasible? |
It should be possible with a custom linting rule, we'd have to check for package.json dependencies and have a mapping between package name and store name. |
Great. Created an issue with #11865 |
This doesn't seem to work for me, not sure what's going wrong here. Also question: this doesn't save the featured image, categories ... Are these supposed to be fixed in another issue? |
Thanks for testing. I'll dig in to see if I can tell what is happening. This addresses meta boxes so far. Featured image is being handles separately in #12037. I didn't realized categories/tags weren't included here, we should add them. One potential issue is I think the post endpoint accepts these directly, I'm not sure the autosave endpoint does. |
* | ||
* @return {boolean} Whether the post is being previewed. | ||
*/ | ||
export function isPreviewingPost( state ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's slightly weird that preview would have this side-effect but it wouldn't be evident from selector name. Though I guess it matches the expectation of the action itself.
5fb123c
to
74035ca
Compare
|
||
// Once popup redirect is evaluated, even if already closed, delete | ||
// reference to avoid later assignment of location in post update. | ||
delete this.previewWindow; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aduth I removed this to be able to refresh the window without an autosave (once the metaboxes finish saving). I'm not aware of any downsides but let me know if I missed something.
I pushed some updates here, It's working better now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍 But a second review would be good as I did work on this.
<PostPreviewButton /> | ||
<PostPreviewButton | ||
forceIsAutosaveable={ hasActiveMetaboxes } | ||
forcePreviewLink={ isSaving ? null : undefined } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could be refactored to:
forcePreviewLink={ isSaving }
and then we only would need to update the code later in the execution flow to:
previewLink: forcePreviewLink ? null : getAutosaveAttribute( 'preview_link' ),
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it can't because we're forcing the null
value from outside. The inner component don't know what value to put unless we rename the prop something like forceEmptyPreviewLink
! wasAutosavingPost && | ||
! isSavingPost && | ||
! isAutosavingPost | ||
hasActiveMetaBoxes && ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hope it works 🙏 😅
* @return {boolean} Whether the post is being previewed. | ||
*/ | ||
export function isPreviewingPost( state ) { | ||
return isSavingPost( state ) && !! state.saving.options.isPreview; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I don't think we need !!
in this condition. If we need it, we should probably be consistent and add it in the previous selector that is updated in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated. it's better to have it to ensure the return value is always a boolean.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It works as expected in my testing using the snippet shared by @danielbachhuber in #11280 (comment).
Description
When clicking the preview button, save all metaboxes. Set preview URL only after metabox save is complete.
How has this been tested?
Using the sample code from #11280 (comment) I added a meta box. I tested changing the metabox value and clicking preview before blurring out of the field or letting a regular autosave trigger. I observed the correct meta on the preview page, and meta was saved to the post (as expected).
Types of changes
Checklist: