diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md
index 66f713b3aa40fc..7014f5a1ac6579 100644
--- a/docs/reference-guides/core-blocks.md
+++ b/docs/reference-guides/core-blocks.md
@@ -543,13 +543,13 @@ Show a block pattern. ([Source](https://github.com/WordPress/gutenberg/tree/trun
- **Supports:** interactivity (clientNavigation), ~~html~~, ~~inserter~~, ~~renaming~~
- **Attributes:** slug
-## Author
+## Author (deprecated)
-Display post author details such as name, avatar, and bio. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-author))
+This block is deprecated. Please use the Avatar block, the Author Name block, and the Author Biography block instead. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/post-author))
- **Name:** core/post-author
- **Category:** theme
-- **Supports:** color (background, gradients, link, text), interactivity (clientNavigation), spacing (margin, padding), typography (fontSize, lineHeight), ~~html~~
+- **Supports:** color (background, gradients, link, text), interactivity (clientNavigation), spacing (margin, padding), typography (fontSize, lineHeight), ~~html~~, ~~inserter~~
- **Attributes:** avatarSize, byline, isLink, linkTarget, showAvatar, showBio, textAlign
## Author Biography
diff --git a/packages/block-editor/src/components/block-inspector/index.js b/packages/block-editor/src/components/block-inspector/index.js
index 475d4f6a4b8c2e..559a19d776f51a 100644
--- a/packages/block-editor/src/components/block-inspector/index.js
+++ b/packages/block-editor/src/components/block-inspector/index.js
@@ -27,6 +27,7 @@ import AdvancedControls from '../inspector-controls-tabs/advanced-controls-panel
import PositionControls from '../inspector-controls-tabs/position-controls-panel';
import useBlockInspectorAnimationSettings from './useBlockInspectorAnimationSettings';
import BlockInfo from '../block-info-slot-fill';
+import InspectorControlsLastItem from '../inspector-controls-last-item-slot-fill';
import BlockQuickNavigation from '../block-quick-navigation';
import { useBorderPanelLabel } from '../../hooks/border';
@@ -255,12 +256,15 @@ const BlockInspectorSingleBlock = ( {
{ showTabs && (
-
+ <>
+
+
+ >
) }
{ ! showTabs && (
<>
@@ -309,6 +313,35 @@ const BlockInspectorSingleBlock = ( {
>
) }
+
+
+
+
+
+
+
+
+
+
+
>
) }
diff --git a/packages/block-editor/src/components/inspector-controls-last-item-slot-fill/index.js b/packages/block-editor/src/components/inspector-controls-last-item-slot-fill/index.js
new file mode 100644
index 00000000000000..75decb7cefe000
--- /dev/null
+++ b/packages/block-editor/src/components/inspector-controls-last-item-slot-fill/index.js
@@ -0,0 +1,27 @@
+/**
+ * WordPress dependencies
+ */
+import { privateApis as componentsPrivateApis } from '@wordpress/components';
+
+/**
+ * Internal dependencies
+ */
+import { unlock } from '../../lock-unlock';
+import {
+ useBlockEditContext,
+ mayDisplayControlsKey,
+} from '../block-edit/context';
+
+const { createPrivateSlotFill } = unlock( componentsPrivateApis );
+const { Fill, Slot } = createPrivateSlotFill( 'InspectorControlsLastItem' );
+
+const InspectorControlsLastItem = ( props ) => {
+ const context = useBlockEditContext();
+ if ( ! context[ mayDisplayControlsKey ] ) {
+ return null;
+ }
+ return ;
+};
+InspectorControlsLastItem.Slot = ( props ) => ;
+
+export default InspectorControlsLastItem;
diff --git a/packages/block-editor/src/private-apis.js b/packages/block-editor/src/private-apis.js
index 7205bef5798ec1..76fd9105c7fb96 100644
--- a/packages/block-editor/src/private-apis.js
+++ b/packages/block-editor/src/private-apis.js
@@ -14,6 +14,7 @@ import {
} from './components/inserter/search-items';
import { PrivateListView } from './components/list-view';
import BlockInfo from './components/block-info-slot-fill';
+import InspectorControlsLastItem from './components/inspector-controls-last-item-slot-fill';
import { useHasBlockToolbar } from './components/block-toolbar/use-has-block-toolbar';
import { cleanEmptyObject } from './hooks/utils';
import BlockQuickNavigation from './components/block-quick-navigation';
@@ -65,6 +66,7 @@ lock( privateApis, {
PrivateListView,
ResizableBoxPopover,
BlockInfo,
+ InspectorControlsLastItem,
useHasBlockToolbar,
cleanEmptyObject,
BlockQuickNavigation,
diff --git a/packages/block-library/src/post-author/block.json b/packages/block-library/src/post-author/block.json
index d66498c8ee3df9..7626774798ab09 100644
--- a/packages/block-library/src/post-author/block.json
+++ b/packages/block-library/src/post-author/block.json
@@ -2,9 +2,9 @@
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "core/post-author",
- "title": "Author",
+ "title": "Author (deprecated)",
"category": "theme",
- "description": "Display post author details such as name, avatar, and bio.",
+ "description": "This block is deprecated. Please use the Avatar block, the Author Name block, and the Author Biography block instead.",
"textdomain": "default",
"attributes": {
"textAlign": {
@@ -35,6 +35,7 @@
},
"usesContext": [ "postType", "postId", "queryId" ],
"supports": {
+ "inserter": false,
"html": false,
"spacing": {
"margin": true,
diff --git a/packages/block-library/src/post-author/edit.js b/packages/block-library/src/post-author/edit.js
index 6186b0d052e8aa..ea12f1e8d0fc2e 100644
--- a/packages/block-library/src/post-author/edit.js
+++ b/packages/block-library/src/post-author/edit.js
@@ -12,18 +12,30 @@ import {
InspectorControls,
RichText,
useBlockProps,
+ store as blockEditorStore,
+ privateApis as blockEditorPrivateApis,
} from '@wordpress/block-editor';
import {
+ Button,
ComboboxControl,
PanelBody,
SelectControl,
ToggleControl,
+ __experimentalText as Text,
__experimentalVStack as VStack,
} from '@wordpress/components';
import { useSelect, useDispatch } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { store as coreStore } from '@wordpress/core-data';
+/**
+ * Internal dependencies
+ */
+import { migrateToRecommendedBlocks } from './utils';
+import { unlock } from '../lock-unlock';
+
+const { InspectorControlsLastItem } = unlock( blockEditorPrivateApis );
+
const minimumUsersForCombobox = 25;
const AUTHORS_QUERY = {
@@ -36,6 +48,7 @@ function PostAuthorEdit( {
context: { postType, postId, queryId },
attributes,
setAttributes,
+ clientId,
} ) {
const isDescendentOfQueryLoop = Number.isFinite( queryId );
const { authorId, authorDetails, authors } = useSelect(
@@ -58,6 +71,7 @@ function PostAuthorEdit( {
);
const { editEntityRecord } = useDispatch( coreStore );
+ const { replaceBlock } = useDispatch( blockEditorStore );
const { textAlign, showAvatar, showBio, byline, isLink, linkTarget } =
attributes;
@@ -97,6 +111,10 @@ function PostAuthorEdit( {
const showAuthorControl =
!! postId && ! isDescendentOfQueryLoop && authorOptions.length > 0;
+ function transformBlock() {
+ replaceBlock( clientId, migrateToRecommendedBlocks( attributes ) );
+ }
+
return (
<>
@@ -179,6 +197,26 @@ function PostAuthorEdit( {
+
+
+
+ { __(
+ 'This block is no longer supported. Please migrate to the Author Name, Avatar, and Biography blocks to design youor content as needed.'
+ ) }
+
+
+
+
+ migrateToRecommendedBlocks( attributes ),
+ },
+ ],
+};
+
+export default transforms;
diff --git a/packages/block-library/src/post-author/utils.js b/packages/block-library/src/post-author/utils.js
new file mode 100644
index 00000000000000..4baeba336a94f5
--- /dev/null
+++ b/packages/block-library/src/post-author/utils.js
@@ -0,0 +1,115 @@
+/**
+ * WordPress dependencies
+ */
+import { createBlock } from '@wordpress/blocks';
+import { __ } from '@wordpress/i18n';
+import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';
+
+/**
+ * Internal dependencies
+ */
+import { unlock } from '../lock-unlock';
+
+const { cleanEmptyObject } = unlock( blockEditorPrivateApis );
+
+/**
+ * Generate Author-related blocks based on block attributes.
+ *
+ * @param {Object} attributes Block's attributes.
+ *
+ * @return {Object} Generated block.
+ */
+export function migrateToRecommendedBlocks( attributes ) {
+ const {
+ avatarSize,
+ byline,
+ showAvatar,
+ showBio,
+ isLink,
+ linkTarget,
+ textAlign,
+ style,
+ ...restAttributes
+ } = attributes;
+
+ return createBlock(
+ 'core/group',
+ {
+ ...restAttributes,
+ style: cleanEmptyObject( {
+ ...style,
+ spacing: {
+ blockGap: '1em',
+ },
+ color: {
+ ...style?.color,
+ // Duotone must be applied to the avatar block.
+ duotone: undefined,
+ },
+ } ),
+ layout: {
+ type: 'flex',
+ flexWrap: 'nowrap',
+ verticalAlignment: 'top',
+ },
+ },
+ [
+ showAvatar &&
+ createBlock( 'core/avatar', {
+ size: avatarSize,
+ style: cleanEmptyObject( {
+ border: {
+ radius: '0px',
+ },
+ color: {
+ duotone: style?.color?.duotone,
+ },
+ } ),
+ } ),
+ createBlock(
+ 'core/group',
+ {
+ style: {
+ layout: {
+ selfStretch: 'fill',
+ flexSize: null,
+ },
+ },
+ layout: {
+ type: 'flex',
+ orientation: 'vertical',
+ justifyContent: textAlign,
+ },
+ },
+ [
+ createBlock( 'core/paragraph', {
+ content: byline,
+ placeholder: __( 'Write byline…' ),
+ style: {
+ typography: {
+ fontSize: '0.5em',
+ },
+ },
+ } ),
+ createBlock( 'core/post-author-name', {
+ isLink,
+ linkTarget,
+ style: {
+ typography: {
+ fontSize: '1em',
+ },
+ },
+ } ),
+ showBio &&
+ createBlock( 'core/post-author-biography', {
+ style: {
+ typography: {
+ fontSize: '0.7em',
+ },
+ },
+ } ),
+ ].filter( Boolean )
+ ),
+ ].filter( Boolean )
+ );
+}