Skip to content

Inline Search: add Jetpack branding + Class Refactor #43330

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 53 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
93d363b
Initial search correction commit
anaemnesis Mar 14, 2025
c78183a
changelog
anaemnesis Mar 14, 2025
dd3585b
Update wording/order
anaemnesis Mar 17, 2025
ade1bfe
Initial linking of corrected search result
anaemnesis Mar 18, 2025
accc0d6
- Change order of "No results" and "Did you mean" text
anaemnesis Mar 18, 2025
25d10eb
Merge remote-tracking branch 'origin/trunk' into enhance/surface-sear…
anaemnesis Mar 25, 2025
e934b61
Restore Instant Search Changes
anaemnesis Mar 26, 2025
ffe3308
Initial Inline Search changes
anaemnesis Mar 27, 2025
ce345c3
Cleanup
anaemnesis Mar 28, 2025
738a11c
Cleanup and Refactor
anaemnesis Mar 31, 2025
6005d0e
Let us try adding some tests
anaemnesis Apr 1, 2025
c913e78
Test JS
anaemnesis Apr 1, 2025
0bd7df3
Revise and update our tests
anaemnesis Apr 1, 2025
102d5fe
Revert tests for inclusion in a latter PR
anaemnesis Apr 1, 2025
a492ba0
Revise methods further and make proper use of Assets::class
anaemnesis Apr 1, 2025
c0b4809
Modernise our JS
anaemnesis Apr 1, 2025
3f2d9a8
Simply corrected query html
anaemnesis Apr 1, 2025
bde3ebb
Refactor get_corrected_query_html()
anaemnesis Apr 2, 2025
ae66bbb
Merge remote-tracking branch 'origin/trunk' into enhance/surface-sear…
anaemnesis Apr 2, 2025
de4941a
Merge remote-tracking branch 'origin/trunk' into enhance/surface-sear…
anaemnesis Apr 15, 2025
2e3052d
Add Search Result Highlighting
anaemnesis Apr 16, 2025
ab9ec4c
changelog
anaemnesis Apr 16, 2025
fc6e502
Reorganise class to better group methods
anaemnesis Apr 17, 2025
6e37b09
First pass at highlighting search corrections
anaemnesis Apr 17, 2025
36bf325
Move to a simpler highlighting solution as the previous was overengin…
anaemnesis Apr 17, 2025
ef34d72
Refactor highlighting handling to better leverage the 1.3api
anaemnesis Apr 17, 2025
7f45b38
Remove excerpt highlighting as unnecessary at this time
anaemnesis Apr 21, 2025
a38a9f8
Let us move highlighting to a class of its own
anaemnesis Apr 21, 2025
e6e7ae1
Merge remote-tracking branch 'origin/trunk' into add/inline-search-te…
anaemnesis Apr 21, 2025
588f855
New class for search correction surfacing
anaemnesis Apr 24, 2025
6b6c299
Create Inline Search Webpack config
anaemnesis Apr 28, 2025
f6695f6
Add styling for default themes where necesssary:
anaemnesis Apr 28, 2025
15a00b5
More theme styling
anaemnesis Apr 29, 2025
916f4df
Premium theme styling
anaemnesis Apr 29, 2025
41991cf
Merge remote-tracking branch 'origin/trunk' into enhance/surface-sear…
anaemnesis Apr 29, 2025
0bae6e9
Add query string to activate
anaemnesis Apr 29, 2025
73f3faf
Refactored implementation of search branding
anaemnesis May 1, 2025
3915560
Merge remote-tracking branch 'origin/trunk' into add/inline-search-te…
anaemnesis May 6, 2025
5e51485
We don't need this require
anaemnesis May 6, 2025
4b88094
Use highlight data returned from the API instead of building our own
anaemnesis May 6, 2025
f6c2605
Address PHPStan
anaemnesis May 6, 2025
f5329f3
Highlight content returned without p tags
anaemnesis May 6, 2025
76a6cb0
Merge remote-tracking branch 'origin/trunk' into add/inline-search-te…
anaemnesis May 7, 2025
5f74b79
Cleanup related refactor
anaemnesis May 8, 2025
05b1d47
Merge remote-tracking branch 'origin/trunk' into add/inline-search-te…
anaemnesis May 8, 2025
51ddf6e
Merge remote-tracking branch 'origin/trunk' into add/inline-search-br…
anaemnesis May 8, 2025
619c72a
changelog
anaemnesis May 8, 2025
09f59ea
Merge remote-tracking branch 'origin/add/inline-search-term-highlight…
anaemnesis May 8, 2025
b624e6e
Have the Search Correction class use our abstracted class methods
anaemnesis May 8, 2025
595b5c3
Fix linter notices
anaemnesis May 8, 2025
bff3d46
Merge remote-tracking branch 'origin/trunk' into add/inline-search-br…
anaemnesis May 9, 2025
0da3a87
Rename highlighter class to reflect Inline Search
anaemnesis May 9, 2025
f49a2e6
Fix tests
anaemnesis May 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions projects/packages/search/changelog/add-inline-search-branding
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Inline Search: add Jetpack Branding to search results.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Add highlighting of search term in returned search results.
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<?php
/**
* Inline Search Colophon: Handles Jetpack colophon display
*
* @package automattic/jetpack-search
*/

