I feel like what I want to accomplish is simple: create a custom WordPress Gutenberg Block that auto-populates with the author name and image and is not editable. Then render this block on the frontend post.
I've gone at this from a lot of different angles, and I think what I need is a Dynamic Block
https://developer.wordpress.org/block-editor/tutorials/block-tutorial/creating-dynamic-blocks/
First issue is the wp.data.select("core/editor").getCurrentPostId()
doesn't load the post ID. But then I'll be honest, I don't know if the return would even have the author info I want anyway. Any guidance is most appreciated.
const post_id = wp.data.select("core/editor").getCurrentPostId();
var el = wp.element.createElement;
wp.blocks.registerBlockType('my-plugin/author-block', {
title: 'Author Footer',
icon: 'admin-users',
category: 'my-blocks',
attributes: {
// Nothing stored
},
edit: wp.data.withSelect( function(select){ // Get server stuff to pass to our block
return {
posts: select('core').getEntityRecords('postType', 'post', {per_page: 1, post_id})
};
}) (function(props) { // How our block renders in the editor
if ( ! props.posts ) {
return 'Loading...';
}
if ( props.posts.length === 0 ) {
return 'No posts';
}
var post = props.posts[0];
// Do stuff with the post like maybe get author name and image???
// ... Return elements to editor viewer
}), // End edit()
save: function(props) { // Save the block for rendering in frontend post
// ... Return saved elements
} // End save()
});
Finally figured something out so thought I'd share.
edit: function(props) { // How our block renders in the editor in edit mode
var postID = wp.data.select("core/editor").getCurrentPostId();
wp.apiFetch( { path: '/wp/v2/posts/'+postID } ).then( post => {
var authorID = post.author
wp.apiFetch( { path: '/wp/v2/users/'+authorID } ).then( author => {
authorName = author.name;
authorImage = author.avatar_urls['96'];
jQuery('.author-bottom').html('<img src="'+authorImage+'"><div><h6>Written by</h6><h6 class="author-name">'+authorName+'</h6></div>');
});
});
return el(
'div',
{
className: 'author-bottom'
},
el(
'img',
{
src: null
}
),
el(
'div',
null,
el(
'h6',
null,
'Written by'
),
el(
'h6',
{
className: 'author-name'
},
'Loading...'
)
)
); // End return
}, // End edit()
As soon as the block loads, it initiates a couple apiFetch
calls (one to get the author ID, then another to get the author's name and image).
While that's happening, the author block loads with the temporary text "Loading..."
Once the apiFetch
is complete I used jQuery to update the author block.
There is no save
function because it's a dynamic block. I registered the block in my plugin php file like so:
function my_author_block_dynamic_render($attributes, $content) {
return '
<div class="author-bottom">
<img src="'.get_avatar_url(get_the_author_email(), ['size' => '200']).'">
<div>
<h6>Written by</h6>
<h6 class="author-name">'.get_the_author().'</h6>
</div>
</div>';
}
function my_dynamic_blocks() {
wp_register_script(
'my-blocks-script',
plugins_url( 'my-block.js', __FILE__ ),
array( 'wp-blocks', 'wp-element' ));
register_block_type( 'my-blocks/author-block', array(
'editor_script' => 'my-blocks-script',
'render_callback' => 'my_author_block_dynamic_render'));
}
add_action( 'init', 'my_dynamic_blocks' );
I couldn't find a good tutorial on creating a custom author block, so hopefully this example helps some poor soul down the road!