WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.52k stars 4.2k forks source link

Preview fails to display edits on published posts when metaboxes are visible in Gutenberg #12617

Closed davidAIS closed 5 years ago

davidAIS commented 5 years ago

The preview button in the Gutenberg editor in Wordpress 5 RC3 doesn't display unsaved edits.

Reproduced by creating and saving a page, then edit the page and click preview. The preview page only shows the original page and not the additional edits.

dlh01 commented 5 years ago

While there might be many ways for this behavior to occur, I've observed it happening with this combination involving PHP meta boxes:

  1. A published post is previewed, generating an autosave.
  2. The POST request to save PHP meta boxes is sent to post.php. The published post is updated and its last-modified time is bumped.
  3. The POST request is redirected as a GET request to post.php again. This logic runs, which compares the modified dates of the autosave and the post: https://github.com/WordPress/wordpress-develop/blob/e5b5db9e2349dfe8a43ac42bea5738146f53994d/src/wp-admin/edit-form-blocks.php#L294-L303
  4. The modified date of the post is now more recent than the autosave, so the autosave is deleted.
  5. The preview loads, but there's no more autosave to preview.
earnjam commented 5 years ago

The preview functionality works by the post-preview-button component having a call to componentDidUpdate() that basically attempts to load the preview URL in the preview window every time the component is re-rendered. It stops if there is no preview link or preview window available.

So when you click the preview button this is essentially what happens:

1) It checks to see if a preview window already exists, if not (or has been closed), it opens a new tab/window for the preview 2) It focuses on the preview window (which means the rest of this occurs in the background since your browser now has the preview window focused) 3) It checks to see if the post can be autosaved using isEditedPostAutoSaveable() and if it can't be autosaved, then it just opens the URL in the href attribute of the preview button and stops. 4) If we've reached this point, autosave is possible most likely because there are edits. But first it looks to see if it's a draft, and if so, it just does a regular save. 5) If it's not a draft, then it triggers an autosave because we don't want to update live content yet. 6) Both the autosave and the regular save have the same effect of causing the component to re-render, which triggers the componentDidUpdate() and forces the preview window to reload.

Seems like there are a couple of opportunities for race conditions here due to the various moving parts required to determine when to load the preview and what URL to load. I need to do some more testing to see where I can get this to fail.

KristaButler commented 5 years ago

I have experienced this issue with every page on sites that upgraded to 5.0. Any page that was created before the update does not show changes in the preview, or after publishing. Converting the page to blocks does not seem to resolve the issue.

Armarsh commented 5 years ago

I have this problem on 10 different sites with 8 different themes --- and the one thing that every site shares is that this started with the WP 5.0/ Gutenberg upgrade. So I think that's the heart of the problem, one way or another. And again, disabling plugins and reverting to Twentynineteen didn't solve the problem on the sites that I tested.

designsimply commented 5 years ago

I have done some additional testing but am still looking for reliable steps to reproduce the problem that does not involve plugins.

Based on the information in https://github.com/WordPress/gutenberg/issues/12617#issuecomment-449520938 I ran the following test:

  1. Go to https://jurassic.ninja/ and create a new test site.
  2. Go to Plugins > Add New, search for FakerPress, install & activate.
  3. Go to FakerPress > Posts and generate 200 posts and 80 pages.
  4. Check the size of the database using wp db size --size_format=kb via wp-cli (ssh credentials for jurassic.ninja sites are provided in an admin notice).
  5. Go to Posts and open any published post.
  6. Make any edit to the post.
  7. Click the "Preview" button and check to see if the edit appears in the preview.

Result: the database including the sample content was 5.8 MB and all previews still worked normally in my own testing. (1m38s)

Continuing on, I decided to also test Yoast SEO again since they had recently updated to version 9.4.

  1. Go to Plugins and install or update to Yoast SEO 9.4.
  2. Go to Posts and open any published post.
  3. Make any edit to the post.
  4. Click the "Preview" button and check to see if the edit appears in the preview.

Result: previews of edits made to published posts do not appear if Yoast SEO 9.4 is installed and activated. (53s)

