Ajax Search Pro Knowledge Base
Buy Ajax Search Pro!DocumentationGet SupportDevelopment
  • Knowledge Base
  • Safe Coding Guideline
  • Hooks
    • Filters
      • Query & Output
        • asp_query_args
        • asp_query_{type}
        • asp_cached_content
        • asp_pre_get_front_filters
        • asp_before_ajax_output
        • asp_shortcode_output
        • asp_print_search_query
      • Keyword Suggestions
      • Search Results
        • asp_suggested_phrases
        • asp_results
        • asp_cpt_results
        • asp_buddyp_results
        • asp_attachment_results
        • asp_comment_results
        • asp_blog_results
        • asp_terms_results
        • asp_peepso_group_results
        • asp_peepso_activities_results
        • asp_only_keyword_results
        • asp_only_non_keyword_results
        • asp_result_groups
      • CSS & JS
        • asp_load_js
        • asp_load_css
        • asp_load_css_js
      • Template & Output
        • asp_icl_t
      • Index Table Related
        • asp_index_on_save_stop
        • asp_indexing_keywords
        • asp_indexing_string_pre_process
        • asp_indexing_string_post_process
        • asp_post_content_before_tokenize_clear
        • asp_post_content_before_tokenize
        • asp_post_excerpt_before_tokenize
        • asp_post_title_before_tokenize
        • asp_file_contents_before_tokenize
        • asp_post_permalink_before_tokenize
        • asp_index_terms
        • asp_post_custom_field_before_tokenize
        • asp_index_cf_contents_before_tokenize
        • asp_index_before_shortcode_execution
        • asp_index_after_shortcode_execution
    • Templating
      • Filter layouts Templating
      • Result Templating
    • Constants
  • Frontend Filters
    • Taxonomy Filters
      • Restricting results to the same category as the current post object
      • How to automatically check/select filter values based on the archive page?
    • Frontend filters API
  • Tips & Miscellaneous
    • Divi
      • Divi Blogs Live Search and Filter
    • Jet Engine
      • Jet Engine Listing Grid Live Search and Filter
      • Searching Jet Engine Custom Meta Storage fields
    • Tutorials
      • PDF results thumbnails
      • Demo setup: Staff search and Filter
      • Demo Setup: WooCommerce Search
      • Demo setup: WooCommerce Shop Search and Filter
      • Demo Setup: Events Search – Events Manager
      • Demo Setup: Events Search – The Events Calendar
      • Compact ‘pop-out’ search bar placement on specific pages only
      • Index Table – Indexing ACF repeater field titles and contents
      • Change Suggested Phrases conditionally
      • How to add shortcode to the results content?
      • How to add variables to the “redirect to url” or the “show more url”?
      • Indexing Shortcodes within custom field contents
    • Post Types
      • Index Table - Indexing child post contents to parent
      • Limit results to specific post IDs only
      • Filter posts (or CPT) which user can’t access
      • Restricting results by user Groups using the Groups plugin by itthinx
      • Limiting results to specific posts by parent ID
      • Limit results to current page children
      • Excluding posts or CPT by parent ID(s)
      • Searching posts, pages (or any CPT) by specified keywords only, nothing else
      • Showing the post type name in result title or content
      • Searching within given categories/taxonomy terms only
      • Search only in the same category as the current post or page (single page)
      • Search only within the current category (or any taxonomy) archive
      • Filtering pages by page template
    • Taxonomy Terms
      • Displaying taxonomy name in taxonomy term results
      • Limiting taxonomy term results to specific term IDs only
    • WooCommerce
      • Displaying On Sale products only in WooCommerce
      • Ordering product by stock status
      • Making a product in-stock & out of stock filter
      • Add to cart button for Vertical and Horizontal results
      • Get formatted price in result title or in content
      • Showing products in-stock only
      • Showing in-stock and backorder products only
      • Excluding hidden catalog products
      • Showing featured products first
      • How to search products & product SKU?
      • How to search Products by variation SKUs?
      • Search product attributes
      • How to search users by city, state, zip code… ?
    • Compatibility
      • WPML Compatibility issues and fixes
    • Files & Media
      • Searching Image EXIF metadata
    • Other
      • Restrict results from the current author archive page
      • Presetting search options via a custom URL
      • Matomo analytics tracking integration
      • Replace search keywords (whole words)
      • Replace or remove characters from search phrase
      • Adding spaces in search phrase between alphabetics and numbers
      • How to change the results URL to something else?
      • Numbering the results
      • How to use the search without the live ajax feature, as a regular search?
      • Empty search input field on the search results page
      • Singular and Plural keywords index
  • Other
    • SearchQuery
    • REST API
    • Building a custom REST API
    • Javascript API
    • Javascript Hooks
      • asp_redirect_url
      • asp_search_data
      • asp_live_load_html
      • asp_search_html
      • asp_compact_width
    • Theme Functions
Powered by GitBook
On this page
  • Post version 4.27
  • Pre version 4.27
  1. Tips & Miscellaneous
  2. Other

Singular and Plural keywords index

Automatic singularization and pluralization with Ajax Search Pro

PreviousEmpty search input field on the search results pageNextSearchQuery

Last updated 1 month ago

Post version 4.27

After version 4.27 an option is available on the Index Table -> Advanced settings menu. After enabling the option a needs to be created.

Pre version 4.27

The tutorial below is outdated, after Ajax Search Pro 4.27 is no longer needed, please see the Post version 4.27 section above.

