WordPress / gutenberg

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

Changing content with wp_insert_post_data is not reflected in the editor. #12026

Open websupporter opened 5 years ago

websupporter commented 5 years ago

Describe the bug If I hook into wp_insert_post_data to change some text while saving my content, the title gets updated automatically, but not the content.

To Reproduce

add_filter( 'wp_insert_post_data', 'just_a_test', 10, 2 );
function just_a_test( $data, $raw ){
    $blacklist = array(
        preg_quote(' a stupid example '),
    );
    foreach ($blacklist as $delete ) {
        $data['post_title'] = preg_replace('^' . $delete . '^i', ' --censored-- ', $data['post_title']);
        $data['post_content'] = preg_replace('^' . $delete . '^i', ' --censored-- ', $data['post_content']);
    }
    return $data;
}

Take this code and enter for example the title "This is a stupid example but okay". Add the same string as text and press "Update" or "Save Draft". While the title in Gutenberg has changed, the content is still the same.

Expected behavior After the upate the content should read "This is --censored-- but okay"

Desktop (please complete the following information):

earnjam commented 5 years ago

The filter is working in that it saves the changes and it displays properly on a preview or publish. It's just that the content area of the editor is not live-updated with the filtered content. A refresh of the editor will cause it to show the new edited content.

It appears this is because we update the post title from the REST API response on a save, but we don't change the content area. There may be a technical reason for doing that, but I'm not sure what off-hand (performance maybe?)

metal450 commented 5 years ago

When testing WP5.0b5 against my plugins, I also discovered this issue - which breaks my plugin.

(https://wordpress.org/plugins/facebook-photo-fetcher/)

spacedmonkey commented 5 years ago

This is a major issue for me as well. When I click update in the editor, the values that come back from the api, should be used to redraw the whole editor with these values. Without that redraw, the editor could edittiing very different content than what is found in the database, which will generate errors.

aduth commented 5 years ago

It appears this is because we update the post title from the REST API response on a save, but we don't change the content area. There may be a technical reason for doing that, but I'm not sure what off-hand (performance maybe?)

Performance is one factor, both in the cost of parsing the new content, and in re-drawing the editor block list.

Another is that a new parse would introduce an entirely different set of clientId for each parsed block. While these aren't meant to be deterministic from a "same" block anyways, it's unclear to me whether any plugins or core behaviors might have some dependencies on this value.

There may be a potential workaround in using the resetBlocks data action. This will replace the set of parsed blocks in the editor's state and update the editor UI accordingly. I imagine some rough pseudo-code to be:

onSaveComplete( savedContent ) {
    dispatch( 'core/editor' ).resetBlocks( parse( savedContent ) );
}

References

spacedmonkey commented 5 years ago

According to a search I just did, 577 plugins on the repo use this filter. See this link. Which means this will be a common issue.

mcsf commented 5 years ago

Another is that a new parse would introduce an entirely different set of clientId for each parsed block. While these aren't meant to be deterministic from a "same" block anyways,

I dare say this is an even bigger factor than performance. If the editor is expected to take an entire saved post as returned from the server and assume that to be the new truth, then all bets are off in terms of which blocks are which, with consequences for the edit history, etc. It's not that it's not feasible to write a reconciler — which, via diffing, would attempt to map pre-save blocks to post-save blocks — but that would expose the editor to a number of edge cases, potential data loss (what if an update hook is misbehaving and deleting content? we run the risk of losing the editing buffer and its history too), and so on.

it's unclear to me whether any plugins or core behaviors might have some dependencies on this value.

aduth suggested the use of resetBlocks, which I think could be viable in specific instances, but at the request of a particular plugin. To me, given the implications, and using your word-filtering example, it would also be viable to explicitly notify the user with something like: Your post has been saved with automated word filtering. You can [preview] the page or [refresh] the editor to see those edits.

spacedmonkey commented 5 years ago

I would say that, that the redraw only happen if two conditions are meet.

If there is a diff, a message is display. 'If seems like some code as changed the content of the post, do you wish need to refresh the page to see the changes' 'Refresh', 'Dismiss'.

This way, backwards compatibility is maintained. In the dev docs, we say that this message is bad and push developers to use JavaScript method to refresh.

metal450 commented 5 years ago

Seven months later: was this regression going to be addressed, or just ignored...?

meevly commented 4 years ago

It's a huge frustration trying to change the content on the backend on save... I think this should definitely be solved somehow.

dameBiz commented 3 years ago

hey guys, anyone has any solution or at least a workaround to this issue Githubissues.

  • Githubissues is a development platform for aggregating issues.