Last, I tested Advanced Custom Fields since it was mentioned as problematic in earlier comments.

  1. Go to Plugins and install or update to Advanced Custom Fields 5.7.9.
  2. Go to Posts and open any published post.
  3. Make any edit to the post.
  4. Click the "Preview" button and check to see if the edit appears in the preview.

Result: previews of edits made to published posts do not appear when using Advanced Custom Fields 5.7.9. (1m23s)

What I'm seeing in testing so far is that I can definitely correlate some plugins, particularly plugins using meta boxes, with the problem but I am not sure if they are the cause. I can also say that I do not personally see the problem for a site with a database that is 5.8 MB. For those of you having trouble even after deactivating all plugins and switching to the default theme, I am not sure yet what is causing the trouble in your case. @earnjam, if you have any ideas for what else to test, please let me know so I can help out!

designsimply commented 5 years ago

@KristaSnapdragon I noticed you mentioned the problem happens for you on pages created before updating to WP 5.0. May I ask if the same problem happens for you on posts you create after updating to WP 5.0?

davidAIS commented 5 years ago

I'm testing on a site that was created prior to WP 5.0 and the block editor but now with all plugins except Classic Editor deactivated and using the 2019 theme.

In that configuration I am consistently seeing the reported issue with edits to existing pages when edited with the block editor. That's also the case if I turn off the Classic Editor plugin.

In other words there is no interaction here with Yoast or any other plugin in the case of content created prior to WP5.0 and the block editor.

If the Classic Editor is turned off the I can create new content and edit content created using the block editor and preview works correctly.

But if the Classic Editor plugin is turned on, then the issue appears when editing new content that has been created after Classic Editor was turned on - even if it was created with the block editor

It might be tempting to conclude that the issue is a clash with the Classic Plugin itself. However the fact that the issue occurs for content created prior to WP5 and the block editor when it is subsequently edited with the block editor and when there are no activated plugins demonstrates otherwise. There is something more fundamental going on!

talldan commented 5 years ago

While there might be many ways for this behavior to occur, I've observed it happening with this combination involving PHP meta boxes:

  1. A published post is previewed, generating an autosave.
  2. The POST request to save PHP meta boxes is sent to post.php. The published post is updated and it's last-modified time is bumped.
  3. The POST request is redirected as a GET request to post.php again. This logic runs, which compares the modified dates of the autosave and the post: https://github.com/WordPress/wordpress-develop/blob/e5b5db9e2349dfe8a43ac42bea5738146f53994d/src/wp-admin/edit-form-blocks.php#L294-L303
  4. The modified date of the post is now more recent than the autosave, so the autosave is deleted.
  5. The preview loads, but there's no more autosave to preview.

@dlh01 Thanks for debugging that. I think that's the clearest explanation of what's happening here. 👍

earnjam commented 5 years ago

@talldan There are also people reporting it without any meta boxes though, so I don't think that's the only culprit.

talldan commented 5 years ago

@earnjam Yep, but I don't want a very good explanation of one of the causes to be buried in this thread.

jweston491 commented 5 years ago

Not much to add except I am having the same issue with both Yoast and ACF on a vanilla WP using Twenty-Nineteen.

Disabling Gutenberg/installing Classic Editor allows Preview to work as expected.

Using PHP 7.2.9 and MySQL 5.7

bhagwad commented 5 years ago

I have the problem as well.

  1. Post created with classic editor and published
  2. Trying to edit with Gutenberg
  3. Preview is not displaying the changes
nicosabio2016-zz commented 5 years ago

I have the problem as well but not like the others who posted here my wordpress version is not yet updated to 5. Even refreshing the preview page is not working for me.

designsimply commented 5 years ago

@nicosabio2016 thank you for the note! Would you mind noting a bit more detail about your setup for reference? For example, exact WordPress version, Gutenberg plugin version, whether you've tried testing with all plugins temporarily turned off, and how long the problem has been happening to you (if you can remember!).

@bhagwad it would be great if you could include some extra details such as your WP version and whether you have tested with no plugins active. Thank you!

@jweston491 thanks for confirming that the problem only happens for you when previewing edits to published posts and only if you have either ACF or Yoast plugins activated.

johnnyontheweb commented 5 years ago

Same problem for me with 5.0.3 hosted on IIS, the preview does not reflect the changes made in a page. The problem arose when I updated from 4.9.4 to 5.0.3. Is there any solution for this?

