WebDevStudios / wp-search-with-algolia

Improve search on your site. Autocomplete is included, along with full control over look, feel and relevance.
https://wordpress.org/plugins/wp-search-with-algolia/
146 stars 55 forks source link

Cannot use Sort By widget - Woocommerce #382

Closed NowhereWM closed 1 year ago

NowhereWM commented 1 year ago

Describe the bug I am trying to create a sortBy widget for instant search results with the options: a) price ascending b) price descending and c) Default value. It is a woocommerce store (wordpress) or you can try directly this link . . I have followed All the instructions from this page . I am also using wp-search-with-algolia-pro plugin.

To Reproduce Steps to reproduce the behavior:

  1. Go to
  2. Click on sort by widget, it does nothing.

Additional context My current code on instantsearch.php template is:

<?php
/**
 * WP Search With Algolia instantsearch template file.
 *
 * @author  WebDevStudios <contact@webdevstudios.com>
 * @since   1.0.0
 *
 * @version 2.5.2
 * @package WebDevStudios\WPSWA
 */

get_header();

?>
    <div id="ais-wrapper">
    <aside id="ais-facets">
        <div>
    <h3 class="widgettitle"><?php esc_html_e( 'Φιλτράρισμα με τιμή', 'wp-search-with-algolia' ); ?></h3>
    <section class="ais-facets" id="facet-price"></section>
</div>
    <div>
    <h3 class="widgettitle"><?php esc_html_e( 'Κατηγορίες', 'wp-search-with-algolia' ); ?></h3>
    <section class="ais-facets" id="facet-product-cat"></section>
</div>

                        <div>
    <h3 class="widgettitle"><?php esc_html_e( 'Brands', 'wp-search-with-algolia' ); ?></h3>
    <section class="ais-facets" id="facet-brands"></section>
</div>

        </aside>
        <main id="ais-main">
            <div class="algolia-search-box-wrapper">
                <div id="algolia-search-box"></div>

                <div class="sort-by-wrapper">
    <label for="sort-by"><?php esc_html_e( 'Sort by:', 'wp-search-with-algolia' ); ?></label>
    <select id="sort-by">
  <option value="alg_searchable_posts">Default</option>
  <option value="price_replica">Price (Low to High)</option>
  <option value="price_replica_desc">Price (High to Low)</option>
  <!-- Add more sorting options as needed -->
</select>
</div>

                <svg class="search-icon" width="25" height="25" viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg"><path d="M24.828 31.657a16.76 16.76 0 0 1-7.992 2.015C7.538 33.672 0 26.134 0 16.836 0 7.538 7.538 0 16.836 0c9.298 0 16.836 7.538 16.836 16.836 0 3.22-.905 6.23-2.475 8.79.288.18.56.395.81.645l5.985 5.986A4.54 4.54 0 0 1 38 38.673a4.535 4.535 0 0 1-6.417-.007l-5.986-5.986a4.545 4.545 0 0 1-.77-1.023zm-7.992-4.046c5.95 0 10.775-4.823 10.775-10.774 0-5.95-4.823-10.775-10.774-10.775-5.95 0-10.775 4.825-10.775 10.776 0 5.95 4.825 10.775 10.776 10.775z" fill-rule="evenodd"></path></svg>
                <div id="algolia-stats"></div>
                <div id="algolia-powered-by"></div>
            </div>
            <div id="algolia-hits"></div>
            <div id="algolia-pagination"></div>
        </main>

    </div>

    <script type="text/html" id="tmpl-instantsearch-hit">
        <article itemtype="http://schema.org/Article">
            <# if ( data.images.thumbnail ) { #>
                <div class="ais-hits--thumbnail">
                    <a href="{{ data.permalink }}" title="{{ data.post_title }}" class="ais-hits--thumbnail-link">
                        <img src="{{ data.images.thumbnail.url }}" alt="{{ data.post_title }}" title="{{ data.post_title }}" itemprop="image" />
                    </a>
                </div>
            <# } #>

            <div class="ais-hits--content">
                <h2 itemprop="name headline"><a href="{{ data.permalink }}" title="{{ data.post_title }}" class="ais-hits--title-link" itemprop="url">{{{ data._highlightResult.post_title.value }}}</a></h2>

                <!-- 
<div class="excerpt">
    <p>
        <# if ( data._snippetResult['content'] ) { #>
            <span class="suggestion-post-content ais-hits--content-snippet">{{{ data._snippetResult['content'].value }}}</span>
        <# } #>
    </p>
</div>
-->
  <!-- See More button -->
            <a href="{{ data.permalink }}" class="see-more-btn">See More</a>

                <?php
                do_action( 'algolia_instantsearch_after_hit' );
                ?>
            </div>
            <div class="ais-clearfix"></div>
        </article>

    </script>

    <script type="text/javascript">
        window.addEventListener('load', function() {
            if ( document.getElementById("algolia-search-box") ) {
                if ( algolia.indices.searchable_posts === undefined && document.getElementsByClassName("admin-bar").length > 0) {
                    alert('It looks like you haven\'t indexed the searchable posts index. Please head to the Indexing page of the Algolia Search plugin and index it.');
                }

/* Instantiate instantsearch.js */
                var search = instantsearch({
                    indexName: algolia.indices.searchable_posts.name,
                    searchClient: algoliasearch( algolia.application_id, algolia.search_api_key ),
                    routing: {
                        router: instantsearch.routers.history({ writeDelay: 1000 }),
                        stateMapping: {
                            stateToRoute( indexUiState ) {
                                return {
                                    s: indexUiState[ algolia.indices.searchable_posts.name ].query,
                                    page: indexUiState[ algolia.indices.searchable_posts.name ].page
                                }
                            },
                            routeToState( routeState ) {
                                const indexUiState = {};
                                indexUiState[ algolia.indices.searchable_posts.name ] = {
                                    query: routeState.s,
                                    page: routeState.page
                                };
                                return indexUiState;
                            }
                        }
                    }
                });
console.log(search);

                search.addWidgets([

            /* Search box widget */
                    instantsearch.widgets.searchBox({
                        container: '#algolia-search-box',
                        placeholder: 'Ξεκινήστε με μία αναζήτηση...',
                        showReset: false,
                        showSubmit: false,
                        showLoadingIndicator: false,
                    }),

/* Stats widget */
                    instantsearch.widgets.stats({
                        container: '#algolia-stats'
                    }),

                    instantsearch.widgets.configure({
                        hitsPerPage: 10,
                    }),

/* Hits widget */
                    instantsearch.widgets.hits({
                        container: '#algolia-hits',
                        templates: {
                            empty: 'Δεν βρέθηκαν αποτελέσματα για "<strong>{{query}}</strong>".',
                            item: wp.template('instantsearch-hit')
                        },
                        transformData: {
                            item: function (hit) {

                                function replace_highlights_recursive (item) {
                                    if (item instanceof Object && item.hasOwnProperty('value')) {
                                        item.value = _.escape(item.value);
                                        item.value = item.value.replace(/__ais-highlight__/g, '<em>').replace(/__\/ais-highlight__/g, '</em>');
                                    } else {
                                        for (var key in item) {
                                            item[key] = replace_highlights_recursive(item[key]);
                                        }
                                    }
                                    return item;
                                }

                                hit._highlightResult = replace_highlights_recursive(hit._highlightResult);
                                hit._snippetResult = replace_highlights_recursive(hit._snippetResult);

                                return hit;
                            }
                        }
                    }),

/* Pagination widget */
        instantsearch.widgets.pagination({
                        container: '#algolia-pagination'
                    }),

/* Price refinement widget */
instantsearch.widgets.rangeSlider({
    container: '#facet-price',
    attribute: 'price', // Make sure 'price' is the attribute name in your Algolia index
    tooltips: {
        format: function(rawValue) {
            return '$' + Math.round(rawValue);
        }
    }
}),
/* Product Categories refinement widget based on taxonomies.product_cat */
instantsearch.widgets.refinementList({
    container: '#facet-product-cat',
    attribute: 'taxonomies.product_cat',
    operator: 'or',

    sortBy: ['isRefined:desc', 'count:desc', 'name:asc'],
}),
instantsearch.widgets.sortBy({

    container: '#sort-by',
    items: [
        { label: 'Default', value: 'alg_searchable_posts' }, // Main index
        { label: 'Price (Low to High)', value: 'price_replica' }, // Replica for ascending price
        { label: 'Price (High to Low)', value: 'price_replica_desc'}, // Replica for descending price
// Add more sorting options as needed
    ]
}),
                    /* Brands refinement widget */
instantsearch.widgets.refinementList({
    container: '#facet-brands',
    attribute: 'taxonomies.brands', // Updated attribute name
    operator: 'or', // Users can select multiple brands
    limit: 10, // Show 10 brands by default. Adjust this as needed.
    sortBy: ['isRefined:desc', 'count:desc', 'name:asc'],
}),
]);

                /* Start */
                search.start(); 

                // This needs work
                document.querySelector("#algolia-search-box input[type='search']").select()
            }
        });
    </script>

<?php

get_footer();
tw2113 commented 1 year ago

For what it's worth, you missed providing the link to the site in question.

To be certain, you've provided the complete index name for the replica indexes for the sortBy widget, correct? For example, do they have the alg_ prefix as well?

NowhereWM commented 1 year ago

Hello, the website link is auto-motive.gr.

I have used the name of the index, for example it's price_replica and price_replica_desc as they appear inside algolia.

Xenofon

On Mon, Oct 16, 2023, 16:39 Michael Beckwith @.***> wrote:

For what it's worth, you missed providing the link to the site in question.

To be certain, you've provided the complete index name for the replica indexes for the sortBy widget, correct? For example, do they have the alg_ prefix as well?

— Reply to this email directly, view it on GitHub https://github.com/WebDevStudios/wp-search-with-algolia/issues/382#issuecomment-1764507532, or unsubscribe https://github.com/notifications/unsubscribe-auth/BDJF3MNJUJJSWZ7UD7B3X4LX7U2KHAVCNFSM6AAAAAA6BFOVKGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONRUGUYDONJTGI . You are receiving this because you authored the thread.Message ID: @.***>

tw2113 commented 1 year ago

I don't believe you need to be creating the <select> markup yourself, just providing an empty div like <div id="sort-by"></div> would be enough for Algolia's widget to find and render the dropdown for you. Give that a try and let me know if it resolves things.

NowhereWM commented 1 year ago

I am using these now:

instantsearch.widgets.sortBy({

container: '#sort-by',
items: [
    { label: 'Default', value: 'alg_searchable_posts' }, // Main index
    { label: 'Price (Low to High)', value: 'price_replica' }, //

Replica for ascending price { label: 'Price (High to Low)', value: 'price_replica_desc'}, // Replica for descending price // Add more sorting options as needed ] }),

And it's not sorting again :/ I removed the html selector, I attach you our current php of instantsearch

Xenofon

Επισκόπου Αμβροσίου 6 Θεσσαλονίκη, Ελλάδα

@. @.> + 30 23 11 11 88 30 <+302311118830> www.nowhere.gr http://www.nowhere.gr*

On Mon, Oct 16, 2023 at 5:59 PM Michael Beckwith @.***> wrote:

I don't believe you need to be creating the markup yourself, just providing an empty div like

would be enough for Algolia's widget to find and render the dropdown for you. Give that a try and let me know if it resolves things.

— Reply to this email directly, view it on GitHub https://github.com/WebDevStudios/wp-search-with-algolia/issues/382#issuecomment-1764675895, or unsubscribe https://github.com/notifications/unsubscribe-auth/BDJF3MO2FUP75BD4KMCA4QDX7VDWVAVCNFSM6AAAAAA6BFOVKGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONRUGY3TKOBZGU . You are receiving this because you authored the thread.Message ID: @.***>

tw2113 commented 1 year ago

I know I have some blog posts on our WebDevStudios blog about Woocommerce details, and a lot of that got rolled into our Pro plugin. Otherwise, I'm not quite sure what woocommerce-algolia you're referring to.

The only Algolia plugins that we actively support ourselves will be both WP Search with Algolia, and WP Search with Algolia Pro.

I'm still seeing the self-typed up select input when I look at the site and view-source. Is it possible you need to do a cache clearing?

NowhereWM commented 1 year ago

I just cleared cache.

Xenofon

On Mon, Oct 16, 2023, 18:25 Michael Beckwith @.***> wrote:

I know I have some blog posts on our WebDevStudios blog about Woocommerce details, and a lot of that got rolled into our Pro plugin. Otherwise, I'm not quite sure what woocommerce-algolia you're referring to.

The only Algolia plugins that we actively support ourselves will be both WP Search with Algolia, and WP Search with Algolia Pro.

I'm still seeing the self-typed up select input when I look at the site and view-source. Is it possible you need to do a cache clearing?

— Reply to this email directly, view it on GitHub https://github.com/WebDevStudios/wp-search-with-algolia/issues/382#issuecomment-1764736758, or unsubscribe https://github.com/notifications/unsubscribe-auth/BDJF3MIYV5YECRGVBZQHZIDX7VGXDAVCNFSM6AAAAAA6BFOVKGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONRUG4ZTMNZVHA . You are receiving this because you authored the thread.Message ID: @.***>

tw2113 commented 1 year ago

still seeing this in the view-source:

<div class="sort-by-wrapper">
    <label for="sort-by">Sort by:</label>
    <select id="sort-by">
  <option value="alg_searchable_posts">Default</option>
  <option value="price_replica">Price (Low to High)</option>
  <option value="price_replica_desc">Price (High to Low)</option>
  <!-- Add more sorting options as needed -->
</select></div>

as opposed to

<div id="sort-by"></div>

like the documentation generally leans towards.

NowhereWM commented 1 year ago

Fixed! We had another file loaded on the child theme :)

We also fixed the importing issue.

Some more questions: 1) Images we used this code you suggested to change the sizes we sent to algolia. What we need is to push the correct size (full) to our main products because now it's mixed, some products on instant search results return thumbnails and others return the correct size (650x650). Is there a way to control the image size we push to algolia? 2) We find it difficult to add a correct "add to cart button" to add the product from search results to our cart. Do you have any documentation that might help us? 3) Where should we look for documentation, directly in Algolia or on your Github? 4) How can we add elements to the product loop? We want to display the brand Icon inside instasearch product results. Which template are you using in your plugin for the product loop? 5) Finally, do you have a guide or plugin that could help us configure the " events" algolia suggests us to use? We want also to use the "recommend" feature algolia offers besides "search".

Thank you very much for your help, I appreciate it.

Xenofon

Επισκόπου Αμβροσίου 6 Θεσσαλονίκη, Ελλάδα

@. @.> + 30 23 11 11 88 30 <+302311118830> www.nowhere.gr http://www.nowhere.gr*

On Mon, Oct 16, 2023 at 7:03 PM Michael Beckwith @.***> wrote:

still seeing this in the view-source:

as opposed to

like the documentation generally leans towards.

— Reply to this email directly, view it on GitHub https://github.com/WebDevStudios/wp-search-with-algolia/issues/382#issuecomment-1764805550, or unsubscribe https://github.com/notifications/unsubscribe-auth/BDJF3MLBLOIAY72VK2CNMK3X7VLCHAVCNFSM6AAAAAA6BFOVKGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONRUHAYDKNJVGA . You are receiving this because you authored the thread.Message ID: @.***>

tw2113 commented 1 year ago

First I can see for any issues around importing, but good to hear that's presently resolved.

  1. I'd check out the filters found at https://github.com/WebDevStudios/wp-search-with-algolia/blob/main/includes/class-algolia-utils.php#L115-L141 which is where we do all the image fetching. The first filter allows you to customize the sizes that get fetched automatically, so you could return an array of say [ 'thumbnail', 'full' ] and it'd index both. as part of the images property in the Algolia Index. The other is a bit more of a generic one where you can specify a URL, width, and height, for an image. I just opened an enhancement issue for this 2nd filter to get the post ID passed as an extra parameter. Using the first filter will be more advantageous right now.
  2. In case you haven't, I would check out https://www.businessbloomer.com/woocommerce-custom-add-cart-urls-ultimate-guide/. With that, you could piece together something like href="https://yourdomain.com/?add-to-cart=25&quantity=1" with the 25 from this example string being replaced with {{ data.post_id }} as part of the hit template area. Example: href="https://yourdomain.com/?add-to-cart={{ data.post_id }}&quantity=1"
  3. All the content found in the template files would technically be Algolia documentation because the instantsearch.php and autocomplete.php are general PHP files that we load, and let Instantsearch and Autocomplete javascript libraries do their thing. See: https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/ and https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/autocomplete/js/

Most of our documentation is going to be more around indexing and index/settings management via code.

  1. Instantsearch makes use of this template section: https://github.com/WebDevStudios/wp-search-with-algolia/blob/main/templates/instantsearch.php#L47-L72 Details you'd want to be able to output as part of that template you'd need to get added to the Algolia index, so that it ends up being part of the data object that is returned and rendered with each hit. You can add new properties via the "shared attributes" filter setup, some quick examples can be found at https://github.com/WebDevStudios/wp-search-with-algolia/wiki/Custom-Attributes but let me know if you need something a bit more specific.
  2. We don't have anything out of box for this topic, as it's still a bit new for myself overall. https://www.algolia.com/doc/guides/sending-events/getting-started/ is going to be your best bet for this topic. I believe we're largely on the right versions of Instantsearch for this, but Autocomplete is still on version 0.38.x and we're still exploring best ways forward. Chances are we're going to release a version of the plugin with a setting to switch between currently used Autocomplete vs "Modern" Autocomplete.
tw2113 commented 1 year ago

Closing as there's nothing actionable from us with the plugin. Discussion can continue.