Posted on

Which custom fields had the hit?

While the free version of Relevanssi will match search terms in custom field content, it doesn’t know which custom field had the matching content. Premium has that information and it can be made available.

First, you need this in your functions.php:

add_filter('relevanssi_match', 'cfdetail');
function cfdetail($match) {
	global $customfield_data;
	$customfield_data[$match->doc] = $match->customfield_detail;
	return $match;
}

This filter stores the data about the custom field hits in a global variable where it can easily be accessed.

How you can use it? You can, for example, make the custom field content available to Relevanssi custom excerpt creation:

add_filter('relevanssi_excerpt_content', 'excerpt_function', 10, 3);
function excerpt_function($content, $post, $query) {
	global $customfield_data;
 
	if (isset($customfield_data[$post->ID])) {
		$fields = json_decode($customfield_data[$post->ID]);
		foreach(array_keys($fields) as $field) {
			$field_value = get_post_meta($post->ID, $field, TRUE);
			$content .= (is_array($field_value) ? implode(' ', $field_value) : $field_value);
		}
	}
 
	return $content;
}

Another option is to simply print out the custom field content in your search results template. $customfield_data is an array where the key is the post ID and value is a serialized array of (custom field name => number of hits in that custom field) pairs.

Adding weight boost for particular custom field

If you want to boost weight for results that match a particular custom field, you can use this:

add_filter('relevanssi_match', 'rlv_cf_boost');
function rlv_cf_boost($match) {
	$detail = json_decode($match->customfield_detail);
	if (!empty($detail)) {
		if (isset($detail['custom_field_name'])) {
			$match->weight = $match->weight * 10;
		}
	}
	return $match;
}

Now any posts that have matches in “custom_field_name” custom field will get a 10x weight boost.

10 comments Which custom fields had the hit?

  1. Hi Mikko,
    I’m using this script, and it’s correctly finding and displaying my custom field content. However, I’m getting an issue with the serialised array and array_keys() in the foreach: as each array is showing a match (i.e. 1), it’s interpreting it as a boolean. Any thoughts how to get around this error? You can view it here: http://ipta.com.au.s143882.gridserver.com/?s=smith

    Thanks!

  2. As a result, I’ve just changed the condition to the following:
    if ( isset($customfield_data[$post->ID]) && $customfield_data[$post->ID] != ” ) {

    Thanks for the insight!

    Keep up the good work : )

  3. Warning: array_keys() expects parameter 1 to be array, boolean given in functions.php

    Warning: Invalid argument supplied for foreach() in

    anyone else get those errors? using ACF and some of my posts have no custom fields. This seems to be an issue if custom fields are null…

  4. the serialisation format seems to have changed?

    i had to replace:
    $detail = unserialize($match->customfield_detail);
    with:
    $detail = json_decode($match->customfield_detail, true);

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.