// ---- !!! ONLY COPY PASTE CODE BELOW THIS LINE to the functions.php in your theme directory !!! ----// ---- AJAX SEARCH PRO: BEGIN SEMI-AUTOMATIC PLURALIZATION OF ENGLISH KEYWORDS -----
class Inflect
{
    static $plural = array(
        '/(quiz)$/i'               => "$1zes",
        '/^(ox)$/i'                => "$1en",
        '/([m|l])ouse$/i'          => "$1ice",
        '/(matr|vert|ind)ix|ex$/i' => "$1ices",
        '/(x|ch|ss|sh)$/i'         => "$1es",
        '/([^aeiouy]|qu)y$/i'      => "$1ies",
        '/(hive)$/i'               => "$1s",
        '/(?:([^f])fe|([lr])f)$/i' => "$1$2ves",
        '/(shea|lea|loa|thie)f$/i' => "$1ves",
        '/sis$/i'                  => "ses",
        '/([ti])um$/i'             => "$1a",
        '/(tomat|potat|ech|her|vet)o$/i'=> "$1oes",
        '/(bu)s$/i'                => "$1ses",
        '/(alias)$/i'              => "$1es",
        '/(octop)us$/i'            => "$1i",
        '/(ax|test)is$/i'          => "$1es",
        '/(us)$/i'                 => "$1es",
        '/s$/i'                    => "s",
        '/$/'                      => "s"
    );
    
    static $singular = array(
        '/(quiz)zes$/i'             => "$1",
        '/(matr)ices$/i'            => "$1ix",
        '/(vert|ind)ices$/i'        => "$1ex",
        '/^(ox)en$/i'               => "$1",
        '/(alias)es$/i'             => "$1",
        '/(octop|vir)i$/i'          => "$1us",
        '/(cris|ax|test)es$/i'      => "$1is",
        '/(shoe)s$/i'               => "$1",
        '/(o)es$/i'                 => "$1",
        '/(bus)es$/i'               => "$1",
        '/([m|l])ice$/i'            => "$1ouse",
        '/(x|ch|ss|sh)es$/i'        => "$1",
        '/(m)ovies$/i'              => "$1ovie",
        '/(s)eries$/i'              => "$1eries",
        '/([^aeiouy]|qu)ies$/i'     => "$1y",
        '/([lr])ves$/i'             => "$1f",
        '/(tive)s$/i'               => "$1",
        '/(hive)s$/i'               => "$1",
        '/(li|wi|kni)ves$/i'        => "$1fe",
        '/(shea|loa|lea|thie)ves$/i'=> "$1f",
        '/(^analy)ses$/i'           => "$1sis",
        '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i'  => "$1$2sis",        
        '/([ti])a$/i'               => "$1um",
        '/(n)ews$/i'                => "$1ews",
        '/(h|bl)ouses$/i'           => "$1ouse",
        '/(corpse)s$/i'             => "$1",
        '/(us)es$/i'                => "$1",
        '/s$/i'                     => ""
    );
    
    static $irregular = array(
        'move'   => 'moves',
        'foot'   => 'feet',
        'goose'  => 'geese',
        'sex'    => 'sexes',
        'child'  => 'children',
        'man'    => 'men',
        'tooth'  => 'teeth',
        'person' => 'people'
    );
    
    static $uncountable = array( 
        'sheep', 
        'fish',
        'deer',
        'series',
        'species',
        'money',
        'rice',
        'information',
        'equipment'
    );
    
    public static function pluralize( $string ) 
    {
        // save some time in the case that singular and plural are the same
        if ( in_array( strtolower( $string ), self::$uncountable ) )
            return $string;
            
    
        // check for irregular singular forms
        foreach ( self::$irregular as $pattern => $result )
        {
            $pattern = '/' . $pattern . '$/i';
            
            if ( preg_match( $pattern, $string ) )
                return preg_replace( $pattern, $result, $string);
        }
        
        // check for matches using regular expressions
        foreach ( self::$plural as $pattern => $result )
        {
            if ( preg_match( $pattern, $string ) )
                return preg_replace( $pattern, $result, $string );
        }
        
        return $string;
    }
    
    public static function singularize( $string )
    {
        // save some time in the case that singular and plural are the same
        if ( in_array( strtolower( $string ), self::$uncountable ) )
            return $string;

        // check for irregular plural forms
        foreach ( self::$irregular as $result => $pattern )
        {
            $pattern = '/' . $pattern . '$/i';
            
            if ( preg_match( $pattern, $string ) )
                return preg_replace( $pattern, $result, $string);
        }
        
        // check for matches using regular expressions
        foreach ( self::$singular as $pattern => $result )
        {
            if ( preg_match( $pattern, $string ) )
                return preg_replace( $pattern, $result, $string );
        }
        
        return $string;
    }
    
    public static function pluralize_if($count, $string)
    {
        if ($count == 1)
            return "1 $string";
        else
            return $count . " " . self::pluralize($string);
    }
}

add_filter( 'asp_indexing_string_post_process', 'asp_index_add_singular_plural', 10, 1 );
function asp_index_add_singular_plural($s) {
    $final = array();
	$words = explode(' ', $s);
	
    foreach ($words as $word) {
        $singular = Inflect::singularize($word);
        $plural = Inflect::pluralize($word);

        $final[] = $word;

        if ($singular != $word)
            $final[] = $singular;

        if ($plural != $word)
            $final[] = $plural;
    }
	
    return implode(' ', $final);
}
// ---- AJAX SEARCH PRO: END SEMI-AUTOMATIC PLURALIZATION OF ENGLISH KEYWORDS -----
// --------------------------------------------------------------------------------

Use the custom code snippet below to automatically singularize and pluralize English keywords when using the engine. This algorightm is efficient, but of course not a 100% accurate.

After adding the code a must be generated

Index Table
new index
What is this, and where do I put this custom code?
new index
Enabling singularization and pluralization feature in Ajax Search Pro