Reputation: 175
I'm making Wordpress server side rendered block and it works well on frontend, but in editor attributes don't save (I have always default value in editor, although on frontend there is my saved value).
This is my code (not whole but minimal reproducible).
Register block on client side and set block options in editor:
const { __ } = wp.i18n;
const { ServerSideRender } = wp.editor;
const { InspectorControls } = wp.blockEditor;
const { PanelBody, __experimentalNumberControl: NumberControl } = wp.components;
registerBlockType(
'mysite/trainings',
{
title: __( 'Trainings list', 'mysite' ),
attributes: {
postsCount: {
type: 'number',
default: 9,
}
},
edit: ( { attributes, setAttributes } ) => {
const { postsCount } = attributes;
return (
<>
<InspectorControls>
<PanelBody
title={ __( 'Set number of displayed trainings', 'mysite' ) }
>
<NumberControl
value={ postsCount }
onChange={ ( value ) => setAttributes( { postsCount: value } ) }
min={ 1 }
max={ 9 }
/>
</PanelBody>
</InspectorControls>
<ServerSideRender
block="mysite/trainings"
attributes={ {
postsCount: 9,
} }
/>
</>
);
},
save() {
return null;
},
}
);
Register and render block on server side:
add_action( 'init', 'register_trainings_block' );
function register_trainings_block() {
register_block_type(
'mysite/trainings',
array(
'api_version' => 2,
'editor_script' => 'sm_editor_script',
'render_callback' => 'render_trainings_block',
'attributes' => array(
'postsCount' => array(
'type' => 'number',
'default' => 9,
),
),
)
);
}
function render_trainings_block( $attributes ) {
$query_args = array(
'post__in' => array(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10 // IDs of posts
),
'post_type' => 'sm_training',
'orderby' => 'post__in',
'paged' => '1'
);
$posts = new WP_Query( $query_args );
$output = '<section class="wp-block-mysite-trainings">';
$i = 0;
foreach ( $posts->posts as $post ) {
if ( $i < $attributes['postsCount'] ) {
ob_start();
$output .= get_template_part( 'template-parts/content/training' );
$output .= ob_get_clean();
}
$i++;
}
$output .= '</section>';
return $output;
}
Enqueue editor script:
add_action( 'enqueue_block_editor_assets', 'load_editor_scripts' );
public function load_editor_scripts() {
wp_enqueue_script( 'sm_editor_script', get_template_directory_uri() . '/assets/dist/js/editor.js', array(
'wp-blocks',
'wp-i18n',
'wp-editor',
'wp-components',
'wp-block-editor'
), '1.0.0', true );
wp_localize_script( 'sm_editor_script', 'gutenbergBlocks', array( 'themeUrl' => get_template_directory_uri() ) );
}
What am I missing?
Upvotes: -1
Views: 1222
Reputation: 175
I know :)
Two things:
<ServerSideRender
block="mysite/trainings"
attributes={ { postsCount } }
/>
(without default value here)
In js change in onChange function:
<NumberControl
value={ postsCount }
onChange={ ( value ) => setAttributes( { postsCount: Number.parseInt( value ) } ) }
min={ 1 }
max={ 9 }
/>
and in php render_trainings_block function:
$attributes['postsCount'] = (int) $attributes['postsCount'];
Upvotes: 1