namespace Automattic\Jetpack\Search;

/**
* Class for handling Jetpack colophon display
*
* @since $$next-version$$
*/
class Inline_Search_Colophon extends Inline_Search_Component {
/**
* Setup hooks for displaying the Jetpack colophon.
*
* @param \WP_Query $query The current query.
*/
public function setup_colophon_hooks( $query ) {
if ( ! $this->is_valid_search_query( $query ) ) {
return;
}

add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_styles' ) );
add_action( 'wp_footer', array( $this, 'register_colophon_script' ) );
}

/**
* Enqueue theme-specific styles for the search colophon.
* This is hooked to wp_enqueue_scripts to ensure styles load properly in the head.
*
* @since $$next-version$$
*/
public function enqueue_styles() {
$handle = 'jetpack-search-inline-colophon';
$this->register_component_style( $handle, 'colophon.css' );
}

/**
* Register and configure the JavaScript for displaying the colophon.
*
* @since $$next-version$$
*/
public function register_colophon_script() {
$this->register_inline_search_script();

// Don't localize if already localized to prevent duplication
if ( wp_script_is( self::SCRIPT_HANDLE, 'data' ) ) {
$localized_data = wp_scripts()->get_data( self::SCRIPT_HANDLE, 'data' );
if ( $localized_data && strpos( $localized_data, 'JetpackSearchColophon' ) !== false ) {
return;
}
}

// Only localize the script, don't register it again as it's handled by the base class
wp_localize_script(
self::SCRIPT_HANDLE,
'JetpackSearchColophon',
array(
'html' => $this->get_colophon_html(),
'selector' => $this->format_selectors_for_query( $this->get_content_selectors() ),
)
);
}

/**
* Get selectors where colophon will be displayed.
*
* @since $$next-version$$
* @return array CSS selectors for content container elements.
*/
private function get_content_selectors() {
$default_selectors = array(
'.wp-block-query',
'.content',
'#content',
'#site-content',
'.site-main',
'.content-area',
);

/**
* Filter the selectors where colophon appears.
*
* @since $$next-version$$
* @param array $default_selectors CSS selectors for content container elements.
*/
return apply_filters( 'jetpack_search_colophon_selectors', $default_selectors );
}

/**
* Get the locale for the Jetpack URL.
*
* @return string|null The locale prefix or null.
*/
private function get_locale_prefix() {
$locale = get_locale();
if ( empty( $locale ) ) {
return null;
}

$locale_prefix = explode( '-', $locale )[0];
return $locale_prefix !== 'en' ? $locale_prefix : null;
}

/**
* Generate the HTML for the colophon.
*
* @return string The HTML for the colophon.
*/
private function get_colophon_html() {
$locale_prefix = $this->get_locale_prefix();
$url = $locale_prefix
? 'https://' . $locale_prefix . '.jetpack.com/upgrade/search?utm_source=poweredby'
: 'https://jetpack.com/upgrade/search/?utm_source=poweredby';

$logo_svg = $this->get_logo_svg();

return sprintf(
'<div class="jetpack-search-inline-colophon">
<a href="%s" rel="external noopener noreferrer nofollow" target="_blank" class="jetpack-search-inline-colophon-link">
%s
<span>%s</span>
</a>
</div>',
esc_url( $url ),
$logo_svg,
esc_html__( 'Search powered by Jetpack', 'jetpack-search-pkg' )
);
}

/**
* Get the SVG markup for the Jetpack logo.
*
* @return string The SVG markup.
*/
private function get_logo_svg() {
$color_jetpack = '#069E08';
$color_white = '#ffffff';
$logo_size = 12;

return sprintf(
'<svg class="jetpack-search-inline-colophon-logo" height="%1$d" width="%1$d" viewBox="0 0 32 32">
<path class="jetpack-logo__icon-circle" fill="%2$s" d="M16,0C7.2,0,0,7.2,0,16s7.2,16,16,16s16-7.2,16-16S24.8,0,16,0z" />
<polygon class="jetpack-logo__icon-triangle" fill="%3$s" points="15,19 7,19 15,3 " />
<polygon class="jetpack-logo__icon-triangle" fill="%3$s" points="17,29 17,13 25,13 " />
</svg>',
$logo_size,
$color_jetpack,
$color_white
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?php
/**
* Inline Search Component: Base abstract class for inline search components
*
* @package automattic/jetpack-search
*/

namespace Automattic\Jetpack\Search;

use Automattic\Jetpack\Assets;

/**
* Base abstract class for inline search components
*
* @since $$next-version$$
*/
abstract class Inline_Search_Component {
/**
* Common script handle used by all inline search components
*/
protected const SCRIPT_HANDLE = 'jetpack-search-inline';

/**
* Verify query is a valid search query.
*
* @param \WP_Query $query The current query.
* @return bool Whether this is a valid search query.
*/
protected function is_valid_search_query( $query ) {
return $query->is_search() && $query->is_main_query();
}

/**
* Register and enqueue a component stylesheet.
*
* @since $$next-version$$
* @param string $handle The script handle to use for the stylesheet.
* @param string $css_file The CSS filename (without the path).
* @return bool Whether the style was successfully registered and enqueued.
*/
protected function register_component_style( $handle, $css_file ) {
$css_path = 'build/inline-search/';
$full_css_path = $css_path . $css_file;
$package_path = Package::get_installed_path();
$css_full_path = $package_path . '/' . $full_css_path;

// Verify the CSS file exists before trying to enqueue it
if ( ! file_exists( $css_full_path ) ) {
return false;
}

// We need to use plugins_url for reliable URL generation
$file_url = plugins_url(
$full_css_path,
$package_path . '/package.json'
);

// Use the file's modification time for more precise cache busting
$file_version = file_exists( $css_full_path ) ? filemtime( $css_full_path ) : Package::VERSION;

wp_enqueue_style(
$handle,
$file_url,
array(),
$file_version // Use file modification time for cache busting
);

return true;
}

/**
* Register the common inline search script if not already registered.
*
* @since $$next-version$$
* @return bool Whether the script was registered.
*/
protected function register_inline_search_script() {
if ( wp_script_is( self::SCRIPT_HANDLE, 'registered' ) ) {
return true;
}

return Assets::register_script(
self::SCRIPT_HANDLE,
'build/inline-search/jp-search-inline.js',
Package::get_installed_path() . '/src',
array(
'in_footer' => true,
'textdomain' => 'jetpack-search-pkg',
'enqueue' => true,
)
);
}

/**
* Get the search result from the Inline_Search instance.
*
* @return array|null The search result or null if not available.
*/
protected function get_search_result() {
$inline_search = Inline_Search::instance();
return $inline_search->get_search_result();
}

/**
* Convert an array of selectors to a comma-separated string for querySelector.
*
* @param array $selectors Array of CSS selectors.
* @return string Comma-separated string of selectors.
*/
protected function format_selectors_for_query( $selectors ) {
return implode( ', ', $selectors );
}
}
Loading
Loading