我发现,在加载编辑器时,无法更改即将到来的数据。但之后可以替换数据。
JS: script.js
wp.domReady(function () {
const newData = window.myNewBlocksData;
if (newData) {
wp.data.dispatch(\'core/block-editor\').resetBlocks(wp.blocks.parse(newData));
console.log(\'replaced\');
}
})
PHP: <?php
class MyBlocksManipulation
{
public $prefix = \'my\';
public function __construct()
{
add_action(\'admin_enqueue_scripts\', [$this, \'modifyData\'], 999);
add_action(\'save_post\', [$this, \'markPostManipulationDone\'], 999, 3);
}
public function newDataType()
{
$screen = get_current_screen();
if (!(
$screen !== null &&
!empty($screen->is_block_editor) &&
!empty($screen->base) &&
$screen->base === \'post\'
)) {
return;
}
$currentPost = get_post();
$alreadyManipulated = get_post_meta($currentPost->ID, "{$this->prefix}_data_is_modified", true);
if (!empty($alreadyManipulated)) {
return;
}
$newData = wp_slash($this->modifyData());
wp_add_inline_script(\'wp-editor\', "var myNewBlocksData=`{$newData}`");
wp_enqueue_script(
\'my-data-manipulation\',
\'path/to/my/script.js\',
[\'wp-editor\'],
false,
true
);
}
public function modifyData()
{
$currentPost = get_post();
$content = $currentPost->post_content;
return preg_replace_callback("<!-- wp:(.*) ({(.*)}) \\/-->", function ($matches) {
if (!empty($matches[2])) {
$array = self::decode_block_attributes($matches[2]);
// ...
// Do something with this $array ...
// ...
$block = new WP_Block_Parser_Block($matches[1], $array, [], \'\', []);
$serialized = serialize_block((array)$block);
$serialized = trim($serialized, \'<>\');
return $serialized;
}
return "<$matches[0]>";
}, $content);
}
public static function is_json($item)
{
if (is_string($item)) {
$json = json_decode($item, true);
return is_array($json) && json_last_error() == JSON_ERROR_NONE;
}
return false;
}
public static function decode_block_attributes($item)
{
if (self::is_json($item) || is_array($item)) {
$json = is_array($item) ? $item : json_decode($item, true);
return $json;
}
return $item;
}
public function markPostManipulationDone($postId, $post, $update)
{
if (
!$update ||
$post->post_type === \'revision\' ||
!current_user_can(\'edit_post\', $postId)
) {
return $postId;
}
return update_post_meta($postId, "{$this->prefix}_data_is_modified", current_time(\'U\'));
}
}
new MyBlocksManipulation(); // Somwhere on top, before the theme or plugin content is rendered.