1

I'm building a new site and I wanted to build my theme from scratch. However, the WordPress ecosystem is moving more towards blocks and blockthemes. As far as I can tell, it is possible to put hooks (do_action(), apply_filters()) into a block theme, but it seems like I'd be making a weird hybrid. I don't want to only use HTML (including CSS and JS) when I build some of the pages; I really want to have places that I can hook PHP commands into. It's probably more correct to say that I have to use PHP for many of the site features and hooks are a great way to do it.

I haven't seen any hooks inside of blockthemes, so is there a good convention to follow for putting them in one? Or are blockthemes meant to avoid hooks altogether, in favor of blocks and shortcodes? Let's say that I wanted to have a banner at the top of the home page, but underneath the header that changes according to the user roles and current date (I've done that before by hooking into the top of the theme page). What is the best way to implement that in a block theme?

3
  • It turns out that "hybrid themes" are an actual thing suggested by WordPress: developer.wordpress.org/themes/block-themes/… Commented Jun 7, 2022 at 18:01
  • It often isn't useful to be concerned with the correct way of doing things. Make the site work the way you/client want it to work. There are a lot of variations on how to get PHP working anywhere you want in a block theme. Jacob Peattie's answer is a good lead. I won't share the solution I used out of legal concerns. Commented Jun 10, 2022 at 21:08
  • The render callbacks are great and with wp.blocks.registerBlockType() in JS and a little extra code in functions.php you can load blocks that are defined purely in PHP. The front end result is also super clean. For the save: part, just return null, because you'll replace it with PHP. Commented Jun 10, 2022 at 21:20

2 Answers 2

3

I'm not the most experienced in block themes, but from what I've seen of them so far I feel pretty confident in saying that the functionality you describe should be implemented as a block. But it's wrong to say that absolutely everything needs to be HTML and JS. There is still a place for PHP.

Let's say that I wanted to have a banner at the top of the home page, but underneath the header that changes according to the user roles and current date (I've done that before by hooking into the top of the theme page).

In this case the banner should be a custom block that can be added to any block area of a block theme. Twenty Twenty-Two has a Header area that might be appropriate, for example.

Such a block should render some kind of preview in the editor with JS, for performance reasons, but when you register the block you can define it as a dynamic block with a render_callback where you can use PHP logic to render the contents of the block on the front end. That callback would check the user role or date to determine what it renders.

Regarding hooks, those are definitely still relevant, and are still used for all sorts of things. They're just not particularly relevant for adding markup into themes, but since there was never any standardisation of hooks for themes they were never a great way to do this to begin with.

1

For Block Themes PHP I use register_block_style to setup selectable style variations, create custom shortcodes, and I filter render_block.

Here's a couple of PHP examples:

add_shortcode( 'ccom_shop_scripts', function( $atts ) {

    add_action( 'wp_print_footer_scripts', function() {

        ?>
        <script type="text/javascript">

        document.addEventListener( 'DOMContentLoaded', function() {
            alert( 'It works!' );
        } );

        </script>
        <?php

    } );

} );

After activating that code snippet, place that shortcode [ccom_shop_scripts] within a Block Template, Block Template Part, Block Post or Block Page and the code executes, can even return something inline if you wish.

add_filter( 'render_block', function( $block_content, $block ) {

    // Heading Blocks Only
    if( $block['blockName'] != 'core/heading' ) {
        return $block_content;
    }

    // Must Contain Merge Tag
    $merge_tag = '{{post_title}}';
    if( stristr( $block_content, $merge_tag ) === false ) {
        return $block_content;
    }

    // Try Archive Title
    $title = get_the_archive_title();
    if( $title == 'Archives' ) {

        // Try Post Title
        global $post;
        $title = isset( $post->post_title )
            ? $post->post_title : '';

    }

    // Return
    return $title
        ? str_replace( $merge_tag, $title, $block_content )
        : $block_content;

}, 10, 2 );

This is an example of a PHP merge tag for Heading Block elements.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.