From f8a1cfb06b5163e8fc4a7ed97961010fdf06c916 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 25 Aug 2023 15:14:21 +0100 Subject: [PATCH] Dynamic links --- .../block-library/src/navigation-link/edit.js | 22 ++++++++++++++++++- .../src/navigation-link/index.php | 22 ++++++++++--------- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/packages/block-library/src/navigation-link/edit.js b/packages/block-library/src/navigation-link/edit.js index df7ca36d7272a..919c19e587e85 100644 --- a/packages/block-library/src/navigation-link/edit.js +++ b/packages/block-library/src/navigation-link/edit.js @@ -35,7 +35,7 @@ import { } from '@wordpress/dom'; import { decodeEntities } from '@wordpress/html-entities'; import { link as linkIcon, addSubmenu } from '@wordpress/icons'; -import { store as coreStore } from '@wordpress/core-data'; +import { store as coreStore, useEntityRecord } from '@wordpress/core-data'; import { useMergeRefs } from '@wordpress/compose'; /** @@ -180,6 +180,8 @@ export default function NavigationLinkEdit( { const itemLabelPlaceholder = __( 'Add label…' ); const ref = useRef(); + const { record: navPostRecord } = useEntityRecord( 'postType', type, id ); + // Change the label using inspector causes rich text to change focus on firefox. // This is a workaround to keep the focus on the label field when label filed is focused we don't render the rich text. const [ isLabelFieldFocused, setIsLabelFieldFocused ] = useState( false ); @@ -282,6 +284,24 @@ export default function NavigationLinkEdit( { } }, [ url ] ); + useEffect( () => { + // Only updates attributes if: + // - there is an ID (and it has changed). + // - there is a navPostRecord. + if ( id && navPostRecord ) { + // Conditionall update attributes to avoid + // unnecessary re-renders. + setAttributes( { + ...( label !== navPostRecord?.title.rendered && { + label: navPostRecord?.title.rendered, + } ), + ...( url !== navPostRecord?.link && { + url: navPostRecord?.link, + } ), + } ); + } + }, [ id, navPostRecord ] ); + /** * Focus the Link label text and select it. */ diff --git a/packages/block-library/src/navigation-link/index.php b/packages/block-library/src/navigation-link/index.php index 5333ab6ea3dc9..8c53f9086089e 100644 --- a/packages/block-library/src/navigation-link/index.php +++ b/packages/block-library/src/navigation-link/index.php @@ -160,16 +160,18 @@ function render_block_core_navigation_link( $attributes, $content, $block ) { $is_post_type = isset( $attributes['kind'] ) && 'post-type' === $attributes['kind']; $is_post_type = $is_post_type || isset( $attributes['type'] ) && ( 'post' === $attributes['type'] || 'page' === $attributes['type'] ); + $post = $is_post_type && $navigation_link_has_id ? get_post( $attributes['id'] ) : null; + // Don't render the block's subtree if it is a draft or if the ID does not exist. - if ( $is_post_type && $navigation_link_has_id ) { - $post = get_post( $attributes['id'] ); - if ( ! $post || 'publish' !== $post->post_status ) { - return ''; - } + if ( ! $post || 'publish' !== $post->post_status ) { + return ''; } + $dynamic_url = $post ? get_permalink( $post ) : $attributes['url']; + $dynamic_label = $post ? $post->post_title : $attributes['label']; + // Don't render the block's subtree if it has no label. - if ( empty( $attributes['label'] ) ) { + if ( empty( $dynamic_label ) ) { return ''; } @@ -195,8 +197,8 @@ function render_block_core_navigation_link( $attributes, $content, $block ) { ''; - if ( isset( $attributes['label'] ) ) { - $html .= wp_kses_post( $attributes['label'] ); + if ( isset( $dynamic_label ) ) { + $html .= wp_kses_post( $dynamic_label ); } $html .= '';