Skip to content

Commit

Permalink
Merge pull request #31 from philipnewcomer/feature/search-result-high…
Browse files Browse the repository at this point in the history
…lighting

Add highlighting to search results
  • Loading branch information
richaber authored Dec 6, 2019
2 parents a364ac4 + 95c25fe commit 312c8a2
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 4 deletions.
124 changes: 121 additions & 3 deletions includes/class-algolia-search.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

class Algolia_Search {

/**
* @var array
*/
private $current_page_hits = [];

/**
* @var int
*/
private $nb_hits;
private $total_hits;

/**
* @var Algolia_Index
Expand All @@ -18,7 +23,9 @@ class Algolia_Search {
public function __construct( Algolia_Index $index ) {
$this->index = $index;

add_action( 'loop_start', [ $this, 'begin_highlighting' ] );
add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
add_action( 'wp_head', [ $this, 'output_highlighting_bundled_styles' ] );
}

/**
Expand Down Expand Up @@ -56,6 +63,8 @@ public function pre_get_posts( WP_Query $query ) {
'attributesToRetrieve' => 'post_id',
'hitsPerPage' => $posts_per_page,
'page' => $current_page - 1, // Algolia pages are zero indexed.
'highlightPreTag' => '<em class="algolia-search-highlight">',
'highlightPostTag' => '</em>',
)
);

Expand All @@ -73,9 +82,14 @@ public function pre_get_posts( WP_Query $query ) {
add_filter( 'found_posts', array( $this, 'found_posts' ), 10, 2 );
add_filter( 'posts_search', array( $this, 'posts_search' ), 10, 2 );

// Store the current page hits, so that we can use them for highlighting later on.
foreach ( $results['hits'] as $hit ) {
$this->current_page_hits[ $hit['post_id'] ] = $hit;
}

// Store the total number of its, so that we can hook into the `found_posts`.
// This is useful for pagination.
$this->nb_hits = $results['nbHits'];
$this->total_hits = $results['nbHits'];

$post_ids = array();
foreach ( $results['hits'] as $result ) {
Expand Down Expand Up @@ -117,7 +131,7 @@ public function pre_get_posts( WP_Query $query ) {
* @return int
*/
public function found_posts( $found_posts, WP_Query $query ) {
return $this->should_filter_query( $query ) ? $this->nb_hits : $found_posts;
return $this->should_filter_query( $query ) ? $this->total_hits : $found_posts;
}

/**
Expand All @@ -134,4 +148,108 @@ public function found_posts( $found_posts, WP_Query $query ) {
public function posts_search( $search, WP_Query $query ) {
return $this->should_filter_query( $query ) ? '' : $search;
}

/**
* Output the bundled styles for highlighting search result matches, if enabled.
*/
public function output_highlighting_bundled_styles() {
if ( ! $this->highlighting_enabled() ) {
return;
}

if ( ! apply_filters( 'algolia_search_highlighting_enable_bundled_styles', true ) ) {
return;
}

?>
<style>
.algolia-search-highlight {
background-color: #fffbcc;
border-radius: 2px;
font-style: normal;
}
</style>
<?php
}

/**
* Begin highlighting search result matches, if enabled.
*
* This method is called on the loop_start action, where we want to begin highlighting search result matches.
*
* @param WP_Query $query
*/
public function begin_highlighting( $query ) {
if ( ! $this->should_filter_query( $query ) ) {
return;
}

if ( ! $this->highlighting_enabled() ) {
return;
}

add_filter( 'the_title', [ $this, 'highlight_the_title' ], 10, 2 );
add_filter( 'get_the_excerpt', [ $this, 'highlight_get_the_excerpt' ], 10, 2 );

add_action( 'loop_end', [ $this, 'end_highlighting' ] );
}

/**
* Stop highlighting search result matches.
*
* This method is called on the loop_end action, where we want to stop highlighting search result matches.
*
* @param WP_Query $query
*/
public function end_highlighting( $query ) {
remove_filter( 'the_title', [ $this, 'highlight_the_title' ], 10 );
remove_filter( 'get_the_excerpt', [ $this, 'highlight_get_the_excerpt' ], 10 );

remove_action( 'loop_end', [ $this, 'end_highlighting' ] );
}

/**
* Filter the_title, replacing it with the highlighted title from the Algolia index.
*
* @param string $title
* @param int $post_id
*
* @return string
*/
public function highlight_the_title( $title, $post_id ) {
$highlighted_title = $this->current_page_hits[ $post_id ]['_highlightResult']['post_title']['value'] ?? null;

if ( ! empty( $highlighted_title ) ) {
$title = $highlighted_title;
}

return $title;
}

/**
* Filter get_the_excerpt, replacing it with the highlighted excerpt from the Algolia index.
*
* @param string $excerpt
* @param WP_Post $post
*
* @return string
*/
public function highlight_get_the_excerpt( $excerpt, $post ) {
$highlighted_excerpt = $this->current_page_hits[ $post->ID ]['_snippetResult']['content']['value'] ?? null;

if ( ! empty( $highlighted_excerpt ) ) {
$excerpt = $highlighted_excerpt;
}

return $excerpt;
}

/**
* Determine whether highlighting is enabled.
*
* @return bool
*/
private function highlighting_enabled() : bool {
return apply_filters( 'algolia_search_highlighting_enabled', true );
}
}
2 changes: 1 addition & 1 deletion includes/indices/class-algolia-searchable-posts-index.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ protected function get_settings() {
),
'attributesToSnippet' => array(
'post_title:30',
'content:30',
'content:' . intval( apply_filters( 'excerpt_length', 55 ) ),
),
'snippetEllipsisText' => '',
);
Expand Down

0 comments on commit 312c8a2

Please sign in to comment.