diff --git a/lib/block-patterns.php b/lib/block-patterns.php index b9b48ce2cc2776..a7b7554694e56e 100644 --- a/lib/block-patterns.php +++ b/lib/block-patterns.php @@ -81,7 +81,7 @@ function register_gutenberg_patterns() {
- +
diff --git a/packages/block-library/src/post-excerpt/block.json b/packages/block-library/src/post-excerpt/block.json index 9010f9f486235f..a066c4250a88ca 100644 --- a/packages/block-library/src/post-excerpt/block.json +++ b/packages/block-library/src/post-excerpt/block.json @@ -9,10 +9,6 @@ "textAlign": { "type": "string" }, - "wordCount": { - "type": "number", - "default": 55 - }, "moreText": { "type": "string" }, diff --git a/packages/block-library/src/post-excerpt/edit.js b/packages/block-library/src/post-excerpt/edit.js index 0df53eb1879235..4c541f4c391276 100644 --- a/packages/block-library/src/post-excerpt/edit.js +++ b/packages/block-library/src/post-excerpt/edit.js @@ -16,7 +16,7 @@ import { Warning, useBlockProps, } from '@wordpress/block-editor'; -import { PanelBody, RangeControl, ToggleControl } from '@wordpress/components'; +import { PanelBody, ToggleControl, Disabled } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; /** @@ -24,29 +24,8 @@ import { __ } from '@wordpress/i18n'; */ import { useCanEditEntity } from '../utils/hooks'; -function usePostContentExcerpt( wordCount, postId, postType ) { - // Don't destrcuture items from content here, it can be undefined. - const [ , , content ] = useEntityProp( - 'postType', - postType, - 'content', - postId - ); - const renderedPostContent = content?.rendered; - return useMemo( () => { - if ( ! renderedPostContent ) { - return ''; - } - const excerptElement = document.createElement( 'div' ); - excerptElement.innerHTML = renderedPostContent; - const excerpt = - excerptElement.textContent || excerptElement.innerText || ''; - return excerpt.trim().split( ' ', wordCount ).join( ' ' ); - }, [ renderedPostContent, wordCount ] ); -} - export default function PostExcerptEditor( { - attributes: { textAlign, wordCount, moreText, showMoreOnNewLine }, + attributes: { textAlign, moreText, showMoreOnNewLine }, setAttributes, isSelected, context: { postId, postType, queryId }, @@ -59,16 +38,24 @@ export default function PostExcerptEditor( { setExcerpt, { rendered: renderedExcerpt, protected: isProtected } = {}, ] = useEntityProp( 'postType', postType, 'excerpt', postId ); - const postContentExcerpt = usePostContentExcerpt( - wordCount, - postId, - postType - ); const blockProps = useBlockProps( { className: classnames( { [ `has-text-align-${ textAlign }` ]: textAlign, } ), } ); + /** + * When excerpt is editable, strip the html tags from + * rendered excerpt. This will be used if the entity's + * excerpt has been produced from the content. + */ + const strippedRenderedExcerpt = useMemo( () => { + if ( ! renderedExcerpt ) return ''; + const document = new window.DOMParser().parseFromString( + renderedExcerpt, + 'text/html' + ); + return document.body.textContent || document.body.innerText || ''; + }, [ renderedExcerpt ] ); if ( ! postType || ! postId ) { return (
@@ -110,16 +97,17 @@ export default function PostExcerptEditor( { aria-label={ __( 'Post excerpt text' ) } value={ rawExcerpt || - postContentExcerpt || + strippedRenderedExcerpt || ( isSelected ? '' : __( 'No post excerpt found' ) ) } onChange={ setExcerpt } /> ) : ( ( renderedExcerpt && ( - { renderedExcerpt } + + { renderedExcerpt } + ) ) || - postContentExcerpt || __( 'No post excerpt found' ) ); return ( @@ -134,17 +122,6 @@ export default function PostExcerptEditor( { - { ! renderedExcerpt && ( - - setAttributes( { wordCount: newExcerptLength } ) - } - min={ 10 } - max={ 100 } - /> - ) } ' . $attributes['moreText'] . '' : ''; - - $filter_excerpt_length = function() use ( $attributes ) { - return isset( $attributes['wordCount'] ) ? $attributes['wordCount'] : 55; + $more_text = ! empty( $attributes['moreText'] ) ? '' . $attributes['moreText'] . '' : ''; + $filter_excerpt_more = function( $more ) use ( $more_text ) { + return empty( $more_text ) ? $more : ''; }; - add_filter( - 'excerpt_length', - $filter_excerpt_length - ); - + /** + * Some themes might use `excerpt_more` filter to handle the + * `more` link displayed after a trimmed excerpt. Since the + * block has a `more text` attribute we have to check and + * override if needed the return value from this filter. + * So if the block's attribute is not empty override the + * `excerpt_more` filter and return nothing. This will + * result in showing only one `read more` link at a time. + */ + add_filter( 'excerpt_more', $filter_excerpt_more ); $classes = ''; if ( isset( $attributes['textAlign'] ) ) { - $classes .= 'has-text-align-' . $attributes['textAlign']; + $classes .= "has-text-align-{$attributes['textAlign']}"; } $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classes ) ); - $content = '

' . get_the_excerpt( $block->context['postId'] ); - if ( ! isset( $attributes['showMoreOnNewLine'] ) || $attributes['showMoreOnNewLine'] ) { + $content = '

' . get_the_excerpt( $block->context['postId'] ); + $show_more_on_new_line = ! isset( $attributes['showMoreOnNewLine'] ) || $attributes['showMoreOnNewLine']; + if ( $show_more_on_new_line && ! empty( $more_text ) ) { $content .= '

' . $more_text . '

'; } else { $content .= " $more_text

"; } - - remove_filter( - 'excerpt_length', - $filter_excerpt_length - ); - + remove_filter( 'excerpt_more', $filter_excerpt_more ); return sprintf( '
%2$s
', $wrapper_attributes, $content ); } diff --git a/packages/e2e-tests/fixtures/blocks/core__post-excerpt.json b/packages/e2e-tests/fixtures/blocks/core__post-excerpt.json index 57d658a4423d05..4378d6e27b6071 100644 --- a/packages/e2e-tests/fixtures/blocks/core__post-excerpt.json +++ b/packages/e2e-tests/fixtures/blocks/core__post-excerpt.json @@ -4,7 +4,6 @@ "name": "core/post-excerpt", "isValid": true, "attributes": { - "wordCount": 55, "showMoreOnNewLine": true }, "innerBlocks": [],