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.
what is “Relevanssi custom excerpt creation”?
That’s fancy namy for enabling custom excerpts from Relevanssi settings.
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!
Can you show me what $customfield_data[$post->ID] contains before you unserialize it?
Sure thing: http://pastie.org/4795765
It looks like you’re on the right path, as it seems to loop twice – this is from a var_dump just inside the if(isset… condition
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 : )
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…
I’m not sure how that value could be a Boolean, really. It should be an array. More definitive answer would require a closer look under the hood.
the serialisation format seems to have changed?
i had to replace:
$detail = unserialize($match->customfield_detail);
with:
$detail = json_decode($match->customfield_detail, true);
Correct, it was changed in version 2.1. JSON is safer than serializing. I’ll update this post to reflect the change.