首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Gutenberg块操作:用parse_blocks()撤销serialize_blocks()会导致unicode问题

Gutenberg块操作:用parse_blocks()撤销serialize_blocks()会导致unicode问题
EN

WordPress Development用户
提问于 2021-07-03 14:57:55
回答 1查看 1.3K关注 0票数 4

我想用PHP操作Gutenberg块。因此,我需要将post_content解析为数组,并在操作后以相同的方式返回。但我没有走那么远,因为来回解析已经不起作用了。

代码语言:javascript
复制
function change_post_data_before_save( $data, $postarr ) {
    $post_data = $data['post_content']; //post_content seems to be json encoded 
    //stripping slashes otherwise $blocks[0]['attrs'] would be NULL
    $post_data = str_replace('\\"', '"', $post_data);
    //trying to replace double slash in unicodes but it seems not to work
    $post_data = str_replace('\\\u', '\u', $post_data);
    $blocks = parse_blocks($post_data); //there are still some issues with schema and other array parts

    //manipulation of $blocks if needed

    $post_content = serialize_blocks( $blocks ); //seems to work correct
    $data['post_content'] = $post_content;

    return $data;
}
add_filter( 'wp_insert_post_data', 'change_post_data_before_save', 10, 2 );

有什么想法吗?如何在不破坏$data中需要json编码的部分的情况下解码$blocks?我尝试了替换,但它似乎不适用于独角兽,而serialize_blocks()最终摧毁了它。

示例代码:

代码语言:javascript
复制
//expected result - saved in database without wp_insert_post_data (see above)

{"@context":"https://schema.org","@type":"FAQPage","@id":"http://localhost/specials/gutenberg/","mainEntity":[{"@type":"Question","name":"Headline with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)","acceptedAnswer":{"@type":"Answer","text":"This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)"}}]}
Headline with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)




This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)

调试:

代码语言:javascript
复制
//result of $data['post_content']

{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"FAQPage\\",\\"@id\\":\\"http://localhost/specials/gutenberg/\\",\\"mainEntity\\":[{\\"@type\\":\\"Question\\",\\"name\\":\\"Headline with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)\\",\\"acceptedAnswer\\":{\\"@type\\":\\"Answer\\",\\"text\\":\\"This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)\\"}}]}
Headline with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)




This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)
代码语言:javascript
复制
//result of $post_data

{"@context":"https://schema.org","@type":"FAQPage","@id":"http://localhost/specials/gutenberg/","mainEntity":[{"@type":"Question","name":"Headline with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)","acceptedAnswer":{"@type":"Answer","text":"This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)"}}]}
Headline with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)




This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)
代码语言:javascript
复制
//result of $blocks
array (
  0 => 
  array (
    'blockName' => 'uagb/faq',
    'attrs' => 
    array (
      'block_id' => 'f1ad85bc',
      'enableSchemaSupport' => true,
      'schema' => '{"@context":"https://schema.org","@type":"FAQPage","@id":"http://localhost/specials/gutenberg/","mainEntity":[{"@type":"Question","name":"Headline with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)","acceptedAnswer":{"@type":"Answer","text":"This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)"}}]}',
    ),
    'innerBlocks' => 
    array (
      0 => 
      array (
        'blockName' => 'uagb/faq-child',
        'attrs' => 
        array (
          'block_id' => '61cac9b0',
          'question' => 'Headline with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)',
          'answer' => 'This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)',
        ),
        'innerBlocks' => 
        array (
        ),
        'innerHTML' => '
Headline with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)
',
        'innerContent' => 
        array (
          0 => '
Headline with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)
',
        ),
      ),
    ),
    'innerHTML' => '
{"@context":"https://schema.org","@type":"FAQPage","@id":"http://localhost/specials/gutenberg/","mainEntity":[{"@type":"Question","name":"Headline with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)","acceptedAnswer":{"@type":"Answer","text":"This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)"}}]}
',
    'innerContent' => 
    array (
      0 => '
{"@context":"https://schema.org","@type":"FAQPage","@id":"http://localhost/specials/gutenberg/","mainEntity":[{"@type":"Question","name":"Headline with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)","acceptedAnswer":{"@type":"Answer","text":"This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)"}}]}',
      1 => NULL,
      2 => '
',
    ),
  ),
  1 => 
  array (
    'blockName' => NULL,
    'attrs' => 
    array (
    ),
    'innerBlocks' => 
    array (
    ),
    'innerHTML' => '

',
    'innerContent' => 
    array (
      0 => '

',
    ),
  ),
  2 => 
  array (
    'blockName' => 'kadence/iconlist',
    'attrs' => 
    array (
      'items' => 
      array (
        0 => 
        array (
          'icon' => 'fe_alertCircle',
          'link' => '',
          'target' => '_self',
          'size' => 20,
          'width' => 2,
          'text' => 'This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)',
          'color' => '',
          'background' => '',
          'border' => '',
          'borderRadius' => 0,
          'padding' => 5,
          'borderWidth' => 1,
          'style' => 'default',
        ),
      ),
      'uniqueID' => '_a79c18-e7',
    ),
    'innerBlocks' => 
    array (
    ),
    'innerHTML' => '
This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)
',
    'innerContent' => 
    array (
      0 => '
This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)
',
    ),
  ),
)

