diff --git a/lib/blocks.php b/lib/blocks.php index 9e0d63a0c6bf0..95b9c16ad09fd 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -75,6 +75,7 @@ function gutenberg_reregister_core_block_types() { 'post-comment-content.php' => 'core/post-comment-content', 'post-comment-date.php' => 'core/post-comment-date', 'post-comment-edit.php' => 'core/post-comment-edit', + 'post-comment-reply-link.php' => 'core/post-comment-reply-link', 'post-comments.php' => 'core/post-comments', 'post-comments-count.php' => 'core/post-comments-count', 'post-comments-form.php' => 'core/post-comments-form', diff --git a/packages/block-library/src/index.js b/packages/block-library/src/index.js index 77095d01063ca..588edb6070563 100644 --- a/packages/block-library/src/index.js +++ b/packages/block-library/src/index.js @@ -84,6 +84,7 @@ import * as postCommentAuthorAvatar from './post-comment-author-avatar'; import * as postCommentContent from './post-comment-content'; import * as postCommentDate from './post-comment-date'; import * as postCommentEdit from './post-comment-edit'; +import * as postCommentReplyLink from './post-comment-reply-link'; import * as postComments from './post-comments'; import * as postCommentsCount from './post-comments-count'; import * as postCommentsForm from './post-comments-form'; @@ -247,6 +248,7 @@ export const __experimentalRegisterExperimentalCoreBlocks = postCommentContent, postCommentDate, postCommentEdit, + postCommentReplyLink, postComments, postCommentsCount, postCommentsForm, diff --git a/packages/block-library/src/post-comment-reply-link/block.json b/packages/block-library/src/post-comment-reply-link/block.json new file mode 100644 index 0000000000000..ddfdc540e70a6 --- /dev/null +++ b/packages/block-library/src/post-comment-reply-link/block.json @@ -0,0 +1,32 @@ +{ + "apiVersion": 2, + "name": "core/post-comment-reply-link", + "title": "Post Comment Reply Link", + "category": "design", + "parent": [ "core/post-comment" ], + "description": "Displays a link to reply to a comment.", + "textdomain": "default", + "usesContext": [ "commentId" ], + "attributes": { + "textAlign": { + "type": "string" + } + }, + "supports": { + "color": { + "gradients": true, + "link": true, + "text": false + }, + "typography": { + "fontSize": true, + "lineHeight": true, + "__experimentalFontFamily": true, + "__experimentalFontWeight": true, + "__experimentalFontStyle": true, + "__experimentalTextTransform": true, + "__experimentalLetterSpacing": true + }, + "html": false + } +} diff --git a/packages/block-library/src/post-comment-reply-link/edit.js b/packages/block-library/src/post-comment-reply-link/edit.js new file mode 100644 index 0000000000000..776caa9f3e752 --- /dev/null +++ b/packages/block-library/src/post-comment-reply-link/edit.js @@ -0,0 +1,59 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { + AlignmentControl, + BlockControls, + useBlockProps, +} from '@wordpress/block-editor'; + +/** + * Renders the `core/post-comment-reply-link` block on the editor. + * + * @param {Object} props React props. + * @param {Object} props.setAttributes Callback for updating block attributes. + * @param {Object} props.attributes Block attributes. + * @param {string} props.attributes.textAlign The `textAlign` attribute. + * + * @return {JSX.Element} React element. + */ +function Edit( { setAttributes, attributes: { textAlign } } ) { + const blockProps = useBlockProps( { + className: classnames( { + [ `has-text-align-${ textAlign }` ]: textAlign, + } ), + } ); + + const blockControls = ( + + + setAttributes( { textAlign: newAlign } ) + } + /> + + ); + + return ( + <> + { blockControls } +
+ event.preventDefault() } + > + { __( 'Reply' ) } + +
+ + ); +} + +export default Edit; diff --git a/packages/block-library/src/post-comment-reply-link/index.js b/packages/block-library/src/post-comment-reply-link/index.js new file mode 100644 index 0000000000000..7d52091a43abb --- /dev/null +++ b/packages/block-library/src/post-comment-reply-link/index.js @@ -0,0 +1,18 @@ +/** + * WordPress dependencies + */ +import { postCommentReplyLink as icon } from '@wordpress/icons'; + +/** + * Internal dependencies + */ +import metadata from './block.json'; +import edit from './edit'; + +const { name } = metadata; +export { metadata, name }; + +export const settings = { + edit, + icon, +}; diff --git a/packages/block-library/src/post-comment-reply-link/index.php b/packages/block-library/src/post-comment-reply-link/index.php new file mode 100644 index 0000000000000..d3b11b0fbd539 --- /dev/null +++ b/packages/block-library/src/post-comment-reply-link/index.php @@ -0,0 +1,80 @@ +context['commentId'] ) ) { + return ''; + } + + $thread_comments = get_option( 'thread_comments' ); + if ( ! $thread_comments ) { + return ''; + } + + $comment = get_comment( $block->context['commentId'] ); + if ( empty( $comment ) ) { + return ''; + } + + $depth = 1; + $max_depth = get_option( 'thread_comments_depth' ); + $parent_id = $comment->comment_parent; + + // Compute comment's depth iterating over its ancestors. + while ( ! empty( $parent_id ) ) { + $depth++; + $parent_id = get_comment( $parent_id )->comment_parent; + } + + $comment_reply_link = get_comment_reply_link( + array( + 'depth' => $depth, + 'max_depth' => $max_depth, + ), + $comment + ); + + // Render nothing if the generated reply link is empty. + if ( empty( $comment_reply_link ) ) { + return; + } + + $classes = ''; + if ( isset( $attributes['textAlign'] ) ) { + $classes .= 'has-text-align-' . $attributes['textAlign']; + } + + $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classes ) ); + + return sprintf( + '
%2$s
', + $wrapper_attributes, + $comment_reply_link + ); +} + +/** + * Registers the `core/post-comment-reply-link` block on the server. + */ +function register_block_core_post_comment_reply_link() { + register_block_type_from_metadata( + __DIR__ . '/post-comment-reply-link', + array( + 'render_callback' => 'render_block_core_post_comment_reply_link', + ) + ); +} + +add_action( 'init', 'register_block_core_post_comment_reply_link' ); diff --git a/packages/block-library/src/post-comment/edit.js b/packages/block-library/src/post-comment/edit.js index a08048f9c2b2b..d293a45c1fff6 100644 --- a/packages/block-library/src/post-comment/edit.js +++ b/packages/block-library/src/post-comment/edit.js @@ -14,10 +14,12 @@ const ALLOWED_BLOCKS = [ 'core/post-comment-content', 'core/post-comment-author', 'core/post-comment-date', + 'core/post-comment-reply-link', ]; const TEMPLATE = [ [ 'core/post-comment-content' ], [ 'core/post-comment-author' ], + [ 'core/post-comment-reply-link' ], ]; export default function Edit( { attributes: { commentId }, setAttributes } ) { diff --git a/packages/icons/src/index.js b/packages/icons/src/index.js index 27d3cdd12c819..885edbd8d1fef 100644 --- a/packages/icons/src/index.js +++ b/packages/icons/src/index.js @@ -152,6 +152,7 @@ export { default as plus } from './library/plus'; 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 postCommentReplyLink } from './library/post-comment-reply-link'; 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'; diff --git a/packages/icons/src/library/post-comment-reply-link.js b/packages/icons/src/library/post-comment-reply-link.js new file mode 100644 index 0000000000000..551092c131270 --- /dev/null +++ b/packages/icons/src/library/post-comment-reply-link.js @@ -0,0 +1,17 @@ +/** + * WordPress dependencies + */ +import { Path, SVG } from '@wordpress/primitives'; + +const postCommentsReplyLink = ( + + + +); + +export default postCommentsReplyLink; diff --git a/test/integration/fixtures/blocks/core__post-comment-reply-link.html b/test/integration/fixtures/blocks/core__post-comment-reply-link.html new file mode 100644 index 0000000000000..af837d2e3e353 --- /dev/null +++ b/test/integration/fixtures/blocks/core__post-comment-reply-link.html @@ -0,0 +1 @@ + diff --git a/test/integration/fixtures/blocks/core__post-comment-reply-link.json b/test/integration/fixtures/blocks/core__post-comment-reply-link.json new file mode 100644 index 0000000000000..197e2489561b3 --- /dev/null +++ b/test/integration/fixtures/blocks/core__post-comment-reply-link.json @@ -0,0 +1,31 @@ +[ + { + "clientId": "_clientId_0", + "name": "core/post-comment-reply-link", + "isValid": true, + "attributes": { + "textAlign": "right", + "fontFamily": "cambria-georgia", + "fontSize": "extra-large", + "style": { + "typography": { + "lineHeight": "0.8", + "textTransform": "uppercase", + "letterSpacing": "10px" + }, + "elements": { + "link": { + "color": { + "text": "var:preset|color|blue" + } + } + }, + "color": { + "background": "#c82222" + } + } + }, + "innerBlocks": [], + "originalContent": "" + } +] diff --git a/test/integration/fixtures/blocks/core__post-comment-reply-link.parsed.json b/test/integration/fixtures/blocks/core__post-comment-reply-link.parsed.json new file mode 100644 index 0000000000000..5e34e1feefb75 --- /dev/null +++ b/test/integration/fixtures/blocks/core__post-comment-reply-link.parsed.json @@ -0,0 +1,30 @@ +[ + { + "blockName": "core/post-comment-reply-link", + "attrs": { + "textAlign": "right", + "style": { + "typography": { + "lineHeight": "0.8", + "textTransform": "uppercase", + "letterSpacing": "10px" + }, + "elements": { + "link": { + "color": { + "text": "var:preset|color|blue" + } + } + }, + "color": { + "background": "#c82222" + } + }, + "fontSize": "extra-large", + "fontFamily": "cambria-georgia" + }, + "innerBlocks": [], + "innerHTML": "", + "innerContent": [] + } +] diff --git a/test/integration/fixtures/blocks/core__post-comment-reply-link.serialized.html b/test/integration/fixtures/blocks/core__post-comment-reply-link.serialized.html new file mode 100644 index 0000000000000..8e6c147336d66 --- /dev/null +++ b/test/integration/fixtures/blocks/core__post-comment-reply-link.serialized.html @@ -0,0 +1 @@ +