bobbingwide / oik-clone

Clone content between sites
https://www.oik-plugins.com/oik-plugins/oik-clone-clone-your-wordpress-content/
GNU General Public License v2.0
5 stars 0 forks source link

Cloning an oik-css/geshi block containing wp:template part produced rubbish on the server #52

Closed bobbingwide closed 3 years ago

bobbingwide commented 3 years ago

I don't know what's to blame at present. I just know it happened. When I cloned my post to https://herbmiller.me/fizzie-an-experimental-full-site-editing-theme/ the oik-css/geshi blocks which contained HTML comments for template parts got completely messed up.

<div class="WP_DEBUG">front-page.html</div>
<!-- wp:template-part {"slug":"header","theme":"fizzie"} /-->
<!-- wp:template-part {"slug":"page-content","theme":"fizzie"} /-->
<!-- wp:template-part {"slug":"search","theme":"fizzie"} /-->
<!-- wp:template-part {"slug":"page-footer","theme":"fizzie"} /-->
<!-- wp:template-part {"slug":"footer","theme":"fizzie"} /-->
<!-- wp:template-part {"slug":"footer-menu","theme":"fizzie", "className": "footer-menu" } /-->

Workaround

Edit the post manually by copying and pasting the content and updating any IDs in the target.

bobbingwide commented 3 years ago

It would appear that the problem occurs during the reforming of the "content" attribute. In a simple test the source content was

<!-- wp:oik-css/geshi {"lang":"html","text":"oops 2242",
"content":"\u003c!\u002d\u002d wp:template-part 
{\u0022slug\u0022:\u0022header\u0022,\u0022theme\u0022:\u0022fizzie\u0022} /\u002d\u002d\u003e"} /-->

the cloned post's content became

<!-- wp:oik-css/geshi {"lang":"html","text":"oops 2242",
"content":"<!-- wp:template-part {\"slug\":\"header\",\"theme\":\"fizzie\"} /-->"} /-->

when loaded by the Block editor in Code editor mode this becomes

<!-- wp:oik-css/geshi /-->

<p>"} /--&gt;</p>

It appear that parts of the value of the "content" attribute should be converted to Unicode entities?

bobbingwide commented 3 years ago

In Gutenberg there's a JavaScript function called serializeAttributes

/**
 * Given an attributes object, returns a string in the serialized attributes
 * format prepared for post content.
 *
 * @param {Object} attributes Attributes object.
 *
 * @return {string} Serialized attributes.
 */
export function serializeAttributes( attributes ) {
    return (
        JSON.stringify( attributes )
            // Don't break HTML comments.
            .replace( /--/g, '\\u002d\\u002d' )

            // Don't break non-standard-compliant tools.
            .replace( /</g, '\\u003c' )
            .replace( />/g, '\\u003e' )
            .replace( /&/g, '\\u0026' )

            // Bypass server stripslashes behavior which would unescape stringify's
            // escaping of quotation mark.
            //
            // See: https://developer.wordpress.org/reference/functions/wp_kses_stripslashes/
            .replace( /\\"/g, '\\u0022' )
    );
}

Looks like we need a PHP equivalent of this function.

function serializeAttributes( $value ) {
   $result = str_replace( '\"', '\u0022', $value);
   $result = str_replace( '--', '\u002d\u002d', $result);
   $result = str_replace( '<', '\u003c', $result);
   $result = str_replace( '>', '\u003e', $result);
   $result = str_replace( '&', '\u0026', $result);
   return $result;
}