From 33c8d8e13d164776d251f33da3b2f086f4c8b7c6 Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Tue, 8 Jun 2021 10:43:56 +0300 Subject: [PATCH 1/5] hook creation and Post Title usage --- packages/block-library/src/post-title/edit.js | 21 +++++++++++-- packages/block-library/src/utils/hooks.js | 30 +++++++++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 packages/block-library/src/utils/hooks.js diff --git a/packages/block-library/src/post-title/edit.js b/packages/block-library/src/post-title/edit.js index 2bd3e69d00b6f..d38f1579f33bf 100644 --- a/packages/block-library/src/post-title/edit.js +++ b/packages/block-library/src/post-title/edit.js @@ -22,14 +22,16 @@ import { store as coreStore } from '@wordpress/core-data'; * Internal dependencies */ import HeadingLevelDropdown from '../heading/heading-level-dropdown'; +import { useIsEditable } from '../utils/hooks'; export default function PostTitleEdit( { + clientId, attributes: { level, textAlign, isLink, rel, linkTarget }, setAttributes, context: { postType, postId }, } ) { const TagName = 0 === level ? 'p' : 'h' + level; - + const isEditable = useIsEditable( clientId ); const post = useSelect( ( select ) => select( coreStore ).getEditedEntityRecord( @@ -60,7 +62,7 @@ export default function PostTitleEdit( { ); if ( postType && postId ) { - titleElement = ( + titleElement = isEditable ? ( + ) : ( + <TagName { ...( isLink ? {} : blockProps ) }>{ title }</TagName> ); } if ( isLink ) { - titleElement = ( + titleElement = isEditable ? ( <TagName { ...blockProps }> <PlainText tagName="a" @@ -94,6 +98,17 @@ export default function PostTitleEdit( { __experimentalVersion={ 2 } /> </TagName> + ) : ( + <TagName { ...blockProps }> + <a + href={ link } + target={ linkTarget } + rel={ rel } + onClick={ ( event ) => event.preventDefault() } + > + { title } + </a> + </TagName> ); } diff --git a/packages/block-library/src/utils/hooks.js b/packages/block-library/src/utils/hooks.js new file mode 100644 index 0000000000000..6f548690cc06e --- /dev/null +++ b/packages/block-library/src/utils/hooks.js @@ -0,0 +1,30 @@ +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data'; +import { store as blockEditorStore } from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import queryMetaData from '../query/block.json'; +const { name: queryBlockName } = queryMetaData; + +export function useIsEditable( clientId ) { + return useSelect( + ( select ) => { + const { getBlockParents, getBlockName } = select( + blockEditorStore + ); + const blockParents = getBlockParents( clientId ); + const hasQueryParent = blockParents.some( + ( parentClientId ) => + getBlockName( parentClientId ) === queryBlockName + ); + return ! hasQueryParent; + }, + [ clientId ] + ); +} + +export default { useIsEditable }; From dc53c66dd0c22c1ac10d33fbda77ca31bdd62e17 Mon Sep 17 00:00:00 2001 From: ntsekouras <ntsekouras@outlook.com> Date: Tue, 8 Jun 2021 10:57:10 +0300 Subject: [PATCH 2/5] rename hook to `useIsEditablePostBlock` and update Post Date --- packages/block-library/src/post-date/edit.js | 15 +++++++++++++-- packages/block-library/src/post-title/edit.js | 4 ++-- packages/block-library/src/utils/hooks.js | 4 ++-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/packages/block-library/src/post-date/edit.js b/packages/block-library/src/post-date/edit.js index 5e38d307404da..e9d42961a098c 100644 --- a/packages/block-library/src/post-date/edit.js +++ b/packages/block-library/src/post-date/edit.js @@ -26,10 +26,21 @@ import { import { __, sprintf } from '@wordpress/i18n'; import { edit } from '@wordpress/icons'; -export default function PostDateEdit( { attributes, context, setAttributes } ) { +/** + * Internal dependencies + */ +import { useIsEditablePostBlock } from '../utils/hooks'; + +export default function PostDateEdit( { + clientId, + attributes, + context, + setAttributes, +} ) { const { textAlign, format, isLink } = attributes; const { postId, postType } = context; + const isEditable = useIsEditablePostBlock( clientId ); const [ siteFormat ] = useEntityProp( 'root', 'site', 'date_format' ); const [ date, setDate ] = useEntityProp( 'postType', @@ -98,7 +109,7 @@ export default function PostDateEdit( { attributes, context, setAttributes } ) { } } /> - { date && ( + { date && isEditable && ( <ToolbarButton icon={ edit } title={ __( 'Change Date' ) } diff --git a/packages/block-library/src/post-title/edit.js b/packages/block-library/src/post-title/edit.js index d38f1579f33bf..d7682fc15ef28 100644 --- a/packages/block-library/src/post-title/edit.js +++ b/packages/block-library/src/post-title/edit.js @@ -22,7 +22,7 @@ import { store as coreStore } from '@wordpress/core-data'; * Internal dependencies */ import HeadingLevelDropdown from '../heading/heading-level-dropdown'; -import { useIsEditable } from '../utils/hooks'; +import { useIsEditablePostBlock } from '../utils/hooks'; export default function PostTitleEdit( { clientId, @@ -31,7 +31,7 @@ export default function PostTitleEdit( { context: { postType, postId }, } ) { const TagName = 0 === level ? 'p' : 'h' + level; - const isEditable = useIsEditable( clientId ); + const isEditable = useIsEditablePostBlock( clientId ); const post = useSelect( ( select ) => select( coreStore ).getEditedEntityRecord( diff --git a/packages/block-library/src/utils/hooks.js b/packages/block-library/src/utils/hooks.js index 6f548690cc06e..cfdd558e43b2b 100644 --- a/packages/block-library/src/utils/hooks.js +++ b/packages/block-library/src/utils/hooks.js @@ -10,7 +10,7 @@ import { store as blockEditorStore } from '@wordpress/block-editor'; import queryMetaData from '../query/block.json'; const { name: queryBlockName } = queryMetaData; -export function useIsEditable( clientId ) { +export function useIsEditablePostBlock( clientId ) { return useSelect( ( select ) => { const { getBlockParents, getBlockName } = select( @@ -27,4 +27,4 @@ export function useIsEditable( clientId ) { ); } -export default { useIsEditable }; +export default { useIsEditablePostBlock }; From 3429f176928cd6e11fed5c02f956fbb1d137aab6 Mon Sep 17 00:00:00 2001 From: ntsekouras <ntsekouras@outlook.com> Date: Tue, 8 Jun 2021 11:51:13 +0300 Subject: [PATCH 3/5] update excerpt + featured image + content --- .../block-library/src/post-content/edit.js | 38 +++++++++++++++++-- .../block-library/src/post-excerpt/edit.js | 38 ++++++++++++------- .../src/post-featured-image/edit.js | 21 +++++++--- 3 files changed, 76 insertions(+), 21 deletions(-) diff --git a/packages/block-library/src/post-content/edit.js b/packages/block-library/src/post-content/edit.js index 2d39dae73a0b2..758ee3e0be1a1 100644 --- a/packages/block-library/src/post-content/edit.js +++ b/packages/block-library/src/post-content/edit.js @@ -3,6 +3,7 @@ */ import { __ } from '@wordpress/i18n'; import { useSelect } from '@wordpress/data'; +import { useMemo, RawHTML } from '@wordpress/element'; import { useBlockProps, __experimentalUseInnerBlocksProps as useInnerBlocksProps, @@ -11,10 +12,29 @@ import { store as blockEditorStore, Warning, } from '@wordpress/block-editor'; -import { useEntityBlockEditor } from '@wordpress/core-data'; -import { useMemo } from '@wordpress/element'; +import { useEntityProp, useEntityBlockEditor } from '@wordpress/core-data'; -function Content( { layout, postType, postId } ) { +/** + * Internal dependencies + */ +import { useIsEditablePostBlock } from '../utils/hooks'; + +function ReadOnlyContent( { postType, postId } ) { + const [ , , content ] = useEntityProp( + 'postType', + postType, + 'content', + postId + ); + const blockProps = useBlockProps(); + return ( + <div { ...blockProps }> + <RawHTML key="html">{ content?.rendered }</RawHTML> + </div> + ); +} + +function EditableContent( { layout, postType, postId } ) { const themeSupportsLayout = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore ); return getSettings()?.supportsLayout; @@ -53,6 +73,16 @@ function Content( { layout, postType, postId } ) { return <div { ...props } />; } +function Content( props ) { + const { clientId, postType, postId } = props; + const isEditable = useIsEditablePostBlock( clientId ); + return isEditable ? ( + <EditableContent { ...props } /> + ) : ( + <ReadOnlyContent postType={ postType } postId={ postId } /> + ); +} + function Placeholder() { const blockProps = useBlockProps(); return ( @@ -76,6 +106,7 @@ function RecursionError() { } export default function PostContentEdit( { + clientId, context: { postId: contextPostId, postType: contextPostType }, attributes, } ) { @@ -95,6 +126,7 @@ export default function PostContentEdit( { postType={ contextPostType } postId={ contextPostId } layout={ layout } + clientId={ clientId } /> ) : ( <Placeholder /> diff --git a/packages/block-library/src/post-excerpt/edit.js b/packages/block-library/src/post-excerpt/edit.js index e2ee5498905ee..bd3ad6e3bc15e 100644 --- a/packages/block-library/src/post-excerpt/edit.js +++ b/packages/block-library/src/post-excerpt/edit.js @@ -19,6 +19,11 @@ import { import { PanelBody, RangeControl, ToggleControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; +/** + * Internal dependencies + */ +import { useIsEditablePostBlock } from '../utils/hooks'; + function usePostContentExcerpt( wordCount, postId, postType ) { // Don't destrcuture items from content here, it can be undefined. const [ , , content ] = useEntityProp( @@ -41,11 +46,13 @@ function usePostContentExcerpt( wordCount, postId, postType ) { } export default function PostExcerptEditor( { + clientId, attributes: { textAlign, wordCount, moreText, showMoreOnNewLine }, setAttributes, isSelected, context: { postId, postType }, } ) { + const isEditable = useIsEditablePostBlock( clientId ); const [ excerpt, setExcerpt ] = useEntityProp( 'postType', postType, @@ -84,6 +91,23 @@ export default function PostExcerptEditor( { } /> ); + const excerptContent = isEditable ? ( + <RichText + className={ + ! showMoreOnNewLine && + 'wp-block-post-excerpt__excerpt is-inline' + } + aria-label={ __( 'Post excerpt text' ) } + value={ + excerpt || + postContentExcerpt || + ( isSelected ? '' : __( 'No post excerpt found' ) ) + } + onChange={ setExcerpt } + /> + ) : ( + excerpt || postContentExcerpt || __( 'No post excerpt found' ) + ); return ( <> <BlockControls> @@ -119,19 +143,7 @@ export default function PostExcerptEditor( { </PanelBody> </InspectorControls> <div { ...blockProps }> - <RichText - className={ - ! showMoreOnNewLine && - 'wp-block-post-excerpt__excerpt is-inline' - } - aria-label={ __( 'Post excerpt text' ) } - value={ - excerpt || - postContentExcerpt || - ( isSelected ? '' : __( 'No post excerpt found' ) ) - } - onChange={ setExcerpt } - /> + { excerptContent } { ! showMoreOnNewLine && ' ' } { showMoreOnNewLine ? ( <p className="wp-block-post-excerpt__more-text"> diff --git a/packages/block-library/src/post-featured-image/edit.js b/packages/block-library/src/post-featured-image/edit.js index 3acbef2776273..59c5fdac00ca8 100644 --- a/packages/block-library/src/post-featured-image/edit.js +++ b/packages/block-library/src/post-featured-image/edit.js @@ -20,6 +20,11 @@ import { import { __, sprintf } from '@wordpress/i18n'; import { postFeaturedImage } from '@wordpress/icons'; +/** + * Internal dependencies + */ +import { useIsEditablePostBlock } from '../utils/hooks'; + const ALLOWED_MEDIA_TYPES = [ 'image' ]; const placeholderChip = ( <div className="post-featured-image_placeholder"> @@ -29,12 +34,14 @@ const placeholderChip = ( ); function PostFeaturedImageDisplay( { + clientId, attributes: { isLink }, setAttributes, context: { postId, postType }, noticeUI, noticeOperations, } ) { + const isEditable = useIsEditablePostBlock( clientId ); const [ featuredImage, setFeaturedImage ] = useEntityProp( 'postType', postType, @@ -46,6 +53,7 @@ function PostFeaturedImageDisplay( { featuredImage && select( coreStore ).getMedia( featuredImage ), [ featuredImage ] ); + const blockProps = useBlockProps(); const onSelectImage = ( value ) => { if ( value?.id ) { setFeaturedImage( value.id ); @@ -56,6 +64,9 @@ function PostFeaturedImageDisplay( { noticeOperations.createErrorNotice( message ); } let image; + if ( ! featuredImage && ! isEditable ) { + return <div { ...blockProps }>{ placeholderChip }</div>; + } if ( ! featuredImage ) { image = ( <MediaPlaceholder @@ -100,8 +111,8 @@ function PostFeaturedImageDisplay( { /> </PanelBody> </InspectorControls> - <BlockControls group="other"> - { !! media && ( + { !! media && isEditable && ( + <BlockControls group="other"> <MediaReplaceFlow mediaId={ featuredImage } mediaURL={ media.source_url } @@ -110,9 +121,9 @@ function PostFeaturedImageDisplay( { onSelect={ onSelectImage } onError={ onUploadError } /> - ) } - </BlockControls> - <figure { ...useBlockProps() }>{ image }</figure> + </BlockControls> + ) } + <figure { ...blockProps }>{ image }</figure> </> ); } From 52820b67b1701a4b57a5e2f3ecf3880d3a60024f Mon Sep 17 00:00:00 2001 From: ntsekouras <ntsekouras@outlook.com> Date: Tue, 8 Jun 2021 12:28:44 +0300 Subject: [PATCH 4/5] update Post author --- packages/block-library/src/post-author/edit.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/post-author/edit.js b/packages/block-library/src/post-author/edit.js index 6110b36338230..4c5e0d4f4bcf3 100644 --- a/packages/block-library/src/post-author/edit.js +++ b/packages/block-library/src/post-author/edit.js @@ -19,9 +19,21 @@ import { useSelect, useDispatch } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; import { store as coreStore } from '@wordpress/core-data'; -function PostAuthorEdit( { isSelected, context, attributes, setAttributes } ) { +/** + * Internal dependencies + */ +import { useIsEditablePostBlock } from '../utils/hooks'; + +function PostAuthorEdit( { + clientId, + isSelected, + context, + attributes, + setAttributes, +} ) { const { postType, postId } = context; + const isEditable = useIsEditablePostBlock( clientId ); const { authorId, authorDetails, authors } = useSelect( ( select ) => { const { getEditedEntityRecord, getUser, getUsers } = select( @@ -66,7 +78,7 @@ function PostAuthorEdit( { isSelected, context, attributes, setAttributes } ) { <> <InspectorControls> <PanelBody title={ __( 'Author Settings' ) }> - { !! authors?.length && ( + { isEditable && !! authors?.length && ( <SelectControl label={ __( 'Author' ) } value={ authorId } From 07458b65c1db906388af9ccb814ccb8333830609 Mon Sep 17 00:00:00 2001 From: ntsekouras <ntsekouras@outlook.com> Date: Tue, 8 Jun 2021 13:10:57 +0300 Subject: [PATCH 5/5] add jsdoc --- packages/block-library/src/utils/hooks.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/block-library/src/utils/hooks.js b/packages/block-library/src/utils/hooks.js index cfdd558e43b2b..c2ad1ee8999e6 100644 --- a/packages/block-library/src/utils/hooks.js +++ b/packages/block-library/src/utils/hooks.js @@ -10,6 +10,17 @@ import { store as blockEditorStore } from '@wordpress/block-editor'; import queryMetaData from '../query/block.json'; const { name: queryBlockName } = queryMetaData; +/** + * Hook that determines if a Post block is editable or not. + * The returned value is used to determine if the specific + * Post block will be rendered in `readonly` mode or not. + * + * For now this is checking if a Post block is nested in + * a Query block. If it is, the block should not be editable. + * + * @param {string} clientId The ID of the block to be checked. + * @return {boolean} Whether the block can be edited or not. + */ export function useIsEditablePostBlock( clientId ) { return useSelect( ( select ) => {