IreneStr commented 5 years ago

While there might be many ways for this behavior to occur, I've observed it happening with this combination involving PHP meta boxes:

  1. A published post is previewed, generating an autosave.
  2. The POST request to save PHP meta boxes is sent to post.php. The published post is updated and it's last-modified time is bumped.
  3. The POST request is redirected as a GET request to post.php again. This logic runs, which compares the modified dates of the autosave and the post: https://github.com/WordPress/wordpress-develop/blob/e5b5db9e2349dfe8a43ac42bea5738146f53994d/src/wp-admin/edit-form-blocks.php#L294-L303
  4. The modified date of the post is now more recent than the autosave, so the autosave is deleted.
  5. The preview loads, but there's no more autosave to preview.

We've tested this hypothesis with the Yoast SEO plugin, and it seems @dlh01 is right.

When clicking the preview button, there are two autosaves triggered: one of the post itself, and one of the Yoast metabox. The autosave of the post has a timestamp that is one second before the autosave of the metabox. This means that after the above mentioned compare between the dates, the autosave of the post is deleted, while the autosave of the metabox is the one that is used for the preview.

Because the metabox autosave doesn't contain the post content, (our hypothesis is that) it uses the content of the original save, which means the latest changes (that were in the deleted autosave) do not show up in the preview.

For testing purposes, we changed > to < in https://github.com/WordPress/wordpress-develop/blob/e5b5db9e2349dfe8a43ac42bea5738146f53994d/src/wp-admin/edit-form-blocks.php#L296. In that scenario, it keeps the autosave from the content, which means the preview is up-to-date.

When we disable the yoast metabox (but keep the plugin active) the problems disappear and the preview is up-to-date as well.

designsimply commented 5 years ago

Thank you for testing and leaving a comment with findings @IreneStr!

I took a moment today to re-test with the latest development versions WordPress 5.0.4-alpha-44523 and Gutenberg 4.9.0-rc.1 and Yoast SEO 9.5 (and without Yoast SEO) using a https://jurassic.ninja/ test site and found that I am still unable to preview edits to published posts.

talldan commented 5 years ago

@IreneStr & @dlh01 That's great, thanks for validating this cause.

The modified date of the post is now more recent than the autosave, so the autosave is deleted.

I have an idea for a pretty simple fix for this, which is not to delete the autosave if the request is for a meta_box update. Change it from:

    } else {
            wp_delete_post_revision( $autosave->ID );
    }

to:

    } elseif ( ! isset( $_REQUEST['meta_box'] ) ) {
        wp_delete_post_revision( $autosave->ID );
    }

It seemed to solve the issue when I tested it, but I'm not completely familiar with the code for updating metaboxes. Maybe there's a better solution.

youknowriad commented 5 years ago

@talldan I think since we are triggering two save requests (post api and metabox) when we have metaboxes, I think the idea was to explicitely delete of the revisions. So probably instead of deleting the metabox autosave, we should overwrite the previous one. What do you think?

dlh01 commented 5 years ago

@talldan I'm not sure I'm familiar enough with all the intentions of edit-form-blocks.php to offer a really informed opinion about adding a $_REQUEST check in that location. I imagine that it would address the immediate problem, though.

But the current logic of deleting the revision, in itself, also seems sound. The request to save PHP meta boxes results in a "true" update of the post via wp_update_post(), not another autosave. In all other cases core would (I think?) expect that the existing older autosave would be deleted at the next opportunity. See the similar logic in edit-form-advanced.php: https://github.com/WordPress/wordpress-develop/blob/e5b5db9e2349dfe8a43ac42bea5738146f53994d/src/wp-admin/edit-form-advanced.php#L226-L239.

So creating a scenario where an autosave exists when core doesn't expect one to exist could have side-effects.

Again, though, I could be wrong on the facts, and the risk involved in adding an exception might be minimal regardless.

talldan commented 5 years ago

So probably instead of deleting the metabox autosave, we should overwrite the previous one. What do you think?

@youknowriad So you mean overwrite/update any existing autosave during the secondary meta box update? That would improve the situation, as you'd no longer have a lingering autosave that's older than the post, which seems to be the case this code is trying to avoid.

But the current logic of deleting the revision, in itself, also seems sound. The request to save PHP meta boxes results in a "true" update of the post via wp_update_post(), not another autosave. In all other cases core would (I think?) expect that the existing older autosave would be deleted at the next opportunity.

@dlh01 Yep. I think the way Gutenberg handles metabox updates is definitely an edge case. You're right in that it's probably a good idea to stick to that core rule of having autosaves that are older than the post not be retained.

The other solution that came to mind is to change the order of the updates when previewing:

  1. Update post meta
  2. Autosave the post
  3. Show the preview

It would most likely involve some less than ideal code in gutenberg, as the post meta save is currently triggered as a side-effect using a subscription: https://github.com/WordPress/gutenberg/blob/0259f7b2aec9ab66f3a040d08a5aeeb5c65e5756/packages/edit-post/src/store/effects.js#L50-L72

bonlando commented 5 years ago

I'm having a very similar issue, however the changes appear if I wait 5 seconds after the preview loads, then hit reload.

gziolo commented 5 years ago

There is also a report from @dariaknl which might need some action here:

@gziolo I have looked into this issue (#13038) using wordpress-seo plugin (with e2e tests). Your test is failing with:

    Expected: "Hello World! And more."
    Received: "Hello World!"

      107 |       // Title in preview should match updated input.
      108 |       previewTitle = await previewPage.$eval( '.entry-title', ( node ) => node.textContent );
    > 109 |       expect( previewTitle ).toBe( 'Hello World! And more.' );
  • once the post has been published it does not get updated title in preview if you change the title. Indeed the test succeeds with wordpress-seo disabled.

But I tried the same test with built-in Advanced Panels “Custom Fields” enabled and wordpress-seo disabled. I get the same result - the test fails, updated title is not shown in preview. So it seems that the issue is related more to the problem with metabox in general.

I tested with: WP 5.0.3 and Gutenberg 4.8.0 and 4.9.0.

earnjam commented 5 years ago

Did some digging on this. In my testing, the deletion of the autosave didn't seem to matter either way.

The issue stems from a couple of criteria: 1) On published posts, we just want to trigger an autosave and not a regular save on preview because we don't want to update the actual published content yet. 2) Post meta doesn't support revisions, so it has to do a standard save and update immediately.

Metabox saves are handled by a POST to /wp-admin/post.php. That triggers a call to edit_post() and eventually wp_update_post(), which will always update the post_modified date of a published post. Since the meta box save request comes after the autosave request, the post_modified date is newer by 1 second on the published post than on the autosave that is created. The preview sees that and just loads the published post, since it's newer.

We need the post_modified date of the autosave to >= the published post. Flipping the order in which the two separate calls are made seems like the logical solution if it's possible.

earnjam commented 5 years ago

