Si vous constatez la perte de tickets, de commentaires ou de projets, veuillez consulter la page https://status.framasoft.org/incident/626.

Commit 045d7382 authored by wbar's avatar wbar

add a search engine based on lunrjs

parent 3722c323
......@@ -4,6 +4,9 @@ DefaultContentLanguage = "fr"
title = "BWog-notes"
paginate = 10
[outputs]
home = ["html","rss","json"]
[params]
section_on_frontpage = "posts"
description = "Bloc notes en ligne sur l'administration système Linux et autres sujets liés"
......
+++
title = "Recherche"
date = 2020-07-10T19:10:40+02:00
draft = false
+++
Pour rechercher du contenu, c'est par ici :
{{< recherche >}}
-----
C'est la seule page du site qui nécessite du javascript.
Toute la recherche se fait en local sur votre navigateur, rien n'est remonté vers le serveur (vous pouvez vérifier :p ).
La recherche ne fonctionne actuellement que sur les mots complets.
Ce n'est d'ailleurs pas garanti que ça trouve correctement ... je préviens juste au cas où.
[
{{- range $index, $page := (where .Site.RegularPages "Section" "in" .Site.Params.section_on_frontpage ) -}}
{{- if gt $index 0 -}} , {{- end -}}
{{- $entry := dict "uri" $page.RelPermalink "title" $page.Title -}}
{{- $entry = merge $entry (dict "content" ($page.Plain | htmlUnescape)) -}}
{{- $entry = merge $entry (dict "tags" $page.Params.tags) -}}
{{- $entry | jsonify -}}
{{- end -}}
]
<form id="search" class="search" role="search">
<input type="search" id="search-input" class="search-input" placeholder="recherche">
</form>
<div class="nombre-resultats"></div>
<ul class="liste-resultats"></ul>
<script src="/js/lunr-2.3.7.min.js"></script> <!-- lunr.js library -->
<script src="/js/lunr.stemmer.support.min.js"></script>
<script src="/js/lunr.fr.min.js"></script>
<script src="/js/recherche.js"></script>
......@@ -104,3 +104,21 @@ ul li a[href*='framapiaf.org']:before {content: url('/images/icons/masto.png');
#toc {font-size: 90%; background-color: #111; padding: 0.5em 0 0.5em 1.0em; }
#toc h2 {margin-top: 0px;}
.search {
display: flex;
justify-content: center;
min-width: 1em;
line-height: 1.5rem;
padding: 1.25em;
}
.search-input {
font-size:1.5rem;
background-color:#111;
color: #b3b3b3;
margin:0.5em;
padding:0.5em;
border: none;
width:70%;
}
This diff is collapsed.
This diff is collapsed.
!function(r,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(r.lunr)}(this,function(){return function(r){r.stemmerSupport={Among:function(r,t,i,s){if(this.toCharArray=function(r){for(var t=r.length,i=new Array(t),s=0;s<t;s++)i[s]=r.charCodeAt(s);return i},!r&&""!=r||!t&&0!=t||!i)throw"Bad Among initialisation: s:"+r+", substring_i: "+t+", result: "+i;this.s_size=r.length,this.s=this.toCharArray(r),this.substring_i=t,this.result=i,this.method=s},SnowballProgram:function(){var r;return{bra:0,ket:0,limit:0,cursor:0,limit_backward:0,setCurrent:function(t){r=t,this.cursor=0,this.limit=t.length,this.limit_backward=0,this.bra=this.cursor,this.ket=this.limit},getCurrent:function(){var t=r;return r=null,t},in_grouping:function(t,i,s){if(this.cursor<this.limit){var e=r.charCodeAt(this.cursor);if(e<=s&&e>=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor++,!0}return!1},in_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e<=s&&e>=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor--,!0}return!1},out_grouping:function(t,i,s){if(this.cursor<this.limit){var e=r.charCodeAt(this.cursor);if(e>s||e<i)return this.cursor++,!0;if(e-=i,!(t[e>>3]&1<<(7&e)))return this.cursor++,!0}return!1},out_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e>s||e<i)return this.cursor--,!0;if(e-=i,!(t[e>>3]&1<<(7&e)))return this.cursor--,!0}return!1},eq_s:function(t,i){if(this.limit-this.cursor<t)return!1;for(var s=0;s<t;s++)if(r.charCodeAt(this.cursor+s)!=i.charCodeAt(s))return!1;return this.cursor+=t,!0},eq_s_b:function(t,i){if(this.cursor-this.limit_backward<t)return!1;for(var s=0;s<t;s++)if(r.charCodeAt(this.cursor-t+s)!=i.charCodeAt(s))return!1;return this.cursor-=t,!0},find_among:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o<h?o:h,_=t[a],m=l;m<_.s_size;m++){if(n+l==u){f=-1;break}if(f=r.charCodeAt(n+l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n+_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n+_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},find_among_b:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit_backward,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o<h?o:h,_=t[a],m=_.s_size-1-l;m>=0;m--){if(n-l==u){f=-1;break}if(f=r.charCodeAt(n-1-l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n-_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n-_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},replace_s:function(t,i,s){var e=s.length-(i-t),n=r.substring(0,t),u=r.substring(i);return r=n+s+u,this.limit+=e,this.cursor>=i?this.cursor+=e:this.cursor>t&&(this.cursor=t),e},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>r.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),r.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}});
\ No newline at end of file
// merci beaucoup à https://palant.info/2020/06/04/the-easier-way-to-use-lunr-search-with-hugo/
// et https://lord.re/posts/206-recherche-pour-un-blog-statique/
window.addEventListener("DOMContentLoaded", function(event)
{
var index = null;
var lookup = null;
var queuedTerm = null;
var form = document.getElementById("search");
var input = document.getElementById("search-input");
form.addEventListener("keyup", function(event)
{
event.preventDefault();
var term = input.value.trim();
if (!term)
return;
startSearch(term);
}, false);
form.addEventListener("submit", function(event)
{
event.preventDefault();
var term = input.value.trim();
if (!term)
return;
startSearch(term);
}, false);
function startSearch(term)
{
if (index)
{
// Index already present, search directly.
search(term);
}
else if (queuedTerm)
{
// Index is being loaded, replace the term we want to search for.
queuedTerm = term;
}
else
{
// Start loading index, perform the search when done.
queuedTerm = term;
initIndex();
}
}
function searchDone()
{
queuedTerm = null;
}
function initIndex()
{
var request = new XMLHttpRequest();
request.open("GET", "/index.json");
request.responseType = "json";
request.addEventListener("load", function(event)
{
lookup = {};
index = lunr(function()
{
// Uncomment the following line and replace de by the right language
// code to use a lunr language pack.
this.use(lunr.fr);
this.ref("uri");
// If you added more searchable fields to the search index, list them here.
this.field("title");
this.field("content");
this.field("tags");
for (var doc of request.response)
{
this.add(doc);
lookup[doc.uri] = doc;
}
});
// Search index is ready, perform the search now
search(queuedTerm);
}, false);
request.addEventListener("error", searchDone, false);
request.send(null);
}
function search(term)
{
var results = index.search(term);
// The element where search results should be displayed, adjust as needed.
var ul = document.querySelector(".liste-resultats");
ul.innerHTML = "";
var nb_res = document.querySelector(".nombre-resultats")
var title = document.createElement("p");
if (results.length == 0)
title.textContent = `Aucun résultat pour “${term}”`;
else if (results.length == 1)
title.textContent = `1 résultat pour “${term}”`;
else
title.textContent = `${results.length} résultats pour “${term}”`;
nb_res.innerHTML = title.textContent;
var template = document.getElementById("search-result");
for (var result of results)
{
var doc = lookup[result.ref];
var li = document.createElement("li");
let elemlink = document.createElement('a');
elemlink.innerHTML = doc.title;
elemlink.setAttribute('href', doc.uri);
li.appendChild(elemlink);
ul.appendChild(li);
}
//title.scrollIntoView(true);
searchDone();
}
}, false);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment