Skip to content

Commit

Permalink
Create Comments Title block with simple styling (#40419)
Browse files Browse the repository at this point in the history
Co-authored-by: Michal Czaplinski <[email protected]>
Co-authored-by: Bernie Reiter <[email protected]>
  • Loading branch information
3 people authored Apr 19, 2022
1 parent cd815b1 commit a1a1468
Show file tree
Hide file tree
Showing 21 changed files with 555 additions and 56 deletions.
9 changes: 9 additions & 0 deletions docs/reference-guides/core-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,15 @@ An advanced block that allows displaying post comments using different visual co
- **Supports:** align (full, wide), color (background, gradients, link, text), ~~html~~
- **Attributes:** tagName

## Comments Title

Displays a title with the number of comments ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/comments-title))

- **Name:** core/comments-title
- **Category:** theme
- **Supports:** align, color (background, gradients, text), spacing (margin, padding), typography (fontSize, lineHeight), ~~anchor~~, ~~html~~
- **Attributes:** level, multipleCommentsLabel, showCommentsCount, showPostTitle, singleCommentLabel, textAlign

## Cover

Add an image or video with a text overlay — great for headers. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/cover))
Expand Down
1 change: 1 addition & 0 deletions lib/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ function gutenberg_reregister_core_block_types() {
'comments-pagination-next.php' => 'core/comments-pagination-next',
'comments-pagination-numbers.php' => 'core/comments-pagination-numbers',
'comments-pagination-previous.php' => 'core/comments-pagination-previous',
'comments-title.php' => 'core/comments-title',
'file.php' => 'core/file',
'home-link.php' => 'core/home-link',
'image.php' => 'core/image',
Expand Down
1 change: 1 addition & 0 deletions packages/block-library/src/comments-query-loop/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';
import CommentsInspectorControls from './edit/comments-inspector-controls';

const TEMPLATE = [
[ 'core/comments-title' ],
[
'core/comment-template',
{},
Expand Down
70 changes: 70 additions & 0 deletions packages/block-library/src/comments-title/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/comments-title",
"title": "Comments Title",
"category": "theme",
"ancestor": [ "core/comments-query-loop" ],
"description": "Displays a title with the number of comments",
"textdomain": "default",
"usesContext": [ "postId", "postType" ],
"attributes": {
"textAlign": {
"type": "string"
},
"singleCommentLabel": {
"type": "string"
},
"multipleCommentsLabel": {
"type": "string"
},
"showPostTitle": {
"type": "boolean",
"default": true
},
"showCommentsCount": {
"type": "boolean",
"default": true
},
"level": {
"type": "number",
"default": 2
}
},
"supports": {
"anchor": false,
"align": true,
"html": false,
"__experimentalBorder": {
"radius": true,
"color": true,
"width": true,
"style": true
},
"color": {
"gradients": true,
"__experimentalDefaultControls": {
"background": true,
"text": true
}
},
"spacing": {
"margin": true,
"padding": true
},
"typography": {
"fontSize": true,
"lineHeight": true,
"__experimentalFontStyle": true,
"__experimentalFontWeight": true,
"__experimentalFontFamily": true,
"__experimentalTextTransform": true,
"__experimentalDefaultControls": {
"fontSize": true,
"__experimentalFontFamily": true,
"__experimentalFontStyle": true,
"__experimentalFontWeight": true
}
}
}
}
197 changes: 197 additions & 0 deletions packages/block-library/src/comments-title/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import {
AlignmentControl,
BlockControls,
useBlockProps,
PlainText,
InspectorControls,
} from '@wordpress/block-editor';
import { __ } from '@wordpress/i18n';
import { useEntityProp } from '@wordpress/core-data';
import {
PanelBody,
ToggleControl,
__experimentalToggleGroupControl as ToggleGroupControl,
__experimentalToggleGroupControlOption as ToggleGroupControlOption,
} from '@wordpress/components';
import { useState, useEffect } from '@wordpress/element';
import apiFetch from '@wordpress/api-fetch';
import { addQueryArgs } from '@wordpress/url';

/**
* Internal dependencies
*/
import HeadingLevelDropdown from '../heading/heading-level-dropdown';

export default function Edit( {
attributes: {
textAlign,
singleCommentLabel,
multipleCommentsLabel,
showPostTitle,
showCommentsCount,
level,
},
setAttributes,
context: { postType, postId },
} ) {
const TagName = 'h' + level;
const [ commentsCount, setCommentsCount ] = useState();
const [ editingMode, setEditingMode ] = useState( 'plural' );
const [ rawTitle ] = useEntityProp( 'postType', postType, 'title', postId );
const isSiteEditor = typeof postId === 'undefined';
const blockProps = useBlockProps( {
className: classnames( {
[ `has-text-align-${ textAlign }` ]: textAlign,
} ),
} );

useEffect( () => {
if ( isSiteEditor ) {
setCommentsCount( 3 );
return;
}
const currentPostId = postId;
apiFetch( {
path: addQueryArgs( '/wp/v2/comments', {
post: postId,
_fields: 'id',
} ),
method: 'HEAD',
parse: false,
} )
.then( ( res ) => {
// Stale requests will have the `currentPostId` of an older closure.
if ( currentPostId === postId ) {
setCommentsCount(
parseInt( res.headers.get( 'X-WP-Total' ) )
);
}
} )
.catch( () => {
setCommentsCount( 0 );
} );
}, [ postId ] );

const blockControls = (
<BlockControls group="block">
<AlignmentControl
value={ textAlign }
onChange={ ( newAlign ) =>
setAttributes( { textAlign: newAlign } )
}
/>
<HeadingLevelDropdown
selectedLevel={ level }
onChange={ ( newLevel ) =>
setAttributes( { level: newLevel } )
}
/>
</BlockControls>
);

const inspectorControls = (
<InspectorControls>
<PanelBody title={ __( 'Settings' ) }>
{ isSiteEditor && (
<ToggleGroupControl
label={ __( 'Editing mode' ) }
onChange={ setEditingMode }
value={ editingMode }
>
<ToggleGroupControlOption
label={ __( 'Singular' ) }
value="singular"
/>
<ToggleGroupControlOption
label={ __( 'Plural' ) }
value="plural"
/>
</ToggleGroupControl>
) }
<ToggleControl
label={ __( 'Show post title' ) }
checked={ showPostTitle }
onChange={ ( value ) =>
setAttributes( { showPostTitle: value } )
}
/>
<ToggleControl
label={ __( 'Show comments count' ) }
checked={ showCommentsCount }
onChange={ ( value ) =>
setAttributes( { showCommentsCount: value } )
}
/>
</PanelBody>
</InspectorControls>
);

const postTitle = isSiteEditor ? __( '"Post Title"' ) : `"${ rawTitle }"`;

const singlePlaceholder = showPostTitle
? __( 'One response to ' )
: __( 'One response' );

const multiplePlaceholder = showPostTitle
? __( 'Responses to ' )
: __( 'Responses' );

return (
<>
{ blockControls }
{ inspectorControls }
<TagName { ...blockProps }>
{ editingMode === 'singular' || commentsCount === 1 ? (
<>
<PlainText
__experimentalVersion={ 2 }
tagName="span"
aria-label={ singlePlaceholder }
placeholder={ singlePlaceholder }
value={ singleCommentLabel }
onChange={ ( newLabel ) =>
setAttributes( {
singleCommentLabel: newLabel,
} )
}
/>
{ showPostTitle ? postTitle : null }
</>
) : (
<>
{ showCommentsCount ? commentsCount : null }
<PlainText
__experimentalVersion={ 2 }
tagName="span"
aria-label={
showCommentsCount
? ` ${ multiplePlaceholder }`
: multiplePlaceholder
}
placeholder={
showCommentsCount
? ` ${ multiplePlaceholder }`
: multiplePlaceholder
}
value={ multipleCommentsLabel }
onChange={ ( newLabel ) =>
setAttributes( {
multipleCommentsLabel: newLabel,
} )
}
/>
{ showPostTitle ? postTitle : null }
</>
) }
</TagName>
</>
);
}
4 changes: 4 additions & 0 deletions packages/block-library/src/comments-title/editor.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

.wp-block-comments-title.has-background {
padding: inherit;
}
18 changes: 18 additions & 0 deletions packages/block-library/src/comments-title/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* WordPress dependencies
*/
import { commentTitle 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 = {
icon,
edit,
};
68 changes: 68 additions & 0 deletions packages/block-library/src/comments-title/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php
/**
* Server-side rendering of the `core/comments-title` block.
*
* @package WordPress
*/

/**
* Renders the `core/comments-title` block on the server.
*
* @param array $attributes Block attributes.
*
* @return string Return the post comments title.
*/
function render_block_core_comments_title( $attributes ) {

$align_class_name = empty( $attributes['textAlign'] ) ? '' : "has-text-align-{$attributes['textAlign']}";
$show_post_title = ! empty( $attributes['showPostTitle'] ) && $attributes['showPostTitle'];
$show_comments_count = ! empty( $attributes['showCommentsCount'] ) && $attributes['showCommentsCount'];
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $align_class_name ) );
$post_title = $show_post_title ? sprintf( '"%1$s"', get_the_title() ) : null;
$comments_count = number_format_i18n( get_comments_number() );
$tag_name = 'h2';
if ( isset( $attributes['level'] ) ) {
$tag_name = 'h' . $attributes['level'];
}

if ( '0' === $comments_count ) {
return;
}

$single_default_comment_label = $show_post_title ? __( 'One response to' ) : __( 'One response' );
$single_comment_label = ! empty( $attributes['singleCommentLabel'] ) ? $attributes['singleCommentLabel'] : $single_default_comment_label;

$multiple_default_comment_label = $show_post_title ? __( 'Responses to' ) : __( 'Responses' );
$multiple_comment_label = ! empty( $attributes['multipleCommentsLabel'] ) ? $attributes['multipleCommentsLabel'] : $multiple_default_comment_label;

$comments_title = '%1$s %2$s %3$s';

$comments_title = sprintf(
$comments_title,
// If there is only one comment, only display the label.
'1' !== $comments_count && $show_comments_count ? $comments_count : null,
'1' === $comments_count ? $single_comment_label : $multiple_comment_label,
$post_title
);

return sprintf(
'<%1$s id="comments" %2$s>%3$s</%1$s>',
$tag_name,
$wrapper_attributes,
$comments_title
);
}

/**
* Registers the `core/comments-title` block on the server.
*/
function register_block_core_comments_title() {
register_block_type_from_metadata(
__DIR__ . '/comments-title',
array(
'render_callback' => 'render_block_core_comments_title',
)
);
}

add_action( 'init', 'register_block_core_comments_title' );
Loading

0 comments on commit a1a1468

Please sign in to comment.