How to search for words with special characters

If you’re using a language that includes accents or other diacritical marks, you may find that search results are different for the accented search term vs the unaccented one. In order to return the same results for your searches regardless of accent use, you can use the following snippet.

NB: this code may not work for certain dynamically generated content such as Block Editor Blocks.

Add the following code to a custom plugin or your theme’s functions.php file. Check out our Enhancing ElasticPress with Custom Functions article for further explanation on how to do that.

PHP
<?php
/**
 * Add `.folded` fields to some existent properties in the mapping
 *
 * @param array $mapping Current mapping.
 * @return array
 */
function ep_custom_mapping_add_folded_fields( $mapping ) {
	if ( version_compare( \ElasticPress\Elasticsearch::factory()->get_elasticsearch_version(), '7.0', '<' ) ) {
		$post_mapping = &$mapping['mappings']['post'];
	} else {
		$post_mapping = &$mapping['mappings'];
	}

	// Create a new analyzer.
	$mapping['settings']['analysis']['analyzer']['folding'] = [
		'tokenizer' => 'standard',
		'filter'    => [ 'lowercase', 'asciifolding' ],
	];

	// Add the folded field to some properties.
	$new_fields = [ 'post_title', 'post_content_filtered' ];
	foreach ( $new_fields as $field ) {
		$post_mapping['properties'][ $field ]['fields'] = [
			'folded' => [
				'type'     => $post_mapping['properties'][ $field ]['type'],
				'analyzer' => 'folding',
			],
		];
	}

	// Add the folded field to metadata.
	foreach ( $post_mapping['dynamic_templates'] as &$dynamic_template ) {
		if ( isset( $dynamic_template['template_meta_types'] ) ) {
			break;
		}
	}
	$dynamic_template['template_meta_types']['mapping']['properties']['value']['fields']['folded'] = [
		'type'     => 'text',
		'analyzer' => 'folding',
	];

	return $mapping;
}
add_filter( 'ep_post_mapping', 'ep_custom_mapping_add_folded_fields' );

/**
 * Add the folded fields to the weighting config, based on existent fields.
 *
 * @param array $config The weighting config.
 * @return array
 */
function ep_custom_add_folded_post_title( $config ) {
	if ( isset( $config['post_title'] ) ) {
		$config['post_title.folded'] = $config['post_title'];
	}
	if ( isset( $config['post_content'] ) ) {
		$config['post_content_filtered.folded'] = $config['post_content'];
	}

	// If you want to use meta fields, make sure to edit the field name here.
	$config['meta.custom_field.value.folded'] = $config['post_content'];

	return $config;
}
add_filter( 'ep_weighting_default_post_type_weights', 'ep_custom_add_folded_post_title' );

/**
 * Add folded fields to the default configuration.
 *
 * If the weighting dashboard was not saved yet (multisites, for example),
 * add folded fields to the default.
 *
 * @param array $config Default config.
 * @return array
 */
function ep_custom_weighting_config_add_folded_fields( $config ) {
	foreach ( $config as &$post_type_fields ) {
		$post_type_fields = ep_custom_add_folded_post_title( $post_type_fields );
	}
	return $config;
}
add_filter( 'ep_weighting_configuration_for_search', 'ep_custom_weighting_config_add_folded_fields' );