Algolia e usando instantsearch.js do seu script para Shopify
"Bons artistas copiam, grandes artistas roubam." - Steve Jobs
Inspirado por pimoroni.com Eu queria implementar uma pesquisa semelhante na nossa loja virtual, buyzero.de Também. buyzero.de é actualmente alimentado por Shopify.
A pesquisa mostra os resultados à medida que você digita - na página principal, substituindo dinamicamente o conteúdo préviamente exibido. Muito legal, muito útil - e muito, muito rápido (graças a Algolia!)
Desde que lutei com a documentação disponível sobre a Algolia, e o seu serviço de bordo não foi muito útil, tive que descobrir as coisas sozinho, e através do Googling extensivo.
Este é um resumo da minha experiência na implementação da Algolia. Fi-lo num único dia, numa única sessão de cerca de 12 - 14 horas de codificação.
Preparação Sugerida: injeção de código de desenvolvimento em sua página
Sugiro a utilização da extensão Google Chrome Tampermonkey para injetar CSS e Javascript do seu disco rígido local enquanto você se desenvolve.
Para fazer isso, você tem que habilitar o acesso a arquivos para o Tampermonkey. Abrir:
Clique em Detalhes e mude "Permitir acesso a URLs de arquivos" em
Crie o seguinte novo script de usuário em Tampermonkey:
// ==UserScript==== // @nome Algolia-Inject // @namespace https://pi3g.com/ // @versão 0.5 // @description injectar ficheiro local para testar Algolia! // @author Maximilian Batz // @grant GM_getResourceText // @grant GM_addStyle // @noframes // @include https://buyzero.de/* // @resource YOUR_CSS file://D:\algolia_jr.css // @require file://D:\algolia_jr.js // ===/UserScript==== var my_css = GM_getResourceText ("YOUR_CSS"); GM_addStyle(my_css);
Explicação:
- você tem que conceder o getResourceText e o addStyle para poder acessar e injetar o arquivo CSS
- noframes por não executar uma segunda vez nos frames que Shopify aparentemente carrega, e que também coincidiriam com o domínio
- incluir -> irá coincidir no buyzero.de. Você pode querer mudar essa linha
- recurso utilizado para importar arquivo CSS. Forneça o caminho ... no Linux ele pode ser file:///home/whatever/whatever - notar a tripla barra oblíqua para a frente
- exija - inclua seu arquivo javascript
- userscript: este é o userscript para adicionar o arquivo CSS
Adicionando o Código Algolia
Com a parte de "como se desenvolver" fora do caminho, aqui está o meu código como código de amostra num pequeno e agradável ficheiro ZIP.
Por favor, não copie pasta deste blog, pois não tenho certeza se o WordPress vai destruir a formatação do código ... use o .js no arquivo ZIP para copiar.
Por favor note que as dependências Algolia / arquivos JavaScript já foram instalados em nosso tema Shopify - instalando o plugin Algolia Shopify. Também a nossa datastore foi configurada, etc. O Algolia já estava (e ainda está) a servir resultados de pesquisa numa gota abaixo enquanto você digitava na caixa de pesquisa.
Eu acompanho-o através das partes importantes do código:
começamos aj_setup() uma vez que o documento esteja pronto, para injetar nossa nova funcionalidade de busca.
Por favor, note que eu uso aj para preender as minhas funções & id's para este script. Você pode usar o que quiser, não é exigido por Algolia.
O recipiente
em aj_setup() eu preparei um novo container para os resultados da busca (provavelmente seria melhor incluir isso diretamente no seu arquivo temático - para desenvolver isso foi mais fácil).
esta é a parte HTML da pesquisa
$(".main-content").before('<div id="aj-search-container" class="aj-main-content full-width"><div class="background"><div class="pattern"><div class="container"><div class="row"><div class="col-md-12"><div class="row"><div class="col-md-12 center-column content-without-background">'+
""+
"<h1>Suchresultate für: <span id='sc-query'></span></h1>" +
"" +" +
"" +
"" +
"" +
"" +
"
"" +" +
"" +
"" +
"" +
"</DIV" +
"
'</div></div></div></div></div></div></div></div>'
);
- Eu dou-lhe a identificação entre recipientes de busca, ser capaz de mostrar / esconder todos os resultados do contentor de pesquisa
- a maioria dos div's, incluindo contentor são necessários para um estilo compatível com o nosso tema atual - use conforme necessário
- sc-query é usado para espelhar a pesquisa que o usuário digitou atualmente, para mostrar que o sistema atualiza os resultados dinamicamente em seu nome (há código para fazer isso - ler em)
- aj-right-container contém filtros para chegar às "facetas" da busca. O usuário pode escolher uma ou várias marcas para mostrar, categorias de produtos, e nós incluímos um filtro de preço
- aj-clear-all conterá um link para uma facetadura clara - para retornar todos os resultados que correspondam à consulta do usuário
- aj-left-container contém os resultados da pesquisa. aj-stats conterão estatísticas sobre a pesquisa (resultados da pesquisa + tempo gasto na pesquisa), aj-search-results conterão os resultados e aj-search-pagination conterá a paginação
O modelo de sucesso
mais uma vez, isto provavelmente iria directamente para a sua página em vez de ser injectado via Javascript.
$(".main-content").before(''+
'+
' <div class="aj-hit">'+
' <div class="aj-hit-image">'+
' <a href="/pt/{{product_link}}/"><img src="{{image}}" alt="{{título}}"></a>'+
' </div>'+
' <div class="aj-hit-content">'+
' <div class="aj-hit-title"><a href="/pt/{{product_link}}/">{{{{_highlightResultado.title.value}}}{{{variant_title}}}</a></div>'+
'<p class="aj-hit-description">{{{{_highlightResult.body_html_safe.value}}}} <a href="/pt/{{product_link}}/">" mehr</a></p>'+
'<p class="aj-hit-sku"><a href="/pt/{{product_link}}/">{{sku}}</a></p>'+
' <div class="aj-hit-bottominfos">' +
' <div class="aj-hit-price">{{preço}} €</div>' +
' <div class="aj-hit-stock">auf Lager </div>'+
' <div class="aj-hit-link"><a href="/pt/{{product_link}}/">zur Produktseite</a></div>'+
' </div>'+
'</div>'+
">" +
'</div>'+
'+
'');Este modelo é inserido como "script". Esta é a forma recomendada pelos documentos da Algolia.
É usado para renderizar um resultado de pesquisa, ou hit.
Aqui, dentro aj-hit Já o fizemos:
- aj-hit-imagee {{{imagem}}} como espaços reservados para inserir os valores correctos mais tarde
- aj-hit-titleusando {{{{_highlightResult.title.value}}}} - Também ligo no {{{{variant_title}}} para fornecer um título completo para variações
- aj-hit-descriptionpara tornar a descrição do produto - {{{{_highlightResult.body_html_safe.value}}}}
- aj-hit-price para o {{{preço}} - não se esqueça de adicionar a sua moeda (ou adicioná-la modificando a variável passada para o modelo)
- aj-hit-stockpara mostrar o quanto {{{inventory_quantity}} temos
- aj-hit-link - finalmente, um link para a página do produto. {{link_do_produto}}
Tudo isto é bem (IMHO) com o meu ficheiro CSS. Styling está fora do escopo deste post do blog, consulte buyzero.de para alguma inspiração e depois codifique a sua.
Mais sobre {{{_highlightResultado.title.value}}}
Variáveis exibidas usando três colchetes não serão escapadas por Algolia para HTML. Isto é usado aqui, para permitir o destaque.
Algolia irá automaticamente colocar Tags para você ao redor das partes do título, etc. que foram combinadas no _aluzResultado variável. O usuário pode usar a na saída, para mostrar ao usuário porque o resultado da pesquisa é considerado relevante para sua pesquisa.
Mais tarde mostrar-lhe-ei como modificar os valores que são passados para o template, pois não vai querer renderizar todo o corpo de descrição do seu produto, por exemplo.
aj_setup_search
var pb = aj_setup_search();
Para lidar com a busca mais tarde, retornamos uma variável da função de configuração (chamada var point_both dentro da função setup_search. pb é a abreviatura).
var search = instantsearch({ appId: 'YOUR_APP_ID', apiKey: 'YOUR_API_KEY', // search only API key, no ADMIN key indexName: 'shopify_buyzero_de_products', urlSync: true, searchParameters: { hitsPerPage: 10 }, searchFunction(my_helper){ point_both.ihelper = my_helper; //search.helper.setQuery('Pi 3'); //sic! //my_helper.search(); //sic! if(my_helper.state.query === '') { return; } my_helper.search(); } //end searchFunction });//end instantsearch setupAqui nós configuramos a pesquisa (como mencionado anteriormente, a pesquisa instantânea já está incluída e disponível na página através de outro arquivo .js).
Tens de passar:
- seu appId
- apiKey
- indexName
vais receber isto do teu backend Algolia. Lá você também pode navegar por suas estruturas de dados, e ver quais parâmetros você pode usar para facetar, por exemplo.
A parte realmente importante é a função searchFunction (my_helper).
O helper permite-lhe conduzir a pesquisa através do seu próprio script, em vez de o activar a partir de um widget de caixa de pesquisa que é configurado com o Algolia's instantsearch.
É importante criar uma referência a este ajudante, nesta função em particular.
point_both.ihelper = my_helper;
Aceder mais tarde ao helper a partir da variável de pesquisa irá não trabalho.
Na verdade, você precisa de ambos. Vês este código de exemplo, eu comentei?
//search.helper.setQuery('Pi 3'); //sic!
//my_helper.search(); //sic!
sic é a palavra latina para "assim". Ou seja, tem de ser acessada de duas maneiras diferentes para definir a consulta e depois executar a pesquisa.
Além disso, você precisa para adicionar o meu_helper.search() aqui. Isto vai - como eu me lembro - permitir que seus widgets atualizem a pesquisa corretamente... se você achar que seus resultados não estão atualizados, verifique se você os tem aí!
Depois de adicionarmos os widgets - que discutiremos a seguir - terminamos a configuração da pesquisa com o seguinte código:
search.start();
point_both.search = procurar;
ponto de retorno_ambos;Aqui também adicionamos uma referência ao próprio objeto de busca, e o retornamos para a função aj_setup.
Note que o point_both tem agora acesso ao objecto "search", e ao objecto de ajuda especial "ihelper" que obtivemos dentro da função searchFunction.
Adicionando o primeiro widget
vamos adicionar o resultado como o primeiro widget:
search.addWidget(
instantsearch.widgets.hits({
contentor: '#aj - resultados de pesquisa',
modelos: {
item: document.getElementById('aj-hit-template').innerHTML,
vazio: "Es konnten leider keine Resultate für die Suchanfrage >"{{{query}}" gefunden werden."
},
transformData: {
item: função (meu_resultado) {
//console.log(my_result);
//console.log(my_result._highlightResult.body_html_safe.value);
if (my_result["variant_title"] == 'Título por defeito'){
my_result["variant_title"] = ";
}
além disso
{
my_result["variant_title"] = ' :: ' + my_result["variant_title"];
}
//my_result["body_html_safe"] = my_result["body_html_safe"].substring(0,175) + '...';
// NÃO queremos multilinha, queremos igualar o final REAL da corda. /m coincidiria no final da linha...
var pattern_a = /(.*?)(]*)?$/i;
var pattern_b = /[^<]+$/i;
// fazer o primeiro grupo combinado - o que exclui o segundo jogo.
var body_string = my_result._highlightResult.body_html_safe.value.substring(0,175).replace(pattern_a, "$1″);
if (pattern_b.test(body_string)){
body_string = body_string + ""
}
//pesquisa para pi 3 b+
//identificação do produto https://buyzero.de/products/budget-kit-raspberry-pi-3-model-b?variant=698066665499
my_result._highlightResult.body_html_safe.value = body_string + '...';
my_result["product_link"] = "https://buyzero.de/products/” + my_result["handle"] + "?variant=" + my_result["id"];
devolver o meu_resultado;
}
}
})
);O container para colocar a saída é selecionado como '#aj-search-results', o template para renderizar os resultados é selecionado aqui: item: document.getElementById('aj-hit-template').innerHTML.
Eu assumo que eles colocaram isso em uma tag , porque o conteúdo não é renderizado como HTML pelo navegador.
Para o vazio, nós apenas passamos uma string como modelo.
Realmente simples até agora, certo?
A seguir usamos transformData para preparar uma versão resumida do corpo de texto do seu produto e outras variáveis passadas para o modelo de sucesso discutido anteriormente.
Porque introduzimos 's na saída da pesquisa - usando o destaque automático da Algolia - precisamos encurtar o texto de uma forma segura. Eu preparei minhas próprias expressões regulares para isso, no meu código de exemplo.
Se houver uma declaração incompleta começando com ), ela é cortada a partir da saída.
Se houver uma tag sem a correspondente tag para fechá-la, nós a adicionamos.
O link do produto é construído obtendo o cabo, e definindo a id como a variante.
Adicionando paginação
adicionar widgets adicionais é fácil:
// Adicione isto depois das outras chamadas search.addWidget()
search.addWidget(
instantsearch.widgets.pagination({
contentor: '#aj-paginação de pesquisa',
render: function(my_obj){
console.log("render");
console.log(my_obj);
},
getConfiguration: function(my_obj){
console.log("getConfiguration");
console.log(my_obj);
}
})
);
você não quer a saída do log do console... Eu estava usando isso para depurar, e aparentemente esqueci de tirá-lo. Desculpa. Eu sou humano.
Mais uma vez, o contentor de saída do widget está definido. #aj-paginação de pesquisa'.
Você realmente não precisa de mais nada para a paginação funcionar - monte o widget, e estilo - você vai ser bom.
Faceting
Com o faceting o seu utilizador pode refinar a sua pesquisa:
// Faceting
search.addWidget(
instantsearch.widgets.refinementList({
contentor: '#aj-facet-brand',
atributeName: "fornecedor",
operador: "ou",
limite: 5,
MostrarMais: verdade,
cssClasses: {
cabeçalho: 'aj-refine-header',
contar: 'aj-refine-count'.
},
modelos: {
cabeçalho: 'Marcar / Marca'.
}
})
);
- você precisa olhar os possíveis atributosNomes no seu backend Algolia - ele lhe mostrará as facetas disponíveis para os seus dados (veja a captura de tela abaixo).
- O limite de 5 não se refere aos resultados da sua pesquisa, mas sim ao limite de entradas que são mostradas pela Algolia para o seu refinamentoLista
- Os refinamentos disponíveis serão automaticamente actualizados se os outros parâmetros de pesquisa forem alterados (por exemplo, se não houver correspondência para uma marca específica, esta marca não será mostrada)
- showMore: mostrará um show mais link na parte inferior do widget
- contar: 'aj-refine-count' - pode dar um pouco de estilo aos resultados da sua pesquisa. Provavelmente mais do que eu usei aqui - consultar a documentação oficial
Dispositivo Clear Facets
search.addWidget(
instantsearch.widgets.clearAll({
recipiente: '#aj-clear-all',
modelos: {
ligação: Filtro zurücksetzen / Resetzen
},
autoHideContainer: falso,
clearsQuery: true,
})
);usar isto para permitir ao cliente limpar a facetada (ou seja, serão mostrados todos os resultados que correspondem à sua consulta novamente).
Não há necessidade de configurar além disto.
Eu não vou falar sobre os outros widgets - dê uma olhada no meu código se você estiver interessado.
Ligação à caixa de pesquisa
Nós não estamos usando o widget de busca da Algolia, mas nos ligamos a um evento chave acima na entrada do nosso formulário de busca, como este:
var pb = aj_setup_search();
//#search_query é a entrada que queremos
$("#search_query").keyup(function(search) {
updateSearch(pb);
});
}(discutimos aj_setup_search agora mesmo, foi adicionado aqui para mostrar-lhe de onde vem a pb).
Fazemos isso para que possamos fazer um processamento adicional quando o evento keyup é acionado - escondendo o conteúdo que estávamos exibindo anteriormente na página, e adicionando os resultados da pesquisa, etc.
atualização da funçãoSearch(pb){
var my_query = $("#search_query").val();
//$(".main-content").html(my_query);
if (my_query) {
$(".main-content").hide();
$("#megamenu-header-menu2").hide();
$("#ajr_na").show();
$("#sc-query").html(my_query);
$("#aj-arch-container").show();
pb.search.helper.setQuery(my_query);
//console.log(search_handle.helper.state);
pb.ihelper.search();
}
senão (
$("#aj-arch-container").hide();
$(".main-content").show();
$("#ajr_na").hide();
$("#megamenu-header-menu2").show();
}}
Nós usamos jQuery para obter o valor do campo de pesquisa. Se não estiver vazio, ocultamos o conteúdo principal que estávamos exibindo antes, e mostramos o recipiente de pesquisa.
Nós definimos sc-query para mostrar ao utilizador que estamos a responder à sua entrada: $("#sc-query").html(my_query);
Finalmente, as partes importantes são estas aqui:
pb.search.helper.setQuery(my_query);
pb.ihelper.search();
como você vê, precisamos usar dois ajudantes diferentes para definir a consulta e executar a pesquisa real. Sim, é assim que tem de ser feito - felizmente encontrei alguém a queixar-se deste comportamento.
Finalmente, se a cadeia de busca estiver vazia (o usuário pressionou Escape, ou apagou, ou nós apagamos, ou o que quer que seja...) nós escondemos a busca, e mostramos o conteúdo principal.
Obrigado por ler
Obrigado pela vossa atenção, espero que isto ajude alguém que queira implementar o instantsearch.js sem usar o widget de pesquisa da Algolia.
Referências
Tampermonkey
Algolia
- Documentação de widgets Algolia Instantsearch
- https://community.algolia.com/shopify/instant_search.html
- https://www.algolia.com/doc/tutorials/search-ui/instant-search/build-an-instant-search-results-page/instantsearchjs/
- https://www.algolia.com/doc/guides/searching/highlighting-snippeting
- https://www.algolia.com/doc/guides/search-ui/building-a-search-ui/
- https://community.algolia.com/instantsearch.js/v2/widgets/hits.html#struct-HitsTransforms
- https://stackoverflow.com/questions/42672838/algolia-instantsearch-add-a-callback-after-results-are-displayed
- https://community.algolia.com/algoliasearch-helper-js/gettingstarted.html
- https://github.com/algolia/instantsearch.js/issues/1924
- https://jsfiddle.net/bobylito/bsjdch4m/1/
- https://stackoverflow.com/questions/49638646/algolia-instantsearch-with-multiple-indices-and-multiple-pagination-widgets/49796164?noredirect=1#comment86826994_49796164
- https://github.com/algolia/instantsearch.js/issues/2887
Bónus
- https://discourse.algolia.com/t/how-to-create-facet-widget-from-shopify-metafield/1710
- https://github.com/algolia/awesome-algolia