post_content; if ( suiko_builder_of( $post ) ) { // The builder renders its own data through the_content: the only faithful text is the rendered page. $html = apply_filters( 'the_content', $raw ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- WordPress's own filter. $html = preg_replace( '/<(script|style)\b[^>]*>.*?<\/\1>/is', '', $html ); if ( '' === trim( wp_strip_all_tags( (string) $html ) ) ) { // Elementor does not render outside its front end: read the text from its own data instead. $html = suiko_builder_text( $post ); } } elseif ( has_blocks( $raw ) ) { $html = do_blocks( $raw ); } else { $html = wpautop( $raw ); } return trim( suiko_strip_block_classes( $html ) ); } /** * Removes the classes the block editor adds for itself (wp-block-*, is-layout-*, has-*, wp-container-*, wp-elements-*): * Suiko works on the article, not on its presentation, and WordPress puts them back at render time. */ function suiko_strip_block_classes( $html ) { return preg_replace_callback( '/\sclass="([^"]*)"/', function ( $m ) { $keep = array_filter( preg_split( '/\s+/', trim( $m[1] ) ), function ( $c ) { return '' !== $c && ! preg_match( '/^(wp-block-|is-layout-|has-|wp-container-|wp-elements-|is-style-default$)/', $c ); } ); return $keep ? ' class="' . esc_attr( implode( ' ', $keep ) ) . '"' : ''; }, $html ); } /** Wraps each top-level HTML element into the matching core block. */ function suiko_html_to_blocks( $html ) { if ( ! class_exists( 'DOMDocument' ) ) { return "\n" . $html . "\n"; } $doc = new DOMDocument(); libxml_use_internal_errors( true ); $doc->loadHTML( '
' . $html . '
', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD ); libxml_clear_errors(); $root = $doc->getElementById( 'suiko-root' ); if ( ! $root ) { return "\n" . $html . "\n"; } $out = array(); foreach ( $root->childNodes as $node ) { if ( XML_TEXT_NODE === $node->nodeType ) { $text = trim( $node->textContent ); if ( '' !== $text ) { $out[] = "\n

" . esc_html( $text ) . "

\n"; } continue; } if ( XML_ELEMENT_NODE !== $node->nodeType ) { continue; } $out[] = suiko_element_to_block( $doc, $node ); } return implode( "\n\n", array_filter( $out ) ); } function suiko_outer_html( $doc, $node ) { return $doc->saveHTML( $node ); } function suiko_element_to_block( $doc, $node ) { $tag = strtolower( $node->nodeName ); $html = suiko_outer_html( $doc, $node ); switch ( $tag ) { case 'p': return "\n" . $html . "\n"; case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6': $level = (int) substr( $tag, 1 ); $attrs = 2 === $level ? '' : ' {"level":' . $level . '}'; $html = preg_replace( '/^<' . $tag . '(\s[^>]*)?>/', '<' . $tag . ' class="wp-block-heading"$1>', $html, 1 ); return "\n" . $html . "\n"; case 'ul': case 'ol': $items = array(); foreach ( $node->childNodes as $li ) { if ( XML_ELEMENT_NODE === $li->nodeType && 'li' === strtolower( $li->nodeName ) ) { $items[] = "\n" . suiko_outer_html( $doc, $li ) . "\n"; } } $attrs = 'ol' === $tag ? ' {"ordered":true}' : ''; $html = preg_replace( '/^<' . $tag . '(\s[^>]*)?>/', '<' . $tag . ' class="wp-block-list"$1>', $html, 1 ); $open = preg_replace( '/>.*$/s', '>', $html ); return "\n" . $open . "\n" . implode( "\n", $items ) . "\n\n"; case 'table': return "\n
" . $html . "
\n"; case 'blockquote': $html = preg_replace( '/^]*)?>/', '
', $html, 1 ); return "\n" . $html . "\n"; case 'figure': if ( $node->getElementsByTagName( 'table' )->length ) { return "\n" . $html . "\n"; } if ( $node->getElementsByTagName( 'img' )->length ) { return "\n" . $html . "\n"; } return "\n" . $html . "\n"; case 'img': return "\n
" . $html . "
\n"; case 'hr': return "\n
\n"; default: return "\n" . $html . "\n"; } }