Skip to content

Instantly share code, notes, and snippets.

@Shelob9
Last active February 4, 2024 20:38
Show Gist options
  • Save Shelob9/144055408101e2fdfc4bf34adc85dd04 to your computer and use it in GitHub Desktop.
Save Shelob9/144055408101e2fdfc4bf34adc85dd04 to your computer and use it in GitHub Desktop.
Example Gutenberg block with server-side rendering. Gutenberg edit() block creates interface. Gutenberg saves settings automatically, the PHP function passed as `render_callback` to `register_block_type` is used to create HTML for front-end rendering of block.
const { __ } = wp.i18n;
const { registerBlockType } = wp.blocks;
const el = wp.element.createElement;
registerBlockType( 'hiRoy/serverSide', {
title: __( 'Server Side Block', 'text-domain' ),
icon: 'networking',
category: 'common',
attributes: {
images : {
default: [],
type: 'array',
}
},
edit({attributes, setAttributes, className, focus, id}) {
//Put a user interface here.
},
save({attributes, className}) {
//gutenberg will save attributes we can use in server-side callback
return null;
},
} );
<?php
register_block_type('hiRoy/serverSide', array(
'render_callback' => 'hi_roy_render_callback',
'attributes' => array(
'images' => array(
'type' => 'array'
)
)
)
);
function hi_roy_render_callback( $attributes ){
$images = $attributes[ 'images' ];
return '<div><!-- put image gallery here--></div>';
}
@wpexplorer
Copy link

@bizm - This gist isn't intended to explain how to register blocks it's just an example showing how to use the render_callback argument. Now, you don't actually have to use wp_enqueue_script to load your block JS file - you can and probably should be loading the file via your block.json file, see here: https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/ and scroll down to "Editor Script".

@Shelob9
Copy link
Author

Shelob9 commented Feb 16, 2022

@bizm Here is a more up to date example of how to set up a server-side rendered block: https://github.com/imaginarymachines/everything-all-of-the-time/blob/main/blocks/php-block/init.php

Two issues with your snippet that need corrected:

@ducktype
Copy link

ducktype commented Nov 21, 2023

add_action('init',function(){
  $block_meta = [
    'name' => 'test/test',
    'title' => 'Test',
    'render_callback' => function($attrs,$content,$block){
      return "TEST";
    }
  ];
  register_block_type($block_meta['name'],$block_meta);
  add_action('enqueue_block_editor_assets',function()use($block_meta){
    $screen = get_current_screen();
    if(!$screen->is_block_editor()) return;
    add_action('admin_print_footer_scripts',function()use($block_meta){
      echo "
       <script>
        var block = {
          edit: function({attributes, setAttributes, className, focus, id}) {
            return "HELLO"
          },
          save: function({attributes, className}) {
            return
          }
        }
        wp.blocks.registerBlockType('{$block_meta['name']}',block)
      </script>
      ";
    });
  });
});

@1ucay
Copy link

1ucay commented Dec 3, 2023

$block_metas = array(
    array(
        'name'  => 'domain/faq',
        'title' => __( 'FAQ', 'domain' ),
        'description' => '',
        'category' => 'text',
        'icon'  => 'star-filled',
        'api_version' => 2
    ),
    array(
        'name'  => 'domain/accordion',
        'title' => __( 'Accordion', 'domain' ),
        'description' => '',
        'category' => 'text',
        'icon'  => 'star-filled',
        'api_version' => 2
    )
);
foreach( $block_metas as $block_meta ) {

    $block_meta['render_callback'] = function ( $block_attributes, $content ) use ( $block_meta ) {
        ob_start();

        $file = ( str_contains( $block_meta['name'], '/' ) ) ? explode( '/', $block_meta['name'] )[1] : $block_meta['name'];

        if ( ob_get_level() ) {
            // https://wordpress.stackexchange.com/questions/4462/passing-variables-through-locate-template
            if ( $filepath = locate_template( "blocks/{$file}/{$file}.php", true, true, array_merge( $_REQUEST, $block_meta, $block_attributes ) ) )
                include_once( $filepath );

            $output = ob_get_contents();
            ob_end_clean();
        }

        return $output;
    };
    register_block_type( $block_meta['name'], $block_meta );

    add_action( 'enqueue_block_editor_assets', function() use ( $block_meta ) {
        add_action( 'admin_print_footer_scripts', function() use ( $block_meta ) {
            echo "
            <script>
                wp.blocks.registerBlockType('{$block_meta['name']}', {
                    edit: function( props ) {
                        return wp.element.createElement(
                            wp.serverSideRender, {
                                block: props.name
                            }
                        );
                    },
                    save: function({attributes, className}) {
                        return null;
                    }
                })
            </script>
            ";
        });
    });
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment