I have a simple terms page made up of heading and paragraph blocks. I’d like to filter the_content before output in order to get the content of any heading blocks and create a menu with links to named anchors at the top. Of course, by the time I filter the_content
passing $content
it’s already just a string of HTML, no block info.
How might I fetch an array of all the ‘blocked’ content in my the_content filter? Or is there a better way to achieve this that I’m missing?
EDIT
Or perhaps I should be running a filter on save rather than at output..?
Have you tried using parse_blocks()
(pass in get_the_content()
)? That returns an array of all the blocks in your content. From there you can pull out block names and id attributes using an array map or foreach.
Assuming you only want to pull anchor tags from the headings, you could do something like:
$blocks = parse_blocks( get_the_content() );
$block_ids = array();
function get_block_id( $block ) {
if ( $block['blockName'] !== 'core/heading' ) return;
$block_html = $block['innerHTML'];
$id_start = strpos( $block_html, 'id="' ) + 4;
if ( $id_start === false ) return;
$id_end = strpos( $block_html, '"', $id_start );
$block_id = substr( $block_html, $id_start, $id_end - $id_start );
return $block_id;
}
foreach( $blocks as $block ) {
$block_id = get_block_id( $block );
if ( $block_id ) array_push ( $block_ids, $block_id );
}