diff --git a/packages/block-library/src/post-excerpt/edit.js b/packages/block-library/src/post-excerpt/edit.js index 10e36e267504d6..c88a4ab9368829 100644 --- a/packages/block-library/src/post-excerpt/edit.js +++ b/packages/block-library/src/post-excerpt/edit.js @@ -6,7 +6,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { useEntityProp } from '@wordpress/core-data'; +import { useEntityProp, store as coreStore } from '@wordpress/core-data'; import { useMemo } from '@wordpress/element'; import { AlignmentToolbar, @@ -18,12 +18,15 @@ import { } from '@wordpress/block-editor'; import { PanelBody, ToggleControl, RangeControl } from '@wordpress/components'; import { __, _x } from '@wordpress/i18n'; +import { useSelect } from '@wordpress/data'; /** * Internal dependencies */ import { useCanEditEntity } from '../utils/hooks'; +const ELLIPSIS = '…'; + export default function PostExcerptEditor( { attributes: { textAlign, moreText, showMoreOnNewLine, excerptLength }, setAttributes, @@ -32,13 +35,41 @@ export default function PostExcerptEditor( { } ) { const isDescendentOfQueryLoop = Number.isFinite( queryId ); const userCanEdit = useCanEditEntity( 'postType', postType, postId ); - const isEditable = userCanEdit && ! isDescendentOfQueryLoop; - const [ rawExcerpt, setExcerpt, { rendered: renderedExcerpt, protected: isProtected } = {}, ] = useEntityProp( 'postType', postType, 'excerpt', postId ); + + /** + * Check if the post type supports excerpts. + * Add an exception and return early for the "page" post type, + * which is registered without support for the excerpt UI, + * but supports saving the excerpt to the database. + * See: https://core.trac.wordpress.org/browser/branches/6.1/src/wp-includes/post.php#L65 + * Without this exception, users that have excerpts saved to the database will + * not be able to edit the excerpts. + */ + const postTypeSupportsExcerpts = useSelect( + ( select ) => { + if ( postType === 'page' ) { + return true; + } + return !! select( coreStore ).getPostType( postType )?.supports + .excerpt; + }, + [ postType ] + ); + + /** + * The excerpt is editable if: + * - The user can edit the post + * - It is not a descendent of a Query Loop block + * - The post type supports excerpts + */ + const isEditable = + userCanEdit && ! isDescendentOfQueryLoop && postTypeSupportsExcerpts; + const blockProps = useBlockProps( { className: classnames( { [ `has-text-align-${ textAlign }` ]: textAlign, @@ -65,6 +96,7 @@ export default function PostExcerptEditor( { ); return document.body.textContent || document.body.innerText || ''; }, [ renderedExcerpt ] ); + if ( ! postType || ! postId ) { return ( <> @@ -123,14 +155,13 @@ export default function PostExcerptEditor( { * The excerpt length setting needs to be applied to both * the raw and the rendered excerpt depending on which is being used. */ - const rawOrRenderedExcerpt = !! renderedExcerpt - ? strippedRenderedExcerpt - : rawExcerpt; + const rawOrRenderedExcerpt = ( + rawExcerpt || strippedRenderedExcerpt + ).trim(); let trimmedExcerpt = ''; if ( wordCountType === 'words' ) { trimmedExcerpt = rawOrRenderedExcerpt - .trim() .split( ' ', excerptLength ) .join( ' ' ); } else if ( wordCountType === 'characters_excluding_spaces' ) { @@ -143,7 +174,6 @@ export default function PostExcerptEditor( { * so that the spaces are excluded from the word count. */ const excerptWithSpaces = rawOrRenderedExcerpt - .trim() .split( '', excerptLength ) .join( '' ); @@ -152,17 +182,15 @@ export default function PostExcerptEditor( { excerptWithSpaces.replaceAll( ' ', '' ).length; trimmedExcerpt = rawOrRenderedExcerpt - .trim() .split( '', excerptLength + numberOfSpaces ) .join( '' ); } else if ( wordCountType === 'characters_including_spaces' ) { trimmedExcerpt = rawOrRenderedExcerpt - .trim() .split( '', excerptLength ) .join( '' ); } - trimmedExcerpt = trimmedExcerpt + '...'; + const isTrimmed = trimmedExcerpt !== rawOrRenderedExcerpt; const excerptContent = isEditable ? ( ) : (

- { trimmedExcerpt !== '...' - ? trimmedExcerpt - : __( 'No post excerpt found' ) } + { ! isTrimmed + ? rawOrRenderedExcerpt || __( 'No post excerpt found' ) + : trimmedExcerpt + ELLIPSIS }

); return ( @@ -211,7 +241,6 @@ export default function PostExcerptEditor( { value={ excerptLength } onChange={ ( value ) => { setAttributes( { excerptLength: value } ); - setExcerpt(); } } min="10" max="100"