Serialize_blocks()之后的最终结果:

代码语言:javascript
复制
//result of $post_content [can not be shown in Gutenberg UI "This block contains unexpected or invalid content."]

{"@context":"https://schema.org","@type":"FAQPage","@id":"http://localhost/specials/gutenberg/","mainEntity":[{"@type":"Question","name":"Headline with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)","acceptedAnswer":{"@type":"Answer","text":"This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)"}}]}
Headline with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)




This is a test with special characters: (°C, ä, ö, ü, ß, Ö, Ä, Ü)

相关话题:串行化_块破坏内容中的html标记。

EN

回答 1

WordPress Development用户

发布于 2021-07-04 12:55:06

正如注释中已经描述的,许多WordPress Gutenberg插件并不像WordPress所规定的那样使用严格的JSON格式.(文件记录不全)因此出现了两个问题:

  • 有时,数据是JSON格式的,parse_blocks()无法读取这种格式。例如,如果这里没有进行任何更改,则attr值将为空(例如在第一篇文章中)。
  • serialize_blocks()将所有特殊字符转换为Unicode,这将导致插件块停止正常工作,并导致Gutenberg中的错误消息:“此块包含意外或无效的内容”。

特别是对于插件高级-古登堡和卡登斯-块,bug已经被报道。我已经开发了以下的解决方法,这是快速和肮脏的,但它的工作。如果有人有意见,增加或改进,请让我知道!

代码语言:javascript
复制
function change_post_data_before_save( $data ) {
    $post_data = $data['post_content'];
    $post_data = str_replace('\\"', '"', $post_data); //parse_blocks() need " to parse $blocks[]['attr'] correctly

    $blocks = parse_blocks($post_data);
    $post_content = implode( '', array_map( 'serialize_block2', $blocks ) ); //serialize_block() replacement because serialize_block_attributes() does not support JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE

    $post_content = str_replace('"', '\\"', $post_content); //undo " correction from above
    $data['post_content'] = $post_content;

    return $data;
}
add_filter( 'wp_insert_post_data', 'change_post_data_before_save', 10, 2 );


//only sub method calls has been changed
function serialize_block2( $block ) {
    $block_content = '';

    $index = 0;
    foreach ( $block['innerContent'] as $chunk ) {
        $block_content .= is_string( $chunk ) ? $chunk : serialize_block2( $block['innerBlocks'][ $index++ ] ); //change
    }

    if ( ! is_array( $block['attrs'] ) ) {
        $block['attrs'] = array();
    }

    return get_comment_delimited_block_content2(
        $block['blockName'],
        $block['attrs'],
        $block_content
    );
}


//only sub method calls has been changed
function get_comment_delimited_block_content2( $block_name, $block_attributes, $block_content ) {
    if ( is_null( $block_name ) ) {
        return $block_content;
    }

    $serialized_block_name = strip_core_block_namespace( $block_name );
    $serialized_attributes = empty( $block_attributes ) ? '' : serialize_block_attributes2( $block_attributes ) . ' '; //change

    if ( empty( $block_content ) ) {
        return sprintf( '', $serialized_block_name, $serialized_attributes );
    }

    return sprintf(
        '%s',
        $serialized_block_name,
        $serialized_attributes,
        $block_content,
        $serialized_block_name
    );
}


//change gutenberg json_encoding to keep plugin block formats and prevent issue "This block contains unexpected or invalid content."
function serialize_block_attributes2( $block_attributes ) {
    $encoded_attributes = json_encode( $block_attributes, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ); //change
    $encoded_attributes = preg_replace( '/--/', '\\u002d\\u002d', $encoded_attributes );
    $encoded_attributes = preg_replace( '//', '\\u003e', $encoded_attributes );
    $encoded_attributes = preg_replace( '/&/', '\\u0026', $encoded_attributes );
    // Regex: /\\"/
    $encoded_attributes = preg_replace( '/\\\\"/', '\\u0022', $encoded_attributes );

    return $encoded_attributes;
}
票数 1
EN
页面原文内容由WordPress Development提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://wordpress.stackexchange.com/questions/391381

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档