craftcms / shopify

Synchronize and extend product data from your Shopify storefront.
MIT License
45 stars 25 forks source link

How can products be included in site search? #102

Closed AmandaLutzTO closed 7 months ago

AmandaLutzTO commented 7 months ago

Description

Client wants products to be included in site search.

Steps to reproduce

  1. Example twig code for site search is {% set entries = craft.entries().search(query).orderBy('score').limit(4) %}
  2. Results includes pagination
  3. Plugin documentation includes many instances of "using the .search() param" so I know products can be searched
  4. But can site entries and products be searched and ordered by "score" together?

Additional info

linear[bot] commented 7 months ago

PT-1555 How can products be included in site search?

nfourtythree commented 7 months ago

Hi @AmandaLutzTO

Thank you for you message. Unfortunately, out of the box it is not possible to search across different element types.

However there is a bit of a work around solution that you could try which would be the following:

{% set query = 't-shirt' %}
{% set elementQuery = create('craft\\elements\\db\\ElementQuery', ['craft\\base\\Element']) %}
{% do elementQuery.search(query) %}
{% do elementQuery.orderBy('score') %}
{% do elementQuery.limit(4) %}
{% set elementIds = elementQuery.ids() %}

{% set entries = craft.entries.id(elementIds).fixedOrder().indexBy('id').all() %}
{% set products = craft.shopifyProducts.id(elementIds).fixedOrder().indexBy('id').all() %}

<ul>
  {% for id in elementIds %}
    <li>
      {% if entries[id] is defined %}
          {{ entries[id].title }}
        {% elseif products[id] is defined %}
          {{ products[id].title }}
        {% endif %}
    </li>
  {% endfor %}
</ul>

Hope this helps, thanks!

AmandaLutzTO commented 7 months ago

This was a good solution. Thanks for your help!

For anyone else who finds this: watch out! This method also returns matching assets, categories, etc to elementQuery. Listing entries and products with the for/if statements was fine but it really messed up my pagination.

I ended up doing a search query for elements, a search query for products, merging them to 1 collection, and then my for loop includes a twig sort with spaceship operator (https://twig.symfony.com/doc/3.x/filters/sort.html). I'm open to modifying my code if anyone has thoughts/suggestions for improvement.