Skip to content

Commit

Permalink
Framework: Drop server-side block serialization, wpautop
Browse files Browse the repository at this point in the history
A parsed block has no awareness of where inner blocks exist in its innerHTML, so it cannot safely reserialize.

There are a few options:

- Since we merely skip wpautop for known blocks, we could avoid reserialization and return the block's original HTML verbatim if we had access to its outerHTML. See nylen/phpegjs#3

- Move wpautop behavior for freeform content to the editor client. This may align well with desires to transparently upgrade legacy paragraph content to paragraph blocks. This would also allow the server to avoid any preprocessing before showing a post on the front-end, assuming that the saved content has had wpautop applied already.

Acknowledging that this effectively reverts large parts of #2806
  • Loading branch information
aduth committed Jan 30, 2018
1 parent 0dbab97 commit 0869e44
Show file tree
Hide file tree
Showing 4 changed files with 0 additions and 256 deletions.
141 changes: 0 additions & 141 deletions lib/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,80 +70,6 @@ function gutenberg_parse_blocks( $content ) {
return $parser->parse( _gutenberg_utf8_split( $content ) );
}

/**
* Given an array of parsed blocks, returns content string.
*
* @since 1.7.0
*
* @param array $blocks Parsed blocks.
*
* @return string Content string.
*/
function gutenberg_serialize_blocks( $blocks ) {
return implode( '', array_map( 'gutenberg_serialize_block', $blocks ) );
}

/**
* Given a parsed block, returns content string.
*
* @since 1.7.0
*
* @param array $block Parsed block.
*
* @return string Content string.
*/
function gutenberg_serialize_block( $block ) {
// Return content of unknown block verbatim.
if ( ! isset( $block['blockName'] ) ) {
return $block['innerHTML'];
}

// Custom formatting for specific block types.
if ( 'core/more' === $block['blockName'] ) {
$content = '<!--more';
if ( ! empty( $block['attrs']['customText'] ) ) {
$content .= ' ' . $block['attrs']['customText'];
}

$content .= '-->';
if ( ! empty( $block['attrs']['noTeaser'] ) ) {
$content .= "\n" . '<!--noteaser-->';
}

return $content;
}

// For standard blocks, return with comment-delimited wrapper.
$content = '<!-- wp:' . $block['blockName'] . ' ';

if ( ! empty( $block['attrs'] ) ) {
$attrs_json = json_encode( $block['attrs'] );

// In PHP 5.4+, we would pass the `JSON_UNESCAPED_SLASHES` option to
// `json_encode`. To support older versions, we must apply manually.
$attrs_json = str_replace( '\\/', '/', $attrs_json );

// Don't break HTML comments.
$attrs_json = str_replace( '--', '\\u002d\\u002d', $attrs_json );

// Don't break standard-non-compliant tools.
$attrs_json = str_replace( '<', '\\u003c', $attrs_json );
$attrs_json = str_replace( '>', '\\u003e', $attrs_json );
$attrs_json = str_replace( '&', '\\u0026', $attrs_json );

$content .= $attrs_json . ' ';
}

if ( empty( $block['innerHTML'] ) ) {
return $content . '/-->';
}

$content .= '-->';
$content .= $block['innerHTML'];
$content .= '<!-- /wp:' . $block['blockName'] . ' -->';
return $content;
}

/**
* Renders a single block into a HTML string.
*
Expand Down Expand Up @@ -189,70 +115,3 @@ function do_blocks( $content ) {
return $content_after_blocks;
}
add_filter( 'the_content', 'do_blocks', 9 ); // BEFORE do_shortcode().

/**
* Given a string, returns content normalized with automatic paragraphs applied
* to text not identified as a block. Since this executes the block parser, it
* should not be used in a performance-critical flow such as content display.
* Block content will not have automatic paragraphs applied.
*
* @since 1.7.0
*
* @param string $content Original content.
* @return string Content formatted with automatic paragraphs applied
* to unknown blocks.
*/
function gutenberg_wpautop_block_content( $content ) {
$blocks = gutenberg_parse_blocks( $content );
foreach ( $blocks as $i => $block ) {
if ( isset( $block['blockName'] ) ) {
continue;
}

$content = $block['innerHTML'];

// wpautop will trim leading whitespace and return whitespace-only text
// as an empty string. Preserve to apply leading whitespace as prefix.
preg_match( '/^(\s+)/', $content, $prefix_match );
$prefix = empty( $prefix_match ) ? '' : $prefix_match[0];

$content = $prefix . wpautop( $content, false );

// To normalize as text where wpautop would not be applied, restore
// double newline to wpautop'd text if not at the end of content.
$is_last_block = ( count( $blocks ) === $i + 1 );
if ( ! $is_last_block ) {
$content = str_replace( "</p>\n", "</p>\n\n", $content );
}

$blocks[ $i ]['innerHTML'] = $content;
}

return gutenberg_serialize_blocks( $blocks );
}

/**
* Filters saved post data to apply wpautop to freeform block content.
*
* @since 1.7.0
*
* @param array $data An array of slashed post data.
* @return array An array of post data with wpautop applied to freeform
* block content.
*/
function gutenberg_wpautop_insert_post_data( $data ) {
if ( ! empty( $data['post_content'] ) && gutenberg_content_has_blocks( $data['post_content'] ) ) {
// WP_REST_Posts_Controller slashes post data before inserting/updating
// a post. This data gets unslashed by `wp_insert_post` right before
// saving to the DB. The PEG parser needs unslashed input in order to
// properly parse JSON attributes.
$content = wp_unslash( $data['post_content'] );
$content = gutenberg_wpautop_block_content( $content );
$content = wp_slash( $content );

$data['post_content'] = $content;
}

return $data;
}
add_filter( 'wp_insert_post_data', 'gutenberg_wpautop_insert_post_data' );
6 changes: 0 additions & 6 deletions lib/client-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -807,12 +807,6 @@ function gutenberg_editor_scripts_and_styles( $hook ) {
);
}

// Set initial content to apply autop on unknown blocks, preserving this
// behavior for classic content while otherwise disabling for blocks.
if ( ! $is_new_post && is_array( $post_to_edit['content'] ) ) {
$post_to_edit['content']['raw'] = gutenberg_wpautop_block_content( $post_to_edit['content']['raw'] );
}

// Set the post type name.
$post_type = get_post_type( $post );

Expand Down
78 changes: 0 additions & 78 deletions phpunit/class-serializing-test.php

This file was deleted.

31 changes: 0 additions & 31 deletions phpunit/class-wpautop-test.php

This file was deleted.

0 comments on commit 0869e44

Please sign in to comment.