Skip to content

Instantly share code, notes, and snippets.

@morvy
Last active June 11, 2023 16:00
Show Gist options
  • Save morvy/0c19ed7265d76d32af3c4fb99efa7d75 to your computer and use it in GitHub Desktop.
Save morvy/0c19ed7265d76d32af3c4fb99efa7d75 to your computer and use it in GitHub Desktop.
Converts [some] WP Bakery shortcodes into Gutenberg blocks
<?php
// load wp
require_once( dirname( __FILE__ ) . '/wp-load.php' );
// get post content by ID
if (empty($_GET['id'])) {
die('ID is empty');
}
$id = $_GET['id'];
$post = get_post( $id );
// get post content
$content = $post->post_content;
// remove first vc_row and vc_column
$content = preg_replace( '/\[vc_row\]/', '', $content, 1 );
$content = preg_replace( '/\[vc_column\]/', '', $content, 1 );
$content = str_replace( '<p>[vc_column_text]</p>', '', $content );
$content = str_replace( '<p>[/vc_column_text]', '', $content );
$content = str_replace( '[vc_column_text]</p>', '', $content );
$content = preg_replace( '/^\s+/', '', $content );
// remove style="text-align: justify;" from p tag
$content = preg_replace( '/<p style="text-align: justify;">/', '<p>', $content );
$content = preg_replace( '/<p style="text-align: center;">/', '<p class="has-text-align-center">', $content );
// remove last vc_column and vc_row
// remove non-word characters from the end of string
$content = preg_replace( '/\s+$/', '', $content );
$content = preg_replace( '/\[\/vc_column\]\[\/vc_row\]<\/p>$/', '', $content, 1 );
// convert highlighted block to highlighted group
$content = preg_replace( '/\[vc_row_inner.*?highlighted-row.*?\]\[vc_column_inner\]([\s\S]*?)\[\/vc_column_inner\]\[\/vc_row_inner\]/', '<!-- wp:group {"backgroundColor":"palette-color-6","layout":{"type":"constrained"}} -->'.PHP_EOL.'<div class="wp-block-group has-palette-color-6-background-color has-background">$1</div><!-- /wp:group -->', $content );
// remove empty p tag
$content = preg_replace( '/<p><\/p>/', '', $content );
$content = preg_replace( '/\[vc_column_text\]/', '', $content );
$content = preg_replace( '/\[\/vc_column_text\]/', '', $content );
// convert more tag to gutenberg
$content = preg_replace( '/<!--more-->/', '<!-- wp:more -->'."\n".'<!--more-->'."\n".'<!-- /wp:more -->'."\n", $content );
$content = preg_replace( '/<p><!--more--><\/p>/', '<!-- wp:more -->'."\n".'<!--more-->'."\n".'<!-- /wp:more -->'."\n", $content );
// convert vc_inner_column to gutenberg column
$content = preg_replace( '/\[vc_column_inner width="1\/6"\]/', '<!-- wp:column {"verticalAlignment":"center","width":"15%"} -->'."\n".'<div class="wp-block-column is-vertically-aligned-center" style="flex-basis:15%">'."\n", $content );
$content = preg_replace( '/\[vc_column_inner width="1\/4"\]/', '<!-- wp:column {"width":"25%"} -->'."\n".'<div class="wp-block-column" style="flex-basis:25%">'."\n", $content );
$content = preg_replace( '/\[vc_column_inner width="3\/4"\]/', '<!-- wp:column -->'."\n".'<div class="wp-block-column">', $content );
$content = preg_replace( '/\[vc_column_inner width="5\/6"\]/', '<!-- wp:column -->'."\n".'<div class="wp-block-column">', $content );
$content = preg_replace( '/\[\/vc_column_inner\]/', '</div>'.'<!-- /wp:column -->'."\n", $content );
// trim all WP Bakery row, column
$content = preg_replace( '/\[vc_row\]/', '', $content );
$content = preg_replace( '/\[\/vc_row\]/', '', $content );
$content = preg_replace( '/\[vc_column\]/', '', $content );
$content = preg_replace( '/\[\/vc_column\]/', '', $content );
$content = preg_replace( '/\[vc_row_inner\]/', '<!-- wp:columns -->'.PHP_EOL.'<div class="wp-block-columns">', $content );
$content = preg_replace( '/\[\/vc_column_inner\]/', '', $content );
// $content = preg_replace( '/\[vc_row_inner.*?\]/', '', $content );
$content = preg_replace( '/\[\/vc_row_inner\]/', '</div>'.PHP_EOL.'<!-- /wp:columns -->', $content );
// remove p tag around img tag and shortcode
$content = preg_replace( '/<p>\[/', '[', $content );
$content = preg_replace( '/\]<\/p>/', ']', $content );
// convert vc_column_text to gutenberg paragraph
$content = preg_replace( '/\[vc_column_text\]/', '<!-- wp:paragraph -->'."\n".'<p>', $content );
$content = preg_replace( '/\[\/vc_column_text\]/', '</p>'."\n".'<!-- /wp:paragraph -->'."\n", $content );
// wrap p tag with <!-- wp:paragraph -->
$content = preg_replace( '/<p(.*?)>/', '<!-- wp:paragraph -->'."\n".'<p$1>', $content );
$content = preg_replace( '/<\/p>/', '</p>'."\n".'<!-- /wp:paragraph -->'."\n", $content );
// convert vc_btn to gutenberg button
$content = preg_replace_callback( '/\[vc_btn title="(.+?)".*?align="(.+?)" link="url\:(.+?)\|title.*?".*?\]/', function( $matches) {
return replace_btn_with_buttons_group($matches[1], $matches[2], $matches[3]);
}, $content );
// convert vc_icon to gutenberg icon
$content = preg_replace_callback( '/\[vc_icon icon_fontawesome="fas? fa-(.+?)".*?\]/', function( $matches ) {
return replace_icon_with_placeholder($matches[1]);
}, $content );
// convert woo products to gutenberg products
$content = preg_replace_callback( '/\[products.+?ids="(.*?)"\]/', function( $matches ) {
return woo_products_to_gutenberg_block($matches[1]);
}, $content );
// convert gallery to gutenberg gallery
$content = preg_replace_callback( '/\[vc_gallery.*?images="(.*?)".*?\]/', function( $matches ) {
return gallery_to_gutenberg_block($matches[1]);
}, $content );
// convert blockquote tu Gutenberg
$content = preg_replace( '/<blockquote>/', '<!-- wp:quote -->'."\n".'<blockquote class="wp-block-quote">', $content );
$content = preg_replace( '/<\/blockquote>/', '</blockquote>'."\n".'<!-- /wp:quote -->'."\n", $content );
// <h2 style="text-align: center;">
// <h2 class="has-text-align-center">
// convert h2, h3, h4 from style to class like above
$content = preg_replace( '/<h2 style="text-align: (\w+);">/', '<!-- wp:heading {"textAlign":"$1"} -->'."\n".'<h2 class="has-text-align-$1">', $content );
$content = preg_replace( '/<h3 style="text-align: (\w+);">/', '<!-- wp:heading {"textAlign":"$1","level":3} -->'."\n".'<h3 class="has-text-align-$1">', $content );
$content = preg_replace( '/<h4 style="text-align: (\w+);">/', '<!-- wp:heading {"textAlign":"$1","level":4} -->'."\n".'<h4 class="has-text-align-$1">', $content );
// wrap h2 tag with <!-- wp:heading -->
// $content = preg_replace( '/<h2/', '<!-- wp:heading -->'."\n".'<h2', $content );
$content = preg_replace( '/<\/h2>/', '</h2>'."\n".'<!-- /wp:heading -->'."\n", $content );
// wrap h3 tag with <!-- wp:heading -->
// $content = preg_replace( '/<h3/', '<!-- wp:heading -->'."\n".'<h3', $content );
$content = preg_replace( '/<\/h3>/', '</h3>'."\n".'<!-- /wp:heading -->'."\n", $content );
// wrap h4 tag with <!-- wp:heading -->
// $content = preg_replace( '/<h4/', '<!-- wp:heading -->'."\n".'<h4', $content );
$content = preg_replace( '/<\/h4>/', '</h4>'."\n".'<!-- /wp:heading -->'."\n", $content );
// remove spans like this <span style="color: #9c6b27;">
$content = preg_replace( '/<span style="color: #\w+;">(.*?)<\/span>/', '$1', $content );
// convert WP Bakery image to figure, shorcode has image as ID, img_size as size and alignment as class
$content = preg_replace_callback( '/\[vc_single_image.*?image="(\d+)".*?img_size="(\w+)".*?alignment="(\w+)"\]/', function($matches) {
return img_id_to_figure($matches[1], $matches[2], $matches[3]);
}, $content );
// remove space before closing img tag
$content = preg_replace( '/\s+\/>/', '/>', $content );
// remove p tag around comments
// $content = preg_replace( '/<p><!--(.*?)--><\/p>/', '<!-- $1 -->', $content );
// show post content including formatting
// echo '<pre>';
echo $content;
// echo '</pre>';
// create image figure as html
function img_id_to_figure( $id, $size = 'full', $class = '' ) {
$image = wp_get_attachment_image_url( $id, $size );
$output = '';
if ($image) {
$className = '';
if ($class) {
$className = ',"className":"align'.$class.'"';
$class = ' align'.$class;
}
$output .= '<!-- wp:image {"id":'.$id.',"sizeSlug":"'.$size.'","linkDestination":"none"'.$className.'} -->'.PHP_EOL;
$output .= '<figure class="wp-block-image size-'.$size.$class.'">';
$alt = get_post_meta( $id, '_wp_attachment_image_alt', true );
$output .= '<img src="'.$image.'" alt="'.$alt.'" class="wp-image-'.$id.'" />';
// get image caption
$caption = get_post_field( 'post_excerpt', $id );
if ($caption) {
$output .= '<figcaption class="wp-element-caption"><em>'.$caption.'</em></figcaption>';
}
$output .= '</figure>'.PHP_EOL;
$output .= '<!-- /wp:image -->'.PHP_EOL;
return $output;
}
return '';
}
function replace_icon_with_placeholder($icon = '', $text = '') {
$output = '';
// get post by title
$icon_post = get_page_by_title( $icon, OBJECT, 'attachment' );
if (!$icon_post) {
$icon_id = '';
} else {
$icon_id = $icon_post->ID;
}
$output .= '<!-- wp:acf/icons {"name":"acf/icons","data":{"field_6212bffdf3506":"'.$icon_id.'","field_62141e83b0622":"square","field_628d5fcbc90ac":"3"},"align":"center","mode":"preview","textColor":"palette-color-1"} /-->'.PHP_EOL;
return $output;
}
function woo_products_to_gutenberg_block($matches) {
$output = '';
if (empty($matches)) return '';
$products = explode(',', $matches);
$products = array_map('trim', $products);
$products = array_reverse($products);
$ids = '"'.implode('","', $products).'"';
$output = '<!-- wp:acf/products {"name":"acf/products","data":{"field_61d20b6402aab":['.$ids.'],"field_629f2a2500447":"","field_62a5e7d5b7192":"","field_62a60f5370bb7":"AND","field_61d20c3802aac":"","field_620989b2ca45e":"4","field_61d20c6002aad":"post__in","field_61d20cf102aae":"ASC","field_61d20d5f02aaf":["action","title","icons","desc"]},"mode":"edit"} /-->'.PHP_EOL;
return $output;
}
function replace_btn_with_buttons_group($title, $align, $link) {
$output = '';
if (empty($title)) return '';
$output = '<!-- wp:buttons -->'.PHP_EOL;
$output .= '<div class="wp-block-buttons"><!-- wp:button {"align":"'.$align.'"} -->'.PHP_EOL;
$output .= '<div class="wp-block-button align'.$align.'"><a class="wp-block-button__link wp-element-button" href="'.$link.'">'.$title.'</a></div>'.PHP_EOL;
$output .= '<!-- /wp:button --></div>'.PHP_EOL;
$output .= '<!-- /wp:buttons -->'.PHP_EOL;
return $output;
}
function gallery_to_gutenberg_block($matches) {
$output = '';
if (empty($matches)) return '';
$ids = explode(',', $matches);
$ids = array_map('trim', $ids);
$ids = array_reverse($ids);
$ids = '"'.implode('","', $ids).'"';
$output = '<!-- wp:acf/slider {"name":"acf/slider","data":{"field_6031a4d4d7429":['.$ids.'],"field_6031a507d742a":"1","field_6031a9eb88e80":"3/2","field_603296216a9b2":"1","field_603296696a9b3":"1","field_6032968f6a9b4":"5"},"mode":"edit"} /-->'.PHP_EOL;
return $output;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment