Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Site Editor: Add Comment Avatar Core Block #35396

Merged
merged 24 commits into from
Oct 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 47 additions & 46 deletions lib/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,53 +50,54 @@ function gutenberg_reregister_core_block_types() {
'embed',
),
'block_names' => array(
'archives.php' => 'core/archives',
'block.php' => 'core/block',
'calendar.php' => 'core/calendar',
'categories.php' => 'core/categories',
'file.php' => 'core/file',
'latest-comments.php' => 'core/latest-comments',
'latest-posts.php' => 'core/latest-posts',
'loginout.php' => 'core/loginout',
'navigation.php' => 'core/navigation',
'navigation-link.php' => 'core/navigation-link',
'navigation-submenu.php' => 'core/navigation-submenu',
'home-link.php' => 'core/home-link',
'rss.php' => 'core/rss',
'search.php' => 'core/search',
'shortcode.php' => 'core/shortcode',
'social-link.php' => 'core/social-link',
'tag-cloud.php' => 'core/tag-cloud',
'page-list.php' => 'core/page-list',
'post-author.php' => 'core/post-author',
'post-comment.php' => 'core/post-comment',
'post-comment-author.php' => 'core/post-comment-author',
'post-comment-content.php' => 'core/post-comment-content',
'post-comment-date.php' => 'core/post-comment-date',
'post-comments.php' => 'core/post-comments',
'post-comments-count.php' => 'core/post-comments-count',
'post-comments-form.php' => 'core/post-comments-form',
'post-comments-link.php' => 'core/post-comments-link',
'post-content.php' => 'core/post-content',
'post-date.php' => 'core/post-date',
'post-excerpt.php' => 'core/post-excerpt',
'post-featured-image.php' => 'core/post-featured-image',
'post-terms.php' => 'core/post-terms',
'post-navigation-link.php' => 'core/post-navigation-link',
'post-title.php' => 'core/post-title',
'query.php' => 'core/query',
'post-template.php' => 'core/post-template',
'query-title.php' => 'core/query-title',
'query-pagination.php' => 'core/query-pagination',
'query-pagination-next.php' => 'core/query-pagination-next',
'query-pagination-numbers.php' => 'core/query-pagination-numbers',
'query-pagination-previous.php' => 'core/query-pagination-previous',
'site-logo.php' => 'core/site-logo',
'site-tagline.php' => 'core/site-tagline',
'site-title.php' => 'core/site-title',
'archives.php' => 'core/archives',
'block.php' => 'core/block',
'calendar.php' => 'core/calendar',
'categories.php' => 'core/categories',
'file.php' => 'core/file',
'latest-comments.php' => 'core/latest-comments',
'latest-posts.php' => 'core/latest-posts',
'loginout.php' => 'core/loginout',
'navigation.php' => 'core/navigation',
'navigation-link.php' => 'core/navigation-link',
'navigation-submenu.php' => 'core/navigation-submenu',
'home-link.php' => 'core/home-link',
'rss.php' => 'core/rss',
'search.php' => 'core/search',
'shortcode.php' => 'core/shortcode',
'social-link.php' => 'core/social-link',
'tag-cloud.php' => 'core/tag-cloud',
'page-list.php' => 'core/page-list',
'post-author.php' => 'core/post-author',
'post-comment.php' => 'core/post-comment',
'post-comment-author.php' => 'core/post-comment-author',
'post-comment-author-avatar.php' => 'core/post-comment-author-avatar',
'post-comment-content.php' => 'core/post-comment-content',
'post-comment-date.php' => 'core/post-comment-date',
'post-comments.php' => 'core/post-comments',
'post-comments-count.php' => 'core/post-comments-count',
'post-comments-form.php' => 'core/post-comments-form',
'post-comments-link.php' => 'core/post-comments-link',
'post-content.php' => 'core/post-content',
'post-date.php' => 'core/post-date',
'post-excerpt.php' => 'core/post-excerpt',
'post-featured-image.php' => 'core/post-featured-image',
'post-terms.php' => 'core/post-terms',
'post-navigation-link.php' => 'core/post-navigation-link',
'post-title.php' => 'core/post-title',
'query.php' => 'core/query',
'post-template.php' => 'core/post-template',
'query-title.php' => 'core/query-title',
'query-pagination.php' => 'core/query-pagination',
'query-pagination-next.php' => 'core/query-pagination-next',
'query-pagination-numbers.php' => 'core/query-pagination-numbers',
'query-pagination-previous.php' => 'core/query-pagination-previous',
'site-logo.php' => 'core/site-logo',
'site-tagline.php' => 'core/site-tagline',
'site-title.php' => 'core/site-title',
// 'table-of-contents.php' => 'core/table-of-contents',
'template-part.php' => 'core/template-part',
'term-description.php' => 'core/term-description',
'template-part.php' => 'core/template-part',
'term-description.php' => 'core/term-description',
),
),
__DIR__ . '/../build/edit-widgets/blocks/' => array(
Expand Down
2 changes: 2 additions & 0 deletions packages/block-library/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ import * as postContent from './post-content';
import * as postAuthor from './post-author';
import * as postComment from './post-comment';
import * as postCommentAuthor from './post-comment-author';
import * as postCommentAuthorAvatar from './post-comment-author-avatar';
import * as postCommentContent from './post-comment-content';
import * as postCommentDate from './post-comment-date';
import * as postComments from './post-comments';
Expand Down Expand Up @@ -241,6 +242,7 @@ export const __experimentalRegisterExperimentalCoreBlocks =
postAuthor,
postComment,
postCommentAuthor,
postCommentAuthorAvatar,
postCommentContent,
postCommentDate,
postComments,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"apiVersion": 2,
"name": "core/post-comment-author-avatar",
"title": "Comment Author Avatar",
"category": "design",
"parent": [ "core/post-comment" ],
"description": "Comment Author Avatar.",
"textdomain": "default",
"attributes": {
"width": {
"type": "number",
"default": 96
},
"height": {
"type": "number",
"default": 96
}
},
"usesContext": [ "commentId" ],
"supports": {
"html": false,
"__experimentalBorder": {
"radius": true,
"width": true,
"color": true,
"style": true
},
"color": {
"background": true,
"text": false,
"links": false
}
}
}
96 changes: 96 additions & 0 deletions packages/block-library/src/post-comment-author-avatar/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/**
* WordPress dependencies
*/
import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
import { PanelBody, ResizableBox, RangeControl } from '@wordpress/components';
import { useEntityProp } from '@wordpress/core-data';
import { __, _x, isRTL } from '@wordpress/i18n';

export default function Edit( {
attributes,
context: { commentId },
setAttributes,
} ) {
const { height, width } = attributes;

const [ avatars ] = useEntityProp(
'root',
'comment',
'author_avatar_urls',
commentId
);

const [ authorName ] = useEntityProp(
'root',
'comment',
'author_name',
commentId
);
const avatarUrls = avatars ? Object.values( avatars ) : null;
const sizes = avatars ? Object.keys( avatars ) : null;
const minSize = sizes ? sizes[ 0 ] : 24;
const maxSize = sizes ? sizes[ sizes.length - 1 ] : 96;
const blockProps = useBlockProps();
const maxSizeBuffer = Math.floor( maxSize * 2.5 );

const inspectorControls = (
<InspectorControls>
<PanelBody title={ __( 'Avatar Settings' ) }>
<RangeControl
label={ __( 'Image size' ) }
onChange={ ( newWidth ) =>
setAttributes( {
width: newWidth,
height: newWidth,
} )
}
min={ minSize }
max={ maxSizeBuffer }
initialPosition={ width }
value={ width }
/>
</PanelBody>
</InspectorControls>
);

const displayAvatar = avatarUrls ? (
<ResizableBox
size={ {
width,
height,
} }
onResizeStop={ ( event, direction, elt, delta ) => {
setAttributes( {
height: parseInt( height + delta.height, 10 ),
width: parseInt( width + delta.width, 10 ),
} );
} }
lockAspectRatio
enable={ {
top: false,
right: ! isRTL(),
bottom: true,
left: isRTL(),
} }
minWidth={ minSize }
maxWidth={ maxSizeBuffer }
>
<img
src={ avatarUrls[ avatarUrls.length - 1 ] }
alt={ `${ authorName } ${ __( 'Avatar' ) }` }
{ ...blockProps }
/>
</ResizableBox>
) : (
<p { ...blockProps }>
{ _x( 'Comment Author Avatar', 'block title' ) }
</p>
);

return (
<>
{ inspectorControls }
<div>{ displayAvatar }</div>
</>
);
}
18 changes: 18 additions & 0 deletions packages/block-library/src/post-comment-author-avatar/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Internal dependencies
*/
import metadata from './block.json';
import edit from './edit';

