diff --git a/assets/README.md b/assets/README.md
new file mode 100644
index 00000000000000..e437ec744d3807
--- /dev/null
+++ b/assets/README.md
@@ -0,0 +1,7 @@
+## Gutenberg Plugin Assets
+
+The contents of this directory are synced from the [`assets/` directory in the Gutenberg repository on GitHub](https://github.com/WordPress/gutenberg/tree/trunk/assets) to the [`assets/` directory of the Gutenberg WordPress.org plugin repository](https://plugins.trac.wordpress.org/browser/gutenberg/assets). **Any changes committed directly to the plugin repository on WordPress.org will be overwritten.**
+
+The sync is performed by a [GitHub Actions workflow](https://github.com/WordPress/gutenberg/actions/workflows/sync-assets-to-plugin-repo.yml) that is triggered whenever a file in this directory is changed.
+
+Since that workflow requires access to WP.org plugin repository credentials, it needs to be approved manually by a member of the Gutenberg Core team. If you don't have the necessary permissions, please ask someone in [#core-editor](https://wordpress.slack.com/archives/C02QB2JS7).
diff --git a/backport-changelog/6.8/8015.md b/backport-changelog/6.8/8015.md
new file mode 100644
index 00000000000000..214705518a0e72
--- /dev/null
+++ b/backport-changelog/6.8/8015.md
@@ -0,0 +1,3 @@
+https://github.com/WordPress/wordpress-develop/pull/8015
+
+* https://github.com/WordPress/gutenberg/pull/68058
diff --git a/lib/compat/wordpress-6.8/blocks.php b/lib/compat/wordpress-6.8/blocks.php
index 8e176e58c8d7f5..dc8747c04aec2f 100644
--- a/lib/compat/wordpress-6.8/blocks.php
+++ b/lib/compat/wordpress-6.8/blocks.php
@@ -170,7 +170,7 @@ function gutenberg_apply_block_hooks_to_post_content( $content ) {
* @return WP_REST_Response The response object.
*/
function gutenberg_insert_hooked_blocks_into_rest_response( $response, $post ) {
- if ( empty( $response->data['content']['raw'] ) || empty( $response->data['content']['rendered'] ) ) {
+ if ( empty( $response->data['content']['raw'] ) ) {
return $response;
}
@@ -185,6 +185,8 @@ function gutenberg_insert_hooked_blocks_into_rest_response( $response, $post ) {
if ( 'wp_navigation' === $post->post_type ) {
$wrapper_block_type = 'core/navigation';
+ } elseif ( 'wp_block' === $post->post_type ) {
+ $wrapper_block_type = 'core/block';
} else {
$wrapper_block_type = 'core/post-content';
}
@@ -206,6 +208,11 @@ function gutenberg_insert_hooked_blocks_into_rest_response( $response, $post ) {
$response->data['content']['raw'] = $content;
+ // If the rendered content was previously empty, we leave it like that.
+ if ( empty( $response->data['content']['rendered'] ) ) {
+ return $response;
+ }
+
// No need to inject hooked blocks twice.
$priority = has_filter( 'the_content', 'apply_block_hooks_to_content' );
if ( false !== $priority ) {
@@ -224,6 +231,7 @@ function gutenberg_insert_hooked_blocks_into_rest_response( $response, $post ) {
}
add_filter( 'rest_prepare_page', 'gutenberg_insert_hooked_blocks_into_rest_response', 10, 2 );
add_filter( 'rest_prepare_post', 'gutenberg_insert_hooked_blocks_into_rest_response', 10, 2 );
+add_filter( 'rest_prepare_wp_block', 'gutenberg_insert_hooked_blocks_into_rest_response', 10, 2 );
/**
* Updates the wp_postmeta with the list of ignored hooked blocks
@@ -272,6 +280,8 @@ function gutenberg_update_ignored_hooked_blocks_postmeta( $post ) {
if ( 'wp_navigation' === $post->post_type ) {
$wrapper_block_type = 'core/navigation';
+ } elseif ( 'wp_block' === $post->post_type ) {
+ $wrapper_block_type = 'core/block';
} else {
$wrapper_block_type = 'core/post-content';
}
@@ -311,3 +321,4 @@ function gutenberg_update_ignored_hooked_blocks_postmeta( $post ) {
}
add_filter( 'rest_pre_insert_page', 'gutenberg_update_ignored_hooked_blocks_postmeta' );
add_filter( 'rest_pre_insert_post', 'gutenberg_update_ignored_hooked_blocks_postmeta' );
+add_filter( 'rest_pre_insert_wp_block', 'gutenberg_update_ignored_hooked_blocks_postmeta' );
diff --git a/packages/block-library/src/block/index.php b/packages/block-library/src/block/index.php
index 8beef975fad6f3..e8075115cabda4 100644
--- a/packages/block-library/src/block/index.php
+++ b/packages/block-library/src/block/index.php
@@ -87,6 +87,26 @@ function render_block_core_block( $attributes ) {
add_filter( 'render_block_context', $filter_block_context, 1 );
}
+ $ignored_hooked_blocks = get_post_meta( $attributes['ref'], '_wp_ignored_hooked_blocks', true );
+ if ( ! empty( $ignored_hooked_blocks ) ) {
+ $ignored_hooked_blocks = json_decode( $ignored_hooked_blocks, true );
+ $attributes['metadata'] = array(
+ 'ignoredHookedBlocks' => $ignored_hooked_blocks,
+ );
+ }
+
+ // Wrap in "Block" block so the Block Hooks algorithm can insert blocks
+ // that are hooked as first or last child of `core/block`.
+ $content = get_comment_delimited_block_content(
+ 'core/block',
+ $attributes,
+ $content
+ );
+ // Apply Block Hooks.
+ $content = apply_block_hooks_to_content( $content, $reusable_block );
+ // Remove block wrapper.
+ $content = remove_serialized_parent_block( $content );
+
$content = do_blocks( $content );
unset( $seen_refs[ $attributes['ref'] ] );
diff --git a/packages/block-library/src/navigation-link/edit.js b/packages/block-library/src/navigation-link/edit.js
index 39073b848d3ca8..5966739aa61a61 100644
--- a/packages/block-library/src/navigation-link/edit.js
+++ b/packages/block-library/src/navigation-link/edit.js
@@ -9,7 +9,8 @@ import clsx from 'clsx';
import { createBlock } from '@wordpress/blocks';
import { useSelect, useDispatch } from '@wordpress/data';
import {
- PanelBody,
+ __experimentalToolsPanel as ToolsPanel,
+ __experimentalToolsPanelItem as ToolsPanelItem,
TextControl,
TextareaControl,
ToolbarButton,
@@ -161,71 +162,110 @@ function getMissingText( type ) {
function Controls( { attributes, setAttributes, setIsLabelFieldFocused } ) {
const { label, url, description, title, rel } = attributes;
return (
-
- {
- setAttributes( { label: labelValue } );
- } }
+
+ !! label }
label={ __( 'Text' ) }
- autoComplete="off"
- onFocus={ () => setIsLabelFieldFocused( true ) }
- onBlur={ () => setIsLabelFieldFocused( false ) }
- />
- {
- updateAttributes(
- { url: urlValue },
- setAttributes,
- attributes
- );
- } }
+ onDeselect={ () => setAttributes( { label: '' } ) }
+ isShownByDefault
+ >
+ {
+ setAttributes( { label: labelValue } );
+ } }
+ autoComplete="off"
+ onFocus={ () => setIsLabelFieldFocused( true ) }
+ onBlur={ () => setIsLabelFieldFocused( false ) }
+ />
+
+
+ !! url }
label={ __( 'Link' ) }
- autoComplete="off"
- />
- {
- setAttributes( { description: descriptionValue } );
- } }
+ onDeselect={ () => setAttributes( { url: '' } ) }
+ isShownByDefault
+ >
+ {
+ updateAttributes(
+ { url: urlValue },
+ setAttributes,
+ attributes
+ );
+ } }
+ autoComplete="off"
+ />
+
+
+ !! description }
label={ __( 'Description' ) }
- help={ __(
- 'The description will be displayed in the menu if the current theme supports it.'
- ) }
- />
- {
- setAttributes( { title: titleValue } );
- } }
+ onDeselect={ () => setAttributes( { description: '' } ) }
+ isShownByDefault
+ >
+ {
+ setAttributes( { description: descriptionValue } );
+ } }
+ help={ __(
+ 'The description will be displayed in the menu if the current theme supports it.'
+ ) }
+ />
+
+
+ !! title }
label={ __( 'Title attribute' ) }
- autoComplete="off"
- help={ __(
- 'Additional information to help clarify the purpose of the link.'
- ) }
- />
- {
- setAttributes( { rel: relValue } );
- } }
+ onDeselect={ () => setAttributes( { title: '' } ) }
+ isShownByDefault
+ >
+ {
+ setAttributes( { title: titleValue } );
+ } }
+ autoComplete="off"
+ help={ __(
+ 'Additional information to help clarify the purpose of the link.'
+ ) }
+ />
+
+
+ !! rel }
label={ __( 'Rel attribute' ) }
- autoComplete="off"
- help={ __(
- 'The relationship of the linked URL as space-separated link types.'
- ) }
- />
-
+ onDeselect={ () => setAttributes( { rel: '' } ) }
+ isShownByDefault
+ >
+ {
+ setAttributes( { rel: relValue } );
+ } }
+ autoComplete="off"
+ help={ __(
+ 'The relationship of the linked URL as space-separated link types.'
+ ) }
+ />
+
+
);
}
diff --git a/packages/block-library/src/spacer/controls.js b/packages/block-library/src/spacer/controls.js
index 1e899e15aff0de..fde06d3ee8c339 100644
--- a/packages/block-library/src/spacer/controls.js
+++ b/packages/block-library/src/spacer/controls.js
@@ -10,10 +10,11 @@ import {
privateApis as blockEditorPrivateApis,
} from '@wordpress/block-editor';
import {
- PanelBody,
__experimentalUseCustomUnits as useCustomUnits,
__experimentalUnitControl as UnitControl,
__experimentalParseQuantityAndUnitFromRawValue as parseQuantityAndUnitFromRawValue,
+ __experimentalToolsPanel as ToolsPanel,
+ __experimentalToolsPanelItem as ToolsPanelItem,
} from '@wordpress/components';
import { useInstanceId } from '@wordpress/compose';
import { View } from '@wordpress/primitives';
@@ -94,28 +95,54 @@ export default function SpacerControls( {
} ) {
return (
-
+ {
+ setAttributes( {
+ width: undefined,
+ height: '100px',
+ } );
+ } }
+ >
{ orientation === 'horizontal' && (
-
- setAttributes( { width: nextWidth } )
+ isShownByDefault
+ hasValue={ () => width !== undefined }
+ onDeselect={ () =>
+ setAttributes( { width: undefined } )
}
- isResizing={ isResizing }
- />
+ >
+
+ setAttributes( { width: nextWidth } )
+ }
+ isResizing={ isResizing }
+ />
+
) }
{ orientation !== 'horizontal' && (
-
- setAttributes( { height: nextHeight } )
+ isShownByDefault
+ hasValue={ () => height !== '100px' }
+ onDeselect={ () =>
+ setAttributes( { height: '100px' } )
}
- isResizing={ isResizing }
- />
+ >
+
+ setAttributes( { height: nextHeight } )
+ }
+ isResizing={ isResizing }
+ />
+
) }
-
+
);
}
diff --git a/packages/edit-site/src/components/sidebar-navigation-item/style.scss b/packages/edit-site/src/components/sidebar-navigation-item/style.scss
index 230967c4c7e0ed..57b7e84bd57a8b 100644
--- a/packages/edit-site/src/components/sidebar-navigation-item/style.scss
+++ b/packages/edit-site/src/components/sidebar-navigation-item/style.scss
@@ -18,6 +18,7 @@
&[aria-current="true"] {
background: $gray-800;
color: $white;
+ font-weight: $font-weight-medium;
}
// Make sure the focus style is drawn on top of the current item background.
diff --git a/packages/editor/src/components/post-card-panel/index.js b/packages/editor/src/components/post-card-panel/index.js
index 7849f014ab49c8..78f9522ba5f444 100644
--- a/packages/editor/src/components/post-card-panel/index.js
+++ b/packages/editor/src/components/post-card-panel/index.js
@@ -6,6 +6,7 @@ import {
__experimentalHStack as HStack,
__experimentalVStack as VStack,
__experimentalText as Text,
+ privateApis as componentsPrivateApis,
} from '@wordpress/components';
import { store as coreStore } from '@wordpress/core-data';
import { useSelect } from '@wordpress/data';
@@ -25,6 +26,7 @@ import { unlock } from '../../lock-unlock';
import PostActions from '../post-actions';
import usePageTypeBadge from '../../utils/pageTypeBadge';
import { getTemplateInfo } from '../../utils/get-template-info';
+const { Badge } = unlock( componentsPrivateApis );
/**
* Renders a title of the post type and the available quick actions available within a 3-dot dropdown.
@@ -109,11 +111,11 @@ export default function PostCardPanel( {
className="editor-post-card-panel__title"
as="h2"
>
- { title }
+
+ { title }
+
{ pageTypeBadge && postIds.length === 1 && (
-
- { pageTypeBadge }
-
+ { pageTypeBadge }
) }
{
@@ -27,11 +30,11 @@ export default function PageTitleView( { item }: { item: CommonPost } ) {
return (
{ [ frontPageId, postsPageId ].includes( item.id as number ) && (
-
+
{ item.id === frontPageId
? __( 'Homepage' )
: __( 'Posts Page' ) }
-
+
) }
);
diff --git a/packages/fields/src/style.scss b/packages/fields/src/style.scss
index d9a571270fbb68..96b1f816de5b61 100644
--- a/packages/fields/src/style.scss
+++ b/packages/fields/src/style.scss
@@ -3,5 +3,4 @@
@import "./fields/featured-image/style.scss";
@import "./fields/template/style.scss";
@import "./fields/title/style.scss";
-@import "./fields/page-title/style.scss";
@import "./fields/pattern-title/style.scss";