diff --git a/lib/experimental/editor-settings.php b/lib/experimental/editor-settings.php index 126382f85a513e..88611e77544bec 100644 --- a/lib/experimental/editor-settings.php +++ b/lib/experimental/editor-settings.php @@ -34,6 +34,9 @@ function gutenberg_enable_experiments() { if ( $gutenberg_experiments && array_key_exists( 'gutenberg-media-processing', $gutenberg_experiments ) ) { wp_add_inline_script( 'wp-block-editor', 'window.__experimentalMediaProcessing = true', 'before' ); } + if ( $gutenberg_experiments && array_key_exists( 'gutenberg-search-query-block', $gutenberg_experiments ) ) { + wp_add_inline_script( 'wp-block-editor', 'window.__experimentalSearchQueryBlock = true', 'before' ); + } } add_action( 'admin_init', 'gutenberg_enable_experiments' ); diff --git a/lib/experiments-page.php b/lib/experiments-page.php index 27a54b920f4d52..9de707fb0d2db0 100644 --- a/lib/experiments-page.php +++ b/lib/experiments-page.php @@ -175,6 +175,18 @@ function gutenberg_initialize_experiments_settings() { ) ); + add_settings_field( + 'gutenberg-search-query-block', + __( 'Instant Search and Query Block', 'gutenberg' ), + 'gutenberg_display_experiment_field', + 'gutenberg-experiments', + 'gutenberg_experiments_section', + array( + 'label' => __( 'Enable instant search functionality of the Search + Query blocks.', 'gutenberg' ), + 'id' => 'gutenberg-search-query-block', + ) + ); + register_setting( 'gutenberg-experiments', 'gutenberg-experiments' diff --git a/packages/block-library/src/post-template/index.php b/packages/block-library/src/post-template/index.php index 9126355c096a57..691fa0ec90f1b1 100644 --- a/packages/block-library/src/post-template/index.php +++ b/packages/block-library/src/post-template/index.php @@ -50,6 +50,11 @@ function render_block_core_post_template( $attributes, $content, $block ) { $page_key = isset( $block->context['queryId'] ) ? 'query-' . $block->context['queryId'] . '-page' : 'query-page'; $enhanced_pagination = isset( $block->context['enhancedPagination'] ) && $block->context['enhancedPagination']; $page = empty( $_GET[ $page_key ] ) ? 1 : (int) $_GET[ $page_key ]; + $search_query = empty( $_GET['search'] ) ? '' : sanitize_text_field( $_GET['search'] ); + + // Check if the Instant Search experiment is enabled. + $gutenberg_experiments = get_option( 'gutenberg-experiments' ); + $instant_search_enabled = isset( $gutenberg_experiments['gutenberg-search-query-block'] ) && $gutenberg_experiments['gutenberg-search-query-block']; // Use global query if needed. $use_global_query = ( isset( $block->context['query']['inherit'] ) && $block->context['query']['inherit'] ); @@ -64,12 +69,29 @@ function render_block_core_post_template( $attributes, $content, $block ) { if ( in_the_loop() ) { $query = clone $wp_query; $query->rewind_posts(); + $query_args = $wp_query->query_vars; + + // Add search parameter if it exists. + if ( $enhanced_pagination && $instant_search_enabled && ! empty( $search_query ) ) { + $query_args['s'] = $search_query; + } + $query->query( $query_args ); } else { + // The query has not been run yet, modify the global query. + if ( $enhanced_pagination && $instant_search_enabled && ! empty( $search_query ) ) { + $wp_query->set( 's', $search_query ); + } $query = $wp_query; } } else { $query_args = build_query_vars_from_query_block( $block, $page ); - $query = new WP_Query( $query_args ); + + // Add search parameter if enhanced pagination is on and search query exists + if ( $enhanced_pagination && $instant_search_enabled && ! empty( $search_query ) ) { + $query_args['s'] = $search_query; + } + + $query = new WP_Query( $query_args ); } if ( ! $query->have_posts() ) { diff --git a/packages/block-library/src/search/view.js b/packages/block-library/src/search/view.js index c13f66cb99043b..dff0c5608a09fb 100644 --- a/packages/block-library/src/search/view.js +++ b/packages/block-library/src/search/view.js @@ -7,21 +7,6 @@ const isEmpty = ( obj ) => [ Object, Array ].includes( ( obj || {} ).constructor ) && ! Object.entries( obj || {} ).length; -const updateURL = async ( value, name ) => { - const url = new URL( window.location ); - const { actions } = await import( '@wordpress/interactivity-router' ); - - if ( 's' === name ) { - if ( ! isEmpty( value ) ) { - url.searchParams.set( 'search', value ); - } else { - url.searchParams.delete( 'search' ); - } - } - - await actions.navigate( `${ window.location.pathname }${ url.search }` ); -}; - const { state, actions } = store( 'core/search', { @@ -50,6 +35,10 @@ const { state, actions } = store( }, get isSearchInputVisible() { const ctx = getContext(); + + // `ctx.isSearchInputVisible` is a client-side-only context value, so + // if it's not set, it means that it's an initial page load, so we need + // to return the value of `ctx.isSearchInputInitiallyVisible`. if ( typeof ctx.isSearchInputVisible === 'undefined' ) { return ctx.isSearchInputInitiallyVisible; } @@ -101,12 +90,24 @@ const { state, actions } = store( return; } + const url = new URL( window.location ); + if ( 's' === name ) { state.search = value; + if ( ! isEmpty( value ) ) { + url.searchParams.set( 'search', value ); + } else { + url.searchParams.delete( 'search' ); + } } - // If not, navigate to the new URL. - yield updateURL( value, name ); + const { actions: routerActions } = yield import( + '@wordpress/interactivity-router' + ); + + routerActions.navigate( + `${ window.location.pathname }${ url.search }` + ); }, }, },