/**
* WordPress dependencies
*/
import { postCommentAuthorAvatar as icon } from '@wordpress/icons';

const { name } = metadata;
export { metadata, name };

export const settings = {
icon,
edit,
};
62 changes: 62 additions & 0 deletions packages/block-library/src/post-comment-author-avatar/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php
/**
* Server-side rendering of the `core/post-comment-author-avatar` block.
*
* @package WordPress
*/

/**
* Renders the `core/post-comment-author-avatar` block on the server.
*
* @param array $attributes Block attributes.
* @param string $content Block default content.
* @param WP_Block $block Block instance.
* @return string Return the post comment's avatar.
*/
function render_block_core_post_comment_author_avatar( $attributes, $content, $block ) {
if ( ! isset( $block->context['commentId'] ) ) {
return '';
}

$comment = get_comment( $block->context['commentId'] );
if ( ! $comment ) {
return '';
}

// This is the only way to retreive style and classes on different instances.
$wrapper_attributes = WP_Block_Supports::get_instance()->apply_block_supports();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you pass the result of get_block_wrapper_attributes() as extra_attr when calling get_avatar instead?

Copy link
Contributor Author

@cbravobernal cbravobernal Oct 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That way the background color dissapears due to that get_avatar() function is not overwriting the class attribute. As class is defined before, it remains with default classes instead of using the block attribute ones.

That is the reason why asks for a class attribute first. I think there are a few components that behaves similar.

This is the get_avatar() function part where it handles class and the rest of attributes:
Screenshot 2021-10-25 at 12 45 16

This is the frontend markup:
Screenshot 2021-10-25 at 12 42 59

Would be a good idea to extend the get_block_wrapper_attributes() to return styles and classes separately if needed? Or maybe would be better to add a couple of functions one for classes and one for styles?

In case the first one is a good approach, I could create an issue for that, but that one should be on Trac I think.

Copy link
Member

@gziolo gziolo Oct 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised that get_block_wrapper_attributes returns a string in the first place. If it would return styles and classes separately, we wouldn't have to worry about the issue you run into. It's probably easier to introduce a lower-level function that returns a single attribute based on the following part of the existing function:

https://github.com/WordPress/wordpress-develop/blob/2382765afa36e10bf3c74420024ad4e85763a47c/src/wp-includes/class-wp-block-supports.php#L171-L203

Something like get_block_wrapper_attribute_value( 'class', 'foo-class boo-class' ).

What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that apply_block_supports performs a few computations:
https://github.com/WordPress/wordpress-develop/blob/2382765afa36e10bf3c74420024ad4e85763a47c/src/wp-includes/class-wp-block-supports.php#L93

So it might make more sense to have a function that returns both attributes as values.

Copy link
Member

@gziolo gziolo Oct 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, it shouldn't be a blocker for this block. Let's tackle it later 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a Trac issue. I will create and test a PR on the WordPress repo.
https://core.trac.wordpress.org/ticket/54319

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thank you!

$width = isset( $attributes['width'] ) ? $attributes['width'] : 96;
$height = isset( $attributes['height'] ) ? $attributes['height'] : 96;
$styles = isset( $wrapper_attributes['style'] ) ? $wrapper_attributes['style'] : '';
$classes = isset( $wrapper_attributes['class'] ) ? $wrapper_attributes['class'] : '';

/* translators: %s is the Comment Author name */
$alt = sprintf( __( '%s Avatar' ), $comment->comment_author );

$avatar_string = get_avatar(
$comment,
null,
'',
$alt,
array(
'height' => $height,
'width' => $width,
'extra_attr' => sprintf( 'style="%1s"', $styles ),
'class' => $classes,
)
);
return $avatar_string;
}

/**
* Registers the `core/comment-author-avatar` block on the server.
*/
function register_block_core_post_comment_author_avatar() {
register_block_type_from_metadata(
__DIR__ . '/post-comment-author-avatar',
array(
'render_callback' => 'render_block_core_post_comment_author_avatar',
)
);
}
add_action( 'init', 'register_block_core_post_comment_author_avatar' );
5 changes: 5 additions & 0 deletions packages/components/src/resizable-box/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ $resize-handler-container-size: $resize-handler-size + ($grid-unit-05 * 2); // M
}
}

// Make the image inside the resize to get the full width
.components-resizable-box__container > img {
width: inherit;
}

// This is the "visible" resize handle - the circle part
.components-resizable-box__handle::after {
display: block;
Expand Down
1 change: 1 addition & 0 deletions packages/icons/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ export { default as postAuthor } from './library/post-author';
export { default as postCategories } from './library/post-categories';
export { default as postContent } from './library/post-content';
export { default as postComments } from './library/post-comments';
export { default as postCommentAuthorAvatar } from './library/post-comment-author-avatar';
export { default as postCommentsCount } from './library/post-comments-count';
export { default as postCommentsForm } from './library/post-comments-form';
export { default as postDate } from './library/post-date';
Expand Down
17 changes: 17 additions & 0 deletions packages/icons/src/library/post-comment-author-avatar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* WordPress dependencies
*/
import { Path, SVG } from '@wordpress/primitives';

const postCommentAuthorAvatar = (
<SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<Path
d="M7.25 16.4371C6.16445 15.2755 5.5 13.7153 5.5 12C5.5 8.41015 8.41015 5.5 12 5.5C15.5899 5.5 18.5 8.41015 18.5 12C18.5 13.7153 17.8356 15.2755 16.75 16.4371V16C16.75 14.4812 15.5188 13.25 14 13.25L10 13.25C8.48122 13.25 7.25 14.4812 7.25 16V16.4371ZM8.75 17.6304C9.70606 18.1835 10.8161 18.5 12 18.5C13.1839 18.5 14.2939 18.1835 15.25 17.6304V16C15.25 15.3096 14.6904 14.75 14 14.75L10 14.75C9.30964 14.75 8.75 15.3096 8.75 16V17.6304ZM4 12C4 7.58172 7.58172 4 12 4C16.4183 4 20 7.58172 20 12C20 16.4183 16.4183 20 12 20C7.58172 20 4 16.4183 4 12ZM14 10C14 11.1046 13.1046 12 12 12C10.8954 12 10 11.1046 10 10C10 8.89543 10.8954 8 12 8C13.1046 8 14 8.89543 14 10Z"
fillRule="evenodd"
clipRule="evenodd"
fill="black"
/>
</SVG>
);

export default postCommentAuthorAvatar;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!-- wp:post-comment-author-avatar {"width":120,"height":120,"style":{"border":{"width":"3px","style":"solid","radius":"100px"}},"borderColor":"recommended-color-02","backgroundColor":"text-color"} /-->
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[
{
"clientId": "_clientId_0",
"name": "core/post-comment-author-avatar",
"isValid": true,
"attributes": {
"width": 120,
"height": 120,
"borderColor": "recommended-color-02",
"backgroundColor": "text-color",
"style": {
"border": {
"width": "3px",
"style": "solid",
"radius": "100px"
}
}
},
"innerBlocks": [],
"originalContent": ""
}
]
Loading