I revisited this today to test out reordering the two requests on a preview, and I now see it deleting the autosave. (I think I was looking at the wp_delete_post_revision() call in core, but had the Gutenberg plugin active, which overrides the editor screen and has it's own call of that function)

It also doesn't matter to the preview whether the autosave post_modified is older or newer than the actual post (I tested by directly changing it). Preview shows the autosave post_content if it exists at all. So the issue is indeed related to the autosave being deleted.

So pretty much ignore my whole post above this one ¯\(ツ)/¯ 😀

I tried removing the metabox save subscription on previews, and then directly calling it from the preview button before the autosave request to see if that would be enough, but it's still a race condition situation that often ends with the autosave being deleted because it's usually a good bit faster to execute than the metabox save.

Seems like we either have to wait on the response from the metabox save before triggering the autosave, making them even slower than they already are, or else put in some kind of exception to the removal of the autosave like @talldan mentioned above. Both seem...not great.

talldan commented 5 years ago

@earnjam Thanks for looking into it. I agree, I'm not enthused about any proposed solution so far.

Any thoughts on what the best option is?

Also should mention there are a couple of trac tickets covering this as well with discussions: https://core.trac.wordpress.org/ticket/45768 https://core.trac.wordpress.org/ticket/45532

MarkRH commented 5 years ago

Interesting. I just experienced this for the first time today editing an old post from 2011, which it placed in a complete Classic Block. I added a paragraph block above it and removed a link from within the Classic Block. Clicked Preview and it showed what I had before any edits with no changes. I tried clicking around different sections and it made no difference. So, I just clicked Update and then the Preview showed the correct content.

Anyway, I'm on WP 5.0.3, Twenty Twelve child theme, and using Firefox 65.

Just tested again and like what some other have said, if I wait a few seconds and refresh the tab that has the preview in it, I then see the changes. So, some odd timing issues.

It's been quite some time since I've edited old post so I'm not sure how far back it would have started.

talldan commented 5 years ago

Apologies for the delay on the fix for this—it's a challenging issue. I now have a proposed fix at #13718.

marcber commented 5 years ago

I do not know if it can help, but I noticed the following:

So can we assume that it is related to some states related to a given page post within the SQL DB, which are used in the preview button logic? Those states being also linked to the autosave logic seems a safe bet indeed.

The whole preview logic should maybe be rewritten from the ground up... I've tracked issues related to this back from 2013 or so, on pretty old WordPress releases. It's been a rampant bug for quite a while it seems.

If possible, the double load trick should be replaced by a cleaner logic that only loads once, even if it's a non published content version.

Regards.

thetroublemaker commented 5 years ago

I've also just noticed this happening; none of the edits from the admin view (code/css) are appearing ont he preview instance.

Armarsh commented 5 years ago

Quick note: this problem seems to have gotten worse with WP 5.1 update.

Before: Preview would not appear initially, but was viewable a few seconds later with a refresh of the preview page.

Now: Preview does not appear at all. Options are to either update the published page to see changes, or revert the published page to draft status while completing edits.

MarkRH commented 5 years ago

Yeah, I can confirm. With 5.1, editing an existing post, preview will not show any changes. Refreshing the preview page no longer works for me as well. So, yeah, it has gotten worse. (Firefox 65.0.1 in Windows 7)

I also does not work if I edit a post I just created in 5.1.

Preview has worked just fine as I am making a post but have not published it yet.

katsar0v commented 5 years ago

Same issue here, works with drafts though, with published not.

earnjam commented 5 years ago

I adjusted the title to reflect the specific details identified in this issue as the culprit. That will help us distinguish it from #13232 if there is another situation where metaboxes are not the cause.

it-tbt commented 5 years ago

I've had the PREVIEW BUTTON do nothing on more than one website, even with WP5.1 and it is painful.

DimeZilla commented 5 years ago

Hi all - Long time listener, first time caller! I love the new block editor and really appreciate the work you all do.

I've been looking into this for a bit because we have a lot of client sites that we've upgraded and we use meta-boxes extensively. I'm not a react developer so I'm sorry if this comment is unhelpful. However, I'd really love for preview to work so I thought maybe these ideas might be helpful. Also, I'm only working off of the build files currently bundled into 5.1 so I don't know if my suggestions here will necessarily work.

To me, this looks like an order of operations problem. I can see that when autosave is triggered, there is a listener in the edit-post component that is like "hey did we just do an autosave? do we have meta boxes? we do? lets update those boxes." (I can see this happening in lines 46 - 72 of edit-post/src/store/effects.js) and then the update requested by the edit-post component is overriding the state and thus the preview generated is not for the latest autosave. If I comment out the subscriber in those lines in my build file, the preview works just fine (however, i have no idea of the implications that result in previewing changes to metaboxes).

It seems to me that it should be the editor component that first broadcasts to the edit-post component that it is about to process an autosave, that way the edit-post component can request it's updates, then the editor component can process the autosave and the thus preview will be the latest autosave. Although, off hand I don't know the right way of doing this so I'm not sure what this might look like.

However, I was also able to get it to work by dispatching a new autosave inside the chained callback in line 117 of the file listed above, effect.js. By invoking a new autosave directly like so: dispatch('core/editor').autosave(). Perhaps that's another hacky solution. So my edit looks like this:

// starting on line 111
apiFetch( {
            url: window._wpMetaBoxUrl,
            method: 'POST',
            body: formData,
            parse: false,
        } )
            .then( () =>{ 
                              // invoke new autosave - maybe add some more conditional logic here to figure out
                             // what triggered this request so that if it's a full save, we request a save, or if it's an
                             // autosave we do an autosave like so.
                              dipatch('core/editor').autosave();
                              store.dispatch( metaBoxUpdatesSuccess() ) 
                        });
David-Else commented 5 years ago

Preview is not working for me in 5.1. I waited for 5.1 to try Gutenberg assuming it would work properly by this point... how can I edit my (pre published) posts and see a preview? This is the most basic thing I can think of. I have to press update each time at the moment.

The actual preview inside Gutenberg does not reflect how it appears on the published post, the formatting of the text in relation to the images is different.

I would actually really like Gutenberg if it worked :)

