SearchWP

Version 4 Documentation

Process ACF Fields to Index Expected Data

Note: This documentation is for SearchWP 4
SearchWP 3.x: Process ACF Fields to Index Expected Data

Sometimes after adding Advanced Custom Fields fields to your SearchWP Engine configuration, expected results still don’t show up.

This is likely due to the way ACF has stored the data. For example, let’s review how Relationship fields work. After setting up the field you’re able to pick and choose any number of entries to select and save alongside your post.

ACF Relationship field

Based on the interface of ACF it makes sense to expect that all of the entry titles of the chosen entries would then become searchable, but that’s not the case!

ACF stores only the post IDs of the chosen entries and that’s what SearchWP is indexing. That’s not very useful for your site visitors however.

Thankfully SearchWP makes it extremely easy to change the way this data is indexed, and instead of storing the post IDs as they appear in the ACF data record, we can tell SearchWP to index the Title (or anything else for that matter!)

Here’s what that looks like in practice:

All hooks should be added to your custom SearchWP Customizations Plugin.

<?php
/**
* Tell SearchWP to index the Title from a Relationship ACF field instead of the post ID
*/
add_filter( 'searchwp\source\post\attributes\meta', function( $meta_value, $args ) {
$acf_field_name = 'read_next'; // The ACF Relationship field name.
// If we're not indexing the Read Next field, return the existing meta value.
// This logic also works for sub-fields of an ACF field as well.
if ( $acf_field_name !== substr( $args['meta_key'], strlen( $args['meta_key'] ) - strlen( $acf_field_name ) ) ) {
return $meta_value;
}
// We're going to store all of our Titles together as one string for SearchWP to index.
$content_to_index = '';
if ( is_array( $meta_value ) && ! empty( $meta_value ) ) {
foreach ( $meta_value[0] as $acf_relationship_item ) {
if ( is_numeric( $acf_relationship_item ) ) {
// ACF stores only the post ID but we want the Title.
$content_to_index .= ' ' . get_the_title( absint( $acf_relationship_item ) );
// If you want to index anything else, you can append it to $content_to_index.
}
}
}
// Return the string of content we want to index instead of the data stored by ACF.
return $content_to_index;
}, 20, 2 );

When your index is rebuilt using the Rebuild Index button on the Engines tab of the SearchWP settings screen, SearchWP’s indexer will run the above hook when indexing the ACF field and instead of indexing the post IDs as ACF has stored the data, it will replace those IDs with the Title for each entry.

You can adjust the hook to index any data you’d like, not just the Title!

Another example would be customizing what SearchWP indexes for an ACF Select Field. By default, ACF stores/retrieves only the Select field value but you may want to allow your visitors to also search by the field label. We can use the same hook to do just that:

<?php
// Tell SearchWP to index both value and label from ACF Select field.
add_filter( 'searchwp\source\post\attributes\meta', function( $meta_value, $args ) {
$acf_field_name = 'state'; // ACF Select field name.
if ( $acf_field_name !== substr( $args['meta_key'], strlen( $args['meta_key'] ) - strlen( $acf_field_name ) ) ) {
return $meta_value;
}
if ( ! is_array( $meta_value ) ) {
$meta_value = [ $meta_value ];
}
$acf_field_object = get_field_object( $acf_field_name, $args['post_id'] );
// Append the Select label to the Select value.
if ( isset( $acf_field_object['choices'] ) ) {
foreach ( $meta_value as $key => $val ) {
if ( isset( $acf_field_object['choices'][ $val ] ) ) {
$meta_value[ $key ] .= ' ' . (string) $acf_field_object['choices'][ $val ];
}
}
}
return $meta_value;
}, 20, 2 );