1
votes

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()
});
1
Try this and check if you're getting post id or not: wp.data.withSelect("core/editor").getCurrentPostId();Brijesh Dhanani

1 Answers

1
votes

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!