jaydanurwin commented 5 years ago

Preview is not working for me in 5.1. I waited for 5.1 to try Gutenberg assuming it would work properly by this point... how can I edit my (pre published) posts and see a preview? This is the most basic thing I can think of. I have to press update each time at the moment.

The actual preview inside Gutenberg does not reflect how it appears on the published post, the formatting of the text in relation to the images is different.

I would actually really like Gutenberg if it worked :)

I'm in the same boat over here. I thought it would be stable by now but my preview in 5.1 literally never works. :(

Running WP 5.1 on Google Cloud Compute Engine (Click to Deploy)

kaylegh commented 5 years ago

On 5.0.3, preview doesn't work. Trying to refresh or empty caches on the preview page doesn't change anything.

talldan commented 5 years ago

As mentioned on the other issue (https://github.com/WordPress/gutenberg/issues/13232), this now seems to be resolved. I'm not sure which particular change has resulted in the fix.

MarkRH commented 5 years ago

Nope. Not fixed in 5.1.1. Editing an existing post and clicking preview does not show the changes.

ernilambar commented 5 years ago

@talldan After testing few themes, I noticed that this problems occurs in those theme which has custom meta fields for the page. In those theme which has no custom meta box, preview works as expected.

thetroublemaker commented 5 years ago

Most data-driven WP sites use some form of custom fields, our site as an example uses ACF.

On Fri, Mar 15, 2019 at 2:23 AM Nilambar Sharma notifications@github.com wrote:

@talldan https://github.com/talldan After testing few themes, I noticed that this problems occurs in those theme which has custom meta fields for the page. In those theme which has no custom meta box, preview works as expected.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/WordPress/gutenberg/issues/12617#issuecomment-473172823, or mute the thread https://github.com/notifications/unsubscribe-auth/ADUrkUAGtSmWGiDRvdyUbSVPhCymk6s_ks5vWzxKgaJpZM4ZC_rC .

Armarsh commented 5 years ago

Lack of preview persists on my sites with WP 5.1.1.

talldan commented 5 years ago

@ernilambar I tested using a custom field, which has the same effect.

@Armarsh, @MarkRH - I tested against master, and I couldn't reproduce. If this is fixed, there's a chance the fix hasn't been released yet.

Tintedshadows commented 5 years ago

Most data-driven WP sites use some form of custom fields, our site as an example uses ACF. On Fri, Mar 15, 2019 at 2:23 AM Nilambar Sharma @.***> wrote: @talldan https://github.com/talldan After testing few themes, I noticed that this problems occurs in those theme which has custom meta fields for the page. In those theme which has no custom meta box, preview works as expected. — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#12617 (comment)>, or mute the thread https://github.com/notifications/unsubscribe-auth/ADUrkUAGtSmWGiDRvdyUbSVPhCymk6s_ks5vWzxKgaJpZM4ZC_rC .

After some testing I can confirm that this was the issue my site was having. Any themes/plugins that adds a meta box to the page editor will cause the preview button to not work. I removed anything that added a meta box from 5 different WordPress installs and the preview button is now working again.

Hopefully this issue will be fixed in the future but a quick fix would be to install the classic editor plugin.

MoreFallout4 commented 5 years ago

Lack of preview persists on my sites with WP 5.1.1.

Same, using Opera v. 60.0.3254.0 on Windows 10 and v. 58.0.3135.107 on Mac OS X 10.14.3

talldan commented 5 years ago

After testing again, it looks like the problem still exists 😞

Sorry to get everyone's hopes up.

gnanasekaranl commented 5 years ago

+1, My combination Windows 10 + chrome Version 72.0.3626.121

minderoodigital commented 5 years ago

+1, can confirm we are experiencing the same issues Windows 10 and Chrome 72.0.3626.121