Summary: Learning about WordPress Dynamic Blocks Development.
Blocks in Gutenberg
WordPress’s Gutenberg editor revolves around blocks, which are essentially modular units that users can insert into their posts and pages. Blocks are the core concept for creating content in the new editor.
- Static blocks: Content is saved to the post content as HTML.
- Dynamic blocks: Content is generated on-the-fly when the page is viewed, based on server-side processing.
Dynamic Block
A dynamic block is a block where the content isn’t static HTML saved into the post content but is rendered on the server every time the page is viewed. This dynamic nature allows blocks to show real-time, updated, or context-specific content.
- Dynamic blocks use PHP to render the block’s output at runtime.
- Static blocks, by contrast, output HTML and store that in the post content directly.
- Recent posts lists
- User profile information
- External API data
- Dynamic form submissions
Static vs Dynamic Blocks
- Static Block Workflow: When we save a post, the block content is saved as static HTML in the post content. On the frontend, WordPress just outputs that saved HTML.
- Dynamic Block Workflow: The block content is not saved directly into the post content. Instead, WordPress runs a PHP function on the server to generate the block’s content every time the post is viewed.
Dynamic Block Rendering
- The block data (attributes and other saved information) is sent to a PHP callback function (defined when registering the block).
- This PHP callback generates the final HTML output, which is then injected into the page’s content.
- This means dynamic blocks can take advantage of server-side features such as querying the database, calling external APIs, or even making use of server-side caching to optimize performance.
Block Registration
The first step is to register the block using register_block_type
. This function connects our block’s frontend JavaScript with server-side rendering functionality.
register_block_type( 'namespace/block-name', array(
'render_callback' => 'render_block_function_name',
) );
The important part here is the render_callback
argument. This tells WordPress to execute a specified PHP function when rendering the block.
Render Callback
The render_callback
is the core of dynamic blocks. This PHP function generates the HTML output dynamically, and it can use any kind of server-side logic. We can query the database, interact with WordPress APIs, or perform any other operation that PHP allows.
function render_block_function_name( $attributes ) {
$recent_posts = wp_get_recent_posts( array(
'numberposts' => 5,
'post_status' => 'publish',
) );
if ( empty( $recent_posts ) ) {
return 'No posts available.';
}
$output = '<ul>';
foreach ( $recent_posts as $post ) {
$output .= '<li>' . esc_html( $post['post_title'] ) . '</li>';
}
$output .= '</ul>';
return $output;
}
- In this case, the callback generates an unordered list of the 5 most recent posts.
- This content is rendered each time the page loads, not saved statically in the post content.
Block Attributes
Dynamic blocks can have attributes that store user-defined data, such as settings or configurations the user may want to adjust. These attributes are often defined in the JavaScript that powers the block’s editor interface.
attributes: {
numberOfPosts: {
type: 'number',
default: 5
}
}
In the render_callback
function, these attributes are passed in and can be used to influence the output.
function render_block_function_name( $attributes ) {
$recent_posts = wp_get_recent_posts( array(
'numberposts' => $attributes['numberOfPosts'],
'post_status' => 'publish',
) );
}
Enqueue Scripts and Styles
Dynamic blocks often rely on specific JavaScript or CSS files to function properly. To handle this, WordPress provides the enqueue_block_assets
action, which allows us to conditionally load scripts and styles only when our block is used.
function enqueue_block_assets() {
if ( has_block( 'namespace/block-name' ) ) {
wp_enqueue_style( 'namespace-block-style', plugins_url( 'style.css', __FILE__ ) );
wp_enqueue_script( 'namespace-block-script', plugins_url( 'script.js', __FILE__ ) );
}
}
add_action( 'enqueue_block_assets', 'enqueue_block_assets' );
Server-Side Rendering Logic
Since dynamic blocks are rendered server-side, the content returned by the PHP function is what gets output into the final HTML. This allows us to easily integrate with other WordPress server-side functions.
- Querying posts: We can use functions like
get_posts()
orWP_Query
. - User data: We can use functions like
get_current_user_id()
orget_userdata()
. - Shortcodes: We can render shortcodes dynamically by calling
do_shortcode()
inside the render callback.
import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
import { PanelBody, RangeControl, TextControl } from '@wordpress/components';
import ServerSideRender from '@wordpress/server-side-render';
registerBlockType( 'namespace/dynamic-block', {
title: 'Server-Side Rendered Block',
icon: 'list-view',
category: 'widgets',
attributes: {
title: {
type: 'string',
default: 'Dynamic Block Title',
},
numberOfPosts: {
type: 'number',
default: 5,
},
},
edit: ( props ) => {
const { attributes, setAttributes } = props;
const blockProps = useBlockProps();
return (
<div { ...blockProps }>
<InspectorControls>
<PanelBody title="Block Settings">
<TextControl
label="Block Title"
value={ attributes.title }
onChange={ ( value ) => setAttributes( { title: value } ) }
/>
<RangeControl
label="Number of Posts"
value={ attributes.numberOfPosts }
onChange={ ( value ) => setAttributes( { numberOfPosts: value } ) }
min={ 1 }
max={ 10 }
/>
</PanelBody>
</InspectorControls>
<ServerSideRender
block="namespace/dynamic-block"
attributes={ attributes }
/>
</div>
);
},
save: () => {
// Server-side rendering, so nothing is saved in post content
return null;
},
} );
<?php
// Register the block type and the render callback
function namespace_register_dynamic_block() {
register_block_type( 'namespace/dynamic-block', array(
'attributes' => array(
'title' => array(
'type' => 'string',
'default' => 'Dynamic Block Title',
),
'numberOfPosts' => array(
'type' => 'number',
'default' => 5,
),
),
'render_callback' => 'namespace_render_dynamic_block',
) );
}
add_action( 'init', 'namespace_register_dynamic_block' );
// Render the block on the server side
function namespace_render_dynamic_block( $attributes ) {
// Set default values for attributes if not provided
$title = isset( $attributes['title'] ) ? $attributes['title'] : 'Dynamic Block Title';
$numberOfPosts = isset( $attributes['numberOfPosts'] ) ? (int) $attributes['numberOfPosts'] : 5;
// Query the latest posts
$recent_posts = wp_get_recent_posts( array(
'numberposts' => $numberOfPosts,
'post_status' => 'publish',
) );
// If no posts found
if ( empty( $recent_posts ) ) {
return '<p>No posts available.</p>';
}
// Generate the output
$output = '<div class="dynamic-block">';
$output .= '<h3>' . esc_html( $title ) . '</h3>';
$output .= '<ul>';
foreach ( $recent_posts as $post ) {
$output .= '<li><a href="' . esc_url( get_permalink( $post['ID'] ) ) . '">' . esc_html( $post['post_title'] ) . '</a></li>';
}
$output .= '</ul>';
$output .= '</div>';
return $output;
}
Leave a Reply