algolia / algoliasearch-wordpress

❌🗑🙅‍♂️ Algolia Search plugin for WordPress is no longer supported. Please use our API client guide instead
https://www.algolia.com/doc/integration/wordpress/getting-started/quick-start/
GNU General Public License v2.0
359 stars 115 forks source link

rangeSlider not working with meta fields #797

Closed alishanster closed 5 years ago

alishanster commented 6 years ago

What did you expect to happen?

Working rangeSlider for prices.

What happened instead?

rangeSlider widget not showing up

How can we reproduce this behavior?

Create custom post types with post meta fields, push post meta fields to Algolia, make meta fields searchable. I also integrated those fields into a custom ranking. I was not using ACF plugin so I simply replaced get_field() to (float) get_post_meta( $post->ID, 'price', true ); .
Note: when I do console.log(data), the price attribute is showing and it is a numeric value

Can you provide a link to a page which shows this issue?

http://carz.stylemix.biz/?s=

Technical info

// index Listings meta_fields

add_filter( 'algolia_post_shared_attributes', 'my_post_attributes', 10, 2 );
add_filter( 'algolia_searchable_post_shared_attributes', 'my_post_attributes', 10, 2 );

/**
 * @param array   $attributes
 * @param WP_Post $post
 *
 * @return array
 */
function my_post_attributes(  $attributes,  $post ) {

    if ( 'listings' !== $post->post_type ) {
        // We only want to add an attribute for the 'listings' post type.
        // Here the post isn't a 'listings', so we return the attributes unaltered.
        return $attributes;
    }

    // Get the field value with the 'get_field' method and assign it to the attributes array.
    // @see https://www.advancedcustomfields.com/resources/get_field/
    $attributes['engine'] = get_post_meta( $post->ID, 'engine', true );
    $attributes['price'] = (float) get_post_meta( $post->ID, 'price', true );
    $attributes['mileage'] = get_post_meta( $post->ID, 'mileage', true );

    // Always return the value we are filtering.
    return $attributes;
}

add_filter( 'algolia_posts_listings_index_settings', 'my_posts_index_settings' );
// We could also have used a more general hook 'algolia_posts_index_settings',
// but in that case we would have needed to add a check on the post type
// to ensure we only adjust settings for the 'listings' post_type.

/**
 * @param array $settings
 *
 * @return array
 */
function my_posts_index_settings(  $settings ) {

    // Make Algolia search into the 'price' field when searching for results.
    // Using ordered instead of unordered would make words matching in the beginning of the attribute
    // make the record score higher.
    // @see https://www.algolia.com/doc/api-client/ruby/parameters#attributestoindex
    $settings['attributesToIndex'][] = 'unordered(engine)';
    $settings['attributesToIndex'][] = 'unordered(price)';
    $settings['attributesToIndex'][] = 'unordered(mileage)';

    // Make Algolia return a pre-computed snippet of 50 chars as part of the result set.
    // @see https://www.algolia.com/doc/api-client/ruby/parameters#attributestohighlight
    $settings['attributesToSnippet'][] = 'engine:50';
    $settings['attributesToSnippet'][] = 'price:50';
    $settings['attributesToSnippet'][] = 'mileage:50';

    // Always return the value we are filtering.
    return $settings;
}

    add_filter( 'algolia_posts_listings_index_settings', 'price_index_settings');
    // We could also have used a more general hook 'algolia_posts_index_settings',
    // but in that case we would have needed to add a check on the post type
    // to ensure we only adjust settings for the 'video' post_type.

    /**
     * @param array $settings
     *
     * @return array
     */
    function price_index_settings( array $settings ) {

        // By default, the plugin uses 'is_sticky' and the 'post_date' in the custom ranking.
        // Here we first retrieve the custom ranking to be able to alter it with more control.
        $customRanking = $settings['customRanking'];

        // We add our custom ranking rule at the beginning of the rules so that
        // it is the first one considered in the algorithm.
        array_unshift( $customRanking, 'desc(price)' );

        // We override the initial custom ranking rules.
        $settings['customRanking'] = $customRanking;

        // Always return the value we are filtering.
        return $settings;
    }
alishanster commented 6 years ago

Here is what I have in instantsearch.php:

                               search.addWidget(
                      instantsearch.widgets.rangeSlider({
                        container: '#aligolia-price',
                        attributeName: 'price',
                        templates: {
                          header: '<h3 class="widgettitle">Price</h3>'
                        },
                        tooltips: {
                          format: function(rawValue) {
                            return 'OMR' + Math.round(rawValue).toLocaleString();
                          }
                        }
                      })
                    );
alishanster commented 6 years ago

Upd. I also added attributesForFaceting to function my_posts_index_settings( $settings ), still no luck...

add_filter( 'algolia_posts_listings_index_settings', 'my_posts_index_settings' );
// We could also have used a more general hook 'algolia_posts_index_settings',
// but in that case we would have needed to add a check on the post type
// to ensure we only adjust settings for the 'listings' post_type.

/**
 * @param array $settings
 *
 * @return array
 */
function my_posts_index_settings(  $settings ) {

    // Make Algolia search into the 'price' field when searching for results.
    // Using ordered instead of unordered would make words matching in the beginning of the attribute
    // make the record score higher.
    // @see https://www.algolia.com/doc/api-client/ruby/parameters#attributestoindex
    $settings['attributesToIndex'][] = 'unordered(engine)';
    $settings['attributesToIndex'][] = 'unordered(price)';
    $settings['attributesToIndex'][] = 'unordered(mileage)';

    // Make Algolia return a pre-computed snippet of 50 chars as part of the result set.
    // @see https://www.algolia.com/doc/api-client/ruby/parameters#attributestohighlight
    $settings['attributesToSnippet'][] = 'engine:50';
    $settings['attributesToSnippet'][] = 'price:50';
    $settings['attributesToSnippet'][] = 'mileage:50';

    $settings['attributesForFaceting'][] = 'price';
    $settings['attributesForFaceting'][] = 'mileage';

    // Always return the value we are filtering.
    return $settings;
}
adrienjoly commented 6 years ago

The slider seems to be working now, doesn't it?

alishanster commented 6 years ago

Yes! Thank you guys for the help. I had to declare attributesForFaceting not only to my custom post type index (posts_listing), but to searchable_posts index as well. In other words just add another filter:

add_filter( 'algolia_searchable_posts_index_settings', 'my_posts_index_settings' );