Skip to content

Instantly share code, notes, and snippets.

@ockham
Last active April 9, 2024 13:16
Show Gist options
  • Save ockham/9a0a7d7bb6cb2428379d761a44b4768a to your computer and use it in GitHub Desktop.
Save ockham/9a0a7d7bb6cb2428379d761a44b4768a to your computer and use it in GitHub Desktop.
Hooked Blocks with Attributes
<?php
/**
* Plugin Name: Block Hooks with Attributes
* Description: Allow insertion of hooked blocks of the same type that are only differentiated by their attributes.
* Version: 0.1.0
* Requires at least: 6.5
*/
defined( 'ABSPATH' ) || exit;
// TODO: Maybe turn into filter?
function add_hooked_blocks_with_attributes(
$parsed_hooked_block,
$hooked_block_type,
$relative_position,
$parsed_anchor_block,
$context,
$container_block = array(
'blockName' => 'core/group',
'innerBlocks' => array(),
'innerContent' => array(
'<div class="wp-block-group">',
'</div>'
),
)
) {
$container_block_type = $container_block['blockName'];
$anchor_block_type = $parsed_anchor_block['blockName'];
$hooked_block_types = get_hooked_blocks();
/** This filter is documented in wp-includes/blocks.php */
$hooked_block_types = apply_filters( 'hooked_block_types', $hooked_block_types, $relative_position, $anchor_block_type, $context );
if ( ! in_array( $container_block_type, $hooked_block_types, true ) ) {
// add filter.
$add_container_block = function( $hooked_block_types, $_relative_position, $_anchor_block_type, $_context ) use (
$relative_position, $anchor_block_type, $context, $container_block_type
) {
// TODO: Fix $context check!
if ( $_relative_position === $relative_position && $_anchor_block_type === $anchor_block_type /* && $_context === $context */ ) {
$hooked_block_types[] = $container_block_type;
}
return $hooked_block_types;
};
add_filter( 'hooked_block_types', $add_container_block, 10, 4 );
}
$add_hooked_block = function( $_parsed_container_block, $_hooked_block_type, $_relative_position, $_parsed_anchor_block, $_context ) use (
$parsed_hooked_block, $hooked_block_type, $relative_position, $anchor_block_type, $context, $container_block
) {
$_anchor_block_type = $_parsed_anchor_block['blockName'];
// TODO: Fix $context check!
if ( $_relative_position === $relative_position && $_anchor_block_type === $anchor_block_type /* && $_context === $context */ ) {
if ( $container_block['blockName'] !== $_hooked_block_type || ! is_array( $_parsed_container_block ) ) {
return $_parsed_container_block;
}
if ( empty( $_parsed_container_block['innerContent'] ) ) {
$_parsed_container_block = array_replace_recursive( $_parsed_container_block, $container_block );
}
$_parsed_container_block['innerBlocks'][] = $parsed_hooked_block;
// Need to insert `null` placeholder into `innerContent` for newly added inner block.
$last_inner_content = array_pop( $_parsed_container_block['innerContent'] );
$_parsed_container_block['innerContent'][] = null;
$_parsed_container_block['innerContent'][] = $last_inner_content;
return $_parsed_container_block;
}
};
add_filter( 'hooked_block', $add_hooked_block, 10, 5 );
}
function add_social_icon_blocks() {
$wordpress_icon_block = array(
'blockName' => 'core/social-link',
'attrs' => array(
'service' => 'wordpress',
'url' => 'https://wordpress.org',
),
'innerContent' => array(),
);
$tumblr_icon_block = array(
'blockName' => 'core/social-link',
'attrs' => array(
'service' => 'tumblr',
'url' => 'https://tumblr.com',
),
'innerContent' => array(),
);
$anchor_block = array(
'blockName' => 'core/post-content',
);
$container_block = array(
'blockName' => 'core/social-links',
'innerContent' => array(
'<ul class="wp-block-social-links">',
'</ul>',
),
);
add_hooked_blocks_with_attributes( $wordpress_icon_block, 'core/social-link', 'after', $anchor_block, null, $container_block );
add_hooked_blocks_with_attributes( $tumblr_icon_block, 'core/social-link', 'after', $anchor_block, null, $container_block );
}
add_action( 'init', 'add_social_icon_blocks' );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment