PHPackages                             gebruederheitz/wp-block-updater - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. gebruederheitz/wp-block-updater

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

gebruederheitz/wp-block-updater
===============================

Update dynamic blocks with innerBlocks

2.0.2(2y ago)0331[6 PRs](https://github.com/gebruederheitz/wp-block-updater/pulls)GPL-3.0-onlyPHPPHP &gt;=7.4

Since Jul 6Pushed 2y agoCompare

[ Source](https://github.com/gebruederheitz/wp-block-updater)[ Packagist](https://packagist.org/packages/gebruederheitz/wp-block-updater)[ RSS](/packages/gebruederheitz-wp-block-updater/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (4)Dependencies (4)Versions (18)Used By (0)

Wordpress Block Updater
=======================

[](#wordpress-block-updater)

*Update dynamic blocks with innerBlocks*

---

Moving from a React-rendered "static" Gutenberg block *(where the block editor's `save()` method returns the markup for the block which gets rendered once and written as static HTML to the post content)* to a "dynamic" block *(which is rendered by PHP)* is trivial. Instead of having save() return the markup, we make it return `null` and let PHP templates handle the block's frontend output. But there's once exception: When the affected block contains "innerBlocks", their rendering will often still have to be handled by Gutenberg &amp; React, so we simply return `` from save() – which will result in invalid blocks, as all existing blocks still contain the full markup, not just the innerBlocks. This package offers a REST interface to update such blocks across posts along with an admin page allowing to run batched updates for all published posts.

> **Warning**
>
> This is not a generic block updater; it will only work correctly for exactly the task described above: Performing a migration of a statically rendered block with innerBlocks to a dynamic block.
>
> Running this tool on a static block will make that block's markup disappear (partially or completely) from your Wordpress frontend!

Running the tool against a dynamic block with no innerBlocks will have no effect.

Installation
------------

[](#installation)

via composer:

```
> composer require gebruederheitz/wp-theme-docs
```

Make sure you have Composer autoload or an alternative class loader present.

Usage
-----

[](#usage)

Instantiate the BlockUpdater, for example in your `functions.php`, passing it an array of qualifying blocks (i.e. those that have moved from static to dynamic rendering):

```
new \Gebruederheitz\Wordpress\BlockUpdater\BlockUpdater(
    ['mynamespace/myblock']
);
```

Now navigate to wordpress/wp-admin/tools.php?page=ghwp-block-updater, select a block and click "Start" in order to loop over all published posts of types `page` and `post` and re-render the block content of the selected block if it exists.

Example Scenario
----------------

[](#example-scenario)

### Before

[](#before)

```
registerBlockType('my/block', {
    title: 'My Block',
    icon: 'someicon',
    description: '...',
    category: 'layout',
    styles: [/*...*/],
    attributes: {/*...*/},
    edit(props) {
        /* ... */
        return ;
    },
    /* A React-rendered (static) block with innerBlocks */
    save(props) {
        return (

                {props.attributes.title}

        );
    },
});
```

### Now

[](#now)

```
registerBlockType('my/block', {
    title: 'My Block',
    icon: 'someicon',
    description: '...',
    category: 'layout',
    styles: [/*...*/],
    attributes: {/*...*/},
    edit(props) {
        /* ... */
        return ;
    },
    /* Only innerBlocks are returned, the rest left to PHP */
    save() {
        return ;
    },
});
```

```
register_block_type('my/block', [
    'editor_script' => 'myblock.js',
    'render_callback' => function(array $attributes = [], string $content = '') {
        foreach ($attributes as $name => $datum) {
            set_query_var($name, $datum);
        }
        if (!empty($content)) {
            set_query_var('innerBlocks', $content);
        }
        if (!empty($attributes['className'])) {
            set_query_var('className', $attributes['className']);
        }

        ob_start();
        load_template('template-parts/blocks/my-block.php', false, $data);
        return ob_get_clean();
    },
    'attributes' => [
        'title' => [
            'type' => 'string',
            'default' => 'Hello World',
        ],
    ],
]);
```

```
# template-parts/blocks/my-block.php
