Skip to content

Instantly share code, notes, and snippets.

@vyskoczilova
Last active May 13, 2021 15:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vyskoczilova/d0663cd7b3712d4fcdf3f289e4b8aca6 to your computer and use it in GitHub Desktop.
Save vyskoczilova/d0663cd7b3712d4fcdf3f289e4b8aca6 to your computer and use it in GitHub Desktop.
Enhanced has_block() function.

Enhanced has_block() snippet

Searching as well in reusable blocks (core's has_block() doesn't), see more in the blog post.

Author: Karolína Vyskočilová (karolina@kybernaut.cz)

Updated: 2021-04-12

Better performance if used multiple times withing a function (parses the content just once).

Usage:

  1. Include the class (and namespace / rename it accroding to your needs).
  2. Instantiate it: $helper = new BlockHelper();
  3. Use $helper->has_block('block/name') in your conditions ;)

Usage:

  1. Include both functions (and namespace / rename them accroding to your needs).
  2. Call enhanced_has_block('block/name) whenever you need to check.
<?php
// Do not copy the line above if you don't need it.
/**
* Has block function which searches as well in reusable blocks.
*
* Extends functionality of core's has_block (https://developer.wordpress.org/reference/functions/has_block/)
*
* @author Karolína Vyskočilová <karolina@kybernaut.cz>
* @since 2021-04-12
* @param mixed $block_name Full Block type to look for.
* @return bool
*/
function enhanced_has_block($block_name)
{
if (has_block($block_name)) {
return true;
}
if (has_block('core/block')) {
$content = get_post_field('post_content');
$blocks = parse_blocks($content);
return search_reusable_blocks_within_innerblocks($blocks, $block_name);
}
return false;
}
/**
* Search for selected block within inner blocks.
*
* The helper function for enhanced_has_block() function.
*
* @author Karolína Vyskočilová <karolina@kybernaut.cz>
* @since 2021-04-12
* @param array $blocks Blocks to loop through.
* @param string $block_name Full Block type to look for.
* @return bool
*/
function search_reusable_blocks_within_innerblocks($blocks, $block_name)
{
foreach ($blocks as $block) {
if (isset($block['innerBlocks']) && !empty($block['innerBlocks'])) {
search_reusable_blocks_within_innerblocks($block['innerBlocks'], $block_name);
} elseif ($block['blockName'] === 'core/block' && !empty($block['attrs']['ref']) && \has_block($block_name, $block['attrs']['ref'])) {
return true;
}
}
return false;
}
<?php
// Do not copy the line above if you don't need it.
/**
* Block Helper extending the functionality of core's has_blocks with search within inner blocks.
* @package WordPress
* @author Karolína Vyskočilová <karolina@kybernaut.cz>
* @since 2021-04-12
*/
class BlockHelper
{
private $blocks;
/**
* Has block implementation counting with reusable blocks
*
* @param string $block_name Full Block type to look for.
* @return bool
*/
public function has_block($block_name)
{
if (has_block($block_name)) {
return true;
}
$this->parse_reusable_blocks();
if (empty($this->blocks)) {
return false;
}
return $this->recursive_search_within_innerblocks($this->blocks, $block_name);
}
/**
* Search for a reusable block inside innerblocks
*
* @param array $blocks Blocks to loop through.
* @param string $block_name BFull Block type to look for.
* @return true|void
*/
private function recursive_search_within_innerblocks($blocks, $block_name)
{
foreach ($blocks as $block) {
if (isset($block['innerBlocks']) && !empty($block['innerBlocks'])) {
$this->recursive_search_within_innerblocks($block['innerBlocks'], $block_name);
} elseif ($block['blockName'] === 'core/block' && !empty($block['attrs']['ref']) && \has_block($block_name, $block['attrs']['ref'])) {
return true;
}
}
return false;
}
/**
* Parse blocks if at leat one reusable block is presnt.
*
* @return void
*/
private function parse_reusable_blocks()
{
if ($this->blocks !== null) {
return;
}
if (has_block('core/block')) {
$content = get_post_field('post_content');
$this->blocks = parse_blocks($content);
return;
}
$this->blocks = false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment