Skip to content

Commit

Permalink
[ New Block ] Add Query Total block for displaying total query result…
Browse files Browse the repository at this point in the history
…s or ranges (#67629)

Co-authored-by: sarthaknagoshe2002 <[email protected]>
Co-authored-by: fabiankaegy <[email protected]>
Co-authored-by: gziolo <[email protected]>
Co-authored-by: jasmussen <[email protected]>
Co-authored-by: codersantosh <[email protected]>
Co-authored-by: bhubbard <[email protected]>
  • Loading branch information
7 people authored Dec 10, 2024
1 parent eeaef67 commit e4124df
Show file tree
Hide file tree
Showing 13 changed files with 321 additions and 0 deletions.
10 changes: 10 additions & 0 deletions docs/reference-guides/core-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,16 @@ Display the query title. ([Source](https://github.com/WordPress/gutenberg/tree/t
- **Supports:** align (full, wide), color (background, gradients, text), interactivity (clientNavigation), spacing (margin, padding), typography (fontSize, lineHeight), ~~html~~
- **Attributes:** level, levelOptions, showPrefix, showSearchTerm, textAlign, type

## Query Total

Display the total number of results in a query. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/query-total))

- **Name:** core/query-total
- **Category:** theme
- **Ancestor:** core/query
- **Supports:** align (full, wide), color (background, gradients, text), spacing (margin, padding), typography (fontSize, lineHeight), ~~html~~
- **Attributes:** displayType

## Quote

Give quoted text visual emphasis. "In quoting others, we cite ourselves." — Julio Cortázar ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/quote))
Expand Down
1 change: 1 addition & 0 deletions lib/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ function gutenberg_reregister_core_block_types() {
'query-pagination-numbers.php' => 'core/query-pagination-numbers',
'query-pagination-previous.php' => 'core/query-pagination-previous',
'query-title.php' => 'core/query-title',
'query-total.php' => 'core/query-total',
'read-more.php' => 'core/read-more',
'rss.php' => 'core/rss',
'search.php' => 'core/search',
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 @@ -99,6 +99,7 @@ import * as queryPaginationNext from './query-pagination-next';
import * as queryPaginationNumbers from './query-pagination-numbers';
import * as queryPaginationPrevious from './query-pagination-previous';
import * as queryTitle from './query-title';
import * as queryTotal from './query-total';
import * as quote from './quote';
import * as reusableBlock from './block';
import * as readMore from './read-more';
Expand Down Expand Up @@ -211,6 +212,7 @@ const getAllBlocks = () => {
queryPaginationNumbers,
queryPaginationPrevious,
queryNoResults,
queryTotal,
readMore,
comments,
commentAuthorName,
Expand Down
45 changes: 45 additions & 0 deletions packages/block-library/src/query-total/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "core/query-total",
"title": "Query Total",
"category": "theme",
"ancestor": [ "core/query" ],
"description": "Display the total number of results in a query.",
"textdomain": "default",
"attributes": {
"displayType": {
"type": "string",
"default": "total-results"
}
},
"usesContext": [ "queryId", "query" ],
"supports": {
"align": [ "wide", "full" ],
"html": false,
"spacing": {
"margin": true,
"padding": true
},
"color": {
"gradients": true,
"text": true,
"__experimentalDefaultControls": {
"background": true
}
},
"typography": {
"fontSize": true,
"lineHeight": true,
"__experimentalFontFamily": true,
"__experimentalFontWeight": true,
"__experimentalFontStyle": true,
"__experimentalTextTransform": true,
"__experimentalTextDecoration": true,
"__experimentalLetterSpacing": true,
"__experimentalDefaultControls": {
"fontSize": true
}
}
}
}
83 changes: 83 additions & 0 deletions packages/block-library/src/query-total/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* WordPress dependencies
*/
import { useBlockProps, BlockControls } from '@wordpress/block-editor';
import { ToolbarGroup, ToolbarDropdownMenu } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import { resultsFound, displayingResults } from './icons';

export default function QueryTotalEdit( { attributes, setAttributes } ) {
const { displayType } = attributes;

// Block properties and classes.
const blockProps = useBlockProps();

const getButtonPositionIcon = () => {
switch ( displayType ) {
case 'total-results':
return resultsFound;
case 'range-display':
return displayingResults;
}
};

const buttonPositionControls = [
{
role: 'menuitemradio',
title: __( 'Total results' ),
isActive: displayType === 'total-results',
icon: resultsFound,
onClick: () => {
setAttributes( { displayType: 'total-results' } );
},
},
{
role: 'menuitemradio',
title: __( 'Range display' ),
isActive: displayType === 'range-display',
icon: displayingResults,
onClick: () => {
setAttributes( { displayType: 'range-display' } );
},
},
];

// Controls for the block.
const controls = (
<>
<BlockControls>
<ToolbarGroup>
<ToolbarDropdownMenu
icon={ getButtonPositionIcon() }
label={ __( 'Change display type' ) }
controls={ buttonPositionControls }
/>
</ToolbarGroup>
</BlockControls>
</>
);

// Render output based on the selected display type.
const renderDisplay = () => {
if ( displayType === 'total-results' ) {
return <div>{ __( '12 results found' ) }</div>;
}

if ( displayType === 'range-display' ) {
return <div>{ __( 'Displaying 1 – 10 of 12' ) }</div>;
}

return null;
};

return (
<div { ...blockProps }>
{ controls }
{ renderDisplay() }
</div>
);
}
43 changes: 43 additions & 0 deletions packages/block-library/src/query-total/icons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* WordPress dependencies
*/
import { SVG, Path } from '@wordpress/components';

export const resultsFound = (
<SVG
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24"
aria-hidden="true"
focusable="false"
>
<Path d="M4 11h4v2H4v-2zm6 0h6v2h-6v-2zm8 0h2v2h-2v-2z" />
</SVG>
);

export const displayingResults = (
<SVG
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24"
aria-hidden="true"
focusable="false"
>
<Path d="M4 13h2v-2H4v2zm4 0h10v-2H8v2zm12 0h2v-2h-2v2z" />
</SVG>
);

export const queryTotal = (
<SVG
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24"
aria-hidden="true"
focusable="false"
>
<Path d="M18 4H6c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2Zm.5 14c0 .3-.2.5-.5.5H6c-.3 0-.5-.2-.5-.5V6c0-.3.2-.5.5-.5h12c.3 0 .5.2.5.5v12Zm-7-6-4.1 5h8.8v-3h-1.5v1.5h-4.2l2.9-3.5-2.9-3.5h4.2V10h1.5V7H7.4l4.1 5Z" />
</SVG>
);
18 changes: 18 additions & 0 deletions packages/block-library/src/query-total/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';
import initBlock from '../utils/init-block';
import { queryTotal } from './icons';

/* Block settings */
const { name } = metadata;
export { metadata, name };

export const settings = {
icon: queryTotal,
edit,
};

export const init = () => initBlock( { name, metadata, settings } );
92 changes: 92 additions & 0 deletions packages/block-library/src/query-total/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php
/**
* Server-side rendering of the `core/query-total` block.
*
* @package WordPress
*/

/**
* Renders the `query-total` block on the server.
*
* @since 6.8.0
*
* @param array $attributes Block attributes.
* @param string $content Block default content.
* @param WP_Block $block Block instance.
*
* @return string The rendered block content.
*/
function render_block_core_query_total( $attributes, $content, $block ) {
global $wp_query;
$wrapper_attributes = get_block_wrapper_attributes();
if ( isset( $block->context['query']['inherit'] ) && $block->context['query']['inherit'] ) {
$query_to_use = $wp_query;
$current_page = max( 1, get_query_var( 'paged', 1 ) );
} else {
$page_key = isset( $block->context['queryId'] ) ? 'query-' . $block->context['queryId'] . '-page' : 'query-page';
$current_page = isset( $_GET[ $page_key ] ) ? (int) $_GET[ $page_key ] : 1;
$query_to_use = new WP_Query( build_query_vars_from_query_block( $block, $current_page ) );
}

$max_rows = $query_to_use->found_posts;
$posts_per_page = $query_to_use->get( 'posts_per_page' );

// Calculate the range of posts being displayed.
$start = ( $current_page - 1 ) * $posts_per_page + 1;
$end = min( $start + $posts_per_page - 1, $max_rows );

// Prepare the display based on the `displayType` attribute.
$output = '';
switch ( $attributes['displayType'] ) {
case 'range-display':
if ( $start === $end ) {
$range_text = sprintf(
/* translators: 1: Start index of posts, 2: Total number of posts */
__( 'Displaying %1$s of %2$s' ),
'<strong>' . $start . '</strong>',
'<strong>' . $max_rows . '</strong>'
);
} else {
$range_text = sprintf(
/* translators: 1: Start index of posts, 2: End index of posts, 3: Total number of posts */
__( 'Displaying %1$s – %2$s of %3$s' ),
'<strong>' . $start . '</strong>',
'<strong>' . $end . '</strong>',
'<strong>' . $max_rows . '</strong>'
);
}

$output = sprintf( '<p>%s</p>', $range_text );
break;

case 'total-results':
default:
$output = sprintf(
'<p><strong>%d</strong> %s</p>',
$max_rows,
_n( 'result found', 'results found', $max_rows )
);
break;
}

return sprintf(
'<div %1$s>%2$s</div>',
$wrapper_attributes,
$output
);
}

/**
* Registers the `query-total` block.
*
* @since 6.8.0
*/
function register_block_core_query_total() {
register_block_type_from_metadata(
__DIR__ . '/query-total',
array(
'render_callback' => 'render_block_core_query_total',
)
);
}
add_action( 'init', 'register_block_core_query_total' );
6 changes: 6 additions & 0 deletions packages/block-library/src/query-total/init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Internal dependencies
*/
import { init } from './';

export default init();
1 change: 1 addition & 0 deletions test/integration/fixtures/blocks/core__query-total.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!-- wp:query-total /-->
10 changes: 10 additions & 0 deletions test/integration/fixtures/blocks/core__query-total.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"name": "core/query-total",
"isValid": true,
"attributes": {
"displayType": "total-results"
},
"innerBlocks": []
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[
{
"blockName": "core/query-total",
"attrs": {},
"innerBlocks": [],
"innerHTML": "",
"innerContent": []
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!-- wp:query-total /-->

0 comments on commit e4124df

Please sign in to comment.