Skip to content

Instantly share code, notes, and snippets.

@JiveDig
Last active August 19, 2022 16:25
Show Gist options
  • Save JiveDig/6b0245a41766280433e38a15873a9a6a to your computer and use it in GitHub Desktop.
Save JiveDig/6b0245a41766280433e38a15873a9a6a to your computer and use it in GitHub Desktop.
Gets a formatted array of block data from post content for use in the `template` parameter of `register_post_type()` function. This is used for a predefined block template for a post type.
<?php
/**
* Dump the data.
*/
add_action( 'wp_footer', function() {
// Get the data.
$parsed = jivedig_get_parsed_blocks_for_template();
// Dump however you'd like.
var_dump( $parsed );
});
/**
* Gets parsed blocks for `template` parameter of `register_post_type()`.
*
* @version 1.0.0
*
* @return array
*/
function jivedig_get_parsed_blocks_for_template() {
global $post;
$blocks = parse_blocks( $post->post_content );
$blocks = jivedig_parse_blocks_for_template( $blocks );
return $blocks;
}
/**
* Parses blocks to be used in the `template` parameter of `register_post_type()`.
*
* @version 1.0.0
*
* @param array $blocks The blocks array from `parse_blocks()` function.
*
* @return array
*/
function jivedig_parse_blocks_for_template( $blocks ) {
$parsed = [];
if ( ! $blocks ) {
return $parsed;
}
foreach ( $blocks as $key => $values ) {
$name = $values['blockName'];
$atts = $values['attrs'];
$inner = isset( $values['innerBlocks'] ) ? jivedig_parse_blocks_for_template( $values['innerBlocks'] ) : [];
// Bail if not block.
if ( is_null( $name ) ) {
continue;
}
// Set default content.
if ( in_array( $name, [ 'core/heading', 'core/paragraph' ] ) && isset( $values['innerHTML'] ) && $values['innerHTML'] ) {
$atts['content'] = jivedig_get_first_child_inner_html( $values['innerHTML'] );
}
// Lock all blocks.
$atts['template_lock'] = [
'move' => in_array( $name, [ 'core/paragraph' ] ),
'remove' => in_array( $name, [ 'core/paragraph' ] ),
];
// If ACF block.
if ( isset( $atts['data'] ) ) {
// Temp store data.
$data = $atts['data'];
// Remove unused attributes from ACF.
unset( $atts['data'] );
unset( $atts['id'] );
unset( $atts['name'] );
// Remove _field key references from ACF.
foreach ( $data as $data_key => $data_value ) {
if ( ! ( is_string( $data_key ) && str_starts_with( $data_key, '_' ) ) ) {
continue;
}
unset( $data[ $data_key ] );
}
// Merge with existing atts.
$atts = array_merge( $atts, $data );
}
$parsed[] = [ $name, $atts, $inner ];
}
return $parsed;
}
/**
* Gets a DOMDocument first child element.
*
* @version 1.0.0
*
* @param string $html Any given HTML string.
*
* @return DOMElement $first_block The group block container.
*/
function jivedig_get_first_child_inner_html( $html ) {
$dom = jivedig_get_dom_document( $html );
$first = $dom->childNodes->item(0);
$inner = $first ? $first->childNodes->item(0) : '';
return $inner ? $inner->ownerDocument->saveHTML( $inner ) : '';
}
/**
* Gets DOMDocument object.
*
* @version 1.0.0
*
* @param string $html Any given HTML string.
*
* @return DOMDocument
*/
function jivedig_get_dom_document( $html ) {
// Create the new document.
$dom = new DOMDocument();
// Modify state.
$libxml_previous_state = libxml_use_internal_errors( true );
// Load the content in the document HTML.
$dom->loadHTML( mb_convert_encoding( $html, 'HTML-ENTITIES', 'UTF-8' ) );
// Remove <!DOCTYPE.
$dom->removeChild( $dom->doctype );
// Remove <html><body></body></html>.
$dom->replaceChild( $dom->firstChild->firstChild->firstChild, $dom->firstChild );
// Handle errors.
libxml_clear_errors();
// Restore.
libxml_use_internal_errors( $libxml_previous_state );
return $dom;
}
/**
* PHP 8 polyfill for older versions of PHP.
*
* @source Laravel Framework
* @link https://github.com/laravel/framework/blob/8.x/src/Illuminate/Support/Str.php
*/
if ( ! function_exists( 'str_starts_with' ) ) {
function str_starts_with( $haystack, $needle ) {
return (string) $needle !== '' && strncmp( $haystack, $needle, strlen( $needle ) ) === 0;
}
}
<?php
/**
* Register custom post type.
*
* @return void
*/
add_action( 'init', function() {
register_post_type( 'thing',
[
// Other
// attributes
// here.
'template' => [
[
'core/group',
[
'align' => 'full',
'contentWidth' => 'xl',
'contentAlign' => 'center',
'verticalSpacingTop' => 'lg',
'verticalSpacingBottom' => 'lg',
'backgroundColor' => 'alt',
'template_lock' => [
'move' => false,
'remove' => false,
],
],
[
[
'core/heading',
[
'content' => 'Descriptive heading',
'template_lock' => [
'move' => false,
'remove' => false,
],
],
[],
],
[
'core/paragraph',
[
'className' => 'is-style-heading',
'content' => 'Default text',
'template_lock' => [
'move' => true,
'remove' => true,
],
],
[],
],
],
]
],
]
);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment