janboddez / share-on-mastodon

Easily share WordPress posts on Mastodon.
https://jan.boddez.net/wordpress/share-on-mastodon
GNU General Public License v3.0
39 stars 5 forks source link

Toot args filter gets custom field too late #115

Closed jsit closed 2 months ago

jsit commented 3 months ago

I've added this code to my theme's functions:

add_filter( 'share_on_mastodon_toot_args', function( $args, $post ) {
    $content_warning = get_post_meta( $post->ID, 'content_warning', true );
    $args['spoiler_text'] = $content_warning;
    return $args;
}, 10, 2);

I published a post "too quickly," where a draft had not been saved before hitting "Publish," and the filter didn't pick up on the content of the custom field. The post on Mastodon didn't get a content warning.

I converted to draft, unlinked the Mastodon post, published again, and it worked.

Is there something about the order in which custom fields are saved and this filter is applied that causes this filter to "miss" the custom field value?

janboddez commented 3 months ago

That would be Gutenberg's doing. It publishes posts before it processes custom fields in a second POST request (i.e., to the server) a split second later.

The only way around this is to (1) save a draft first, to explicitly store the custom field value before publishing, or (2) force the plugin to use the "classic" meta box, or (3) not rely on the custom fields panel, but instead use a custom Gutenberg sidebar plugin (i.e., code one in JS) to set the meta fields along with the first POST request.

If you use the "classic" meta box (check the plugin's settings), the plugin should wait until custom fields are processed (because the classic meta box itself also sets and relies on a custom field).

If you use the Share on Mastodon's built-in "Gutenberg" panel (the default for Gutenberg sites), the plugin has no way of knowing it "should wait" for custom fields. In fact, if no "custom fields" or "classic" meta boxes are used, there would not be a second POST request and POSSE'ing would be skipped altogether. Yeah, it's confusing.

janboddez commented 3 months ago

Added a link to an earlier post of mine where I tried to describe what's going on:

Gutenberg does what it does, and then fires a “second” AJAX request to deal with (and submit) meta boxes’ $_POST variables.

This causes some, uh, weird behavior. Like, a post will already have been published/updated/etc. [before] its “meta fields” are available to the back end.

Likewise, when the custom fields panel's open, any meta value set through a "proper" Gutenberg panel will be overwritten by the "old" value in the custom fields panel. (Which is why some plugins force-hide it when the block editor is in use. 🙃)

And so on.

Either way, forcing the plugin to use the "old" meta box is probably your best bet here.

janboddez commented 3 months ago

Either way, forcing the plugin to use the "old" meta box is probably your best bet here.

Another workaround would be to, in your callback function, map tags (these do get set, again, by Gutenberg, after the post is published but before POSSE'ing happens, so tags oughta be "safe") or something to a CW.

janboddez commented 3 months ago

Oh, another thing you could do, other than use the "classic" meta box option, is set a post "delay" (under the plugin's advanced settings). A delay of a couple seconds should already be enough, but you could set it to like 30 or so, err on the side of caution and all.

Although the "classic" meta box option would be even safer.