Skip to content

Commit 850d467

Browse files
ZoeLeBlancmdlincolnspapastamkoujenniferisasirivaquiroga
authored
full-text search using Lunr.js (#1726)
* maybe solved searching?? * Added comments for search * attempt at a lunr search * removed wrap terms func * fixed lunr ref issue * updated search for multilingual logic * trying to fix enter bug * trying list.js update function * fixed earlier bug and got search working with filter logic * fixed search bugs and got it working with filter logic * fixed search bugs and got it working with filter logic * added search enable button and more comments to code * fixed most of the bugs in full text search * added in support for multiple language stemmers * create snippet templates for search terms * updated search input to work with snippets * trying to comment and clean up code * FR snippets * cleaned up code * ordered lessons by search score * removed abstract styling from style.css * Update snippets.yml translated to ES search snippets * added search info and search indicator * switched icon to question mark * fixed search info for firefox and added loader * cleaning up code and adding comments * cleaning code and changing url to slug * reverted back to url and added more comments * removed all console.logs and added snippet * ES translation of search documentation snippet * FR translation search documentation snippet * use md shortcut for URLs * moved js files to vendor and only loaded file for language * adding the vendor files again * readding js vendor and updatinggitignore Co-authored-by: Matthew Lincoln <[email protected]> Co-authored-by: spapastamkou <[email protected]> Co-authored-by: Jennifer Isasi <[email protected]> Co-authored-by: Riva Quiroga <[email protected]> Co-authored-by: Matthew Lincoln <[email protected]>
1 parent 8da3df8 commit 850d467

File tree

9 files changed

+2076
-114
lines changed

9 files changed

+2076
-114
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ _site/*
33
.DS_Store
44
tmp/
55

6-
vendor/
6+
/vendor
77
.bundle/
88
.vscode/

_data/snippets.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,40 @@ filtering-results:
352352
es: Filtradas por
353353
fr: Filtrage par
354354
pt:
355+
loading-search:
356+
en: LOADING SEARCH...
357+
es: CARGANDO LA BÚSQUEDA...
358+
fr: RECHERCHE EN COURS...
359+
pt:
360+
search-lessons:
361+
en: SEARCH LESSONS
362+
es: BUSCAR LECCIONES
363+
fr: RECHERCHER LES LEÇONS
364+
pt:
365+
start-searching:
366+
en: START SEARCHING
367+
es: INICIAR BÚSQUEDA
368+
fr: DÉMARRER LA RECHERCHE
369+
pt:
370+
type-search-terms:
371+
en: TYPE SEARCH TERMS...
372+
es: ESCRIBE LOS TÉRMINOS DE BÚSQUEDA...
373+
fr: ENTRER UN OU PLUSIEURS TERMES DE RECHERCHE...
374+
pt:
375+
search-info:
376+
en: |
377+
To search for relevant terms, enter them into the search bar and either press the enter key or the search button. All searches are case insensitive. If multiple terms are entered, results will include lessons that have all terms, as well as lessons that contain *either term*. Results with more of the terms will be scored higher in the list.
378+
379+
To only return results with multiple terms, add the `+` symbol before the term. For example, `+Twitter +Network` will return lessons that contain *both* "twitter" and "network". To only return results that *do not* contain a term use the `-` symbol. For example, `-Twitter +Network` will return lessons that contain "network" but not "twitter". For more detailed information, visit this guide on searching: <https://lunrjs.com/guides/searching.html>
380+
es: |
381+
Para buscar términos relevantes, escríbelos en la barra de búsqueda y aprieta la tecla "enter" o haz clic en el botón "buscar lecciones". Las búsquedas no distinguen mayúsculas y minúsculas. Si se ingresan múltiples términos, los resultados incluirán tanto lecciones que los contengan todos, como lecciones que contengan *solo alguno*. Los resultados que incluyan más de un término aparecerán primero en la lista.
382+
383+
Para obtener solo resultados con múltiples términos, agrega el símbolo `+` antes de cada uno. Por ejemplo, `+Twitter +Red` devolverá lecciones que contienen *tanto* "twitter" como "red". Para obtener solo resultados que *no* contengan cierto término, utiliza el símbolo `-`. Por ejemplo, `-Twitter +Red` devolverá lecciones que contienen "red" pero no "twitter". Para información más detallada, puedes revisar la guía sobre búsquedas (en inglés): <https://lunrjs.com/guides/searching.html>
384+
fr: |
385+
Pour obtenir des résultats en utilisant plusieurs termes de recherche, faites précéder chaque terme du symbole `+`. Par exemple, en insérant `+Twitter +réseau`, vous obtiendrez les tutoriels qui contiennent tous les deux termes. Pour *exclure* un terme des résultats obtenus, vous pouvez utiliser le symbole `-`. Par exemple, en insérant `-Twitter +réseau`, vous obtiendrez les tutoriels qui contiennent le terme "réseau", mais pas "Twitter". Pour en savoir plus sur les modalités de recherche, merci de consulter ce guide <https://lunrjs.com/guides/searching.html>
386+
387+
pt: |
388+
355389
356390
# lesson headers
357391
editor:

_includes/lesson-index.html

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,61 @@
11
{% comment %}
2-
Core code for generating filterable lesson indexes on lessons.md and es/lecciones.md. This will repeatedly call lesson_describe.html in which individual lessons have their metadata formatted for display.
2+
Core code for generating filterable lesson indexes on lessons.md and es/lecciones.md. This will repeatedly call
3+
lesson_describe.html in which individual lessons have their metadata formatted for display.
34
{% endcomment %}
4-
5+
<!-- loading graph if search in URI -->
6+
<div id="pre-loader">
7+
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid"
8+
class="lds-ripple" style="background:0 0">
9+
<circle cx="50" cy="50" r="4.719" fill="none" stroke="#1d3f72" stroke-width="2">
10+
<animate attributeName="r" calcMode="spline" values="0;40" keyTimes="0;1" dur="3" keySplines="0 0.2 0.8 1" begin="-1.5s" repeatCount="indefinite" />
11+
<animate attributeName="opacity" calcMode="spline" values="1;0" keyTimes="0;1" dur="3" keySplines="0.2 0 0.8 1" begin="-1.5s" repeatCount="indefinite" />
12+
</circle>
13+
<circle cx="50" cy="50" r="27.591" fill="none" stroke="#5699d2" stroke-width="2">
14+
<animate attributeName="r" calcMode="spline" values="0;40" keyTimes="0;1" dur="3" keySplines="0 0.2 0.8 1" begin="0s" repeatCount="indefinite" />
15+
<animate attributeName="opacity" calcMode="spline" values="1;0" keyTimes="0;1" dur="3" keySplines="0.2 0 0.8 1" begin="0s" repeatCount="indefinite" />
16+
</circle>
17+
</svg>
18+
</div>
519
<ul class="filter activities">
620
{% for activity in site.data.activities %}
721
{% assign atype = activity.type %}
8-
<li id="filter-{{ atype }}" class="filter">{{ activity[page.lang]}} ({{ alllessons | where:"activity",atype | size }})</li>
22+
<li id="filter-{{ atype }}" class="filter">{{ activity[page.lang]}} ({{ alllessons | where:"activity",atype | size }})
23+
</li>
924
{% endfor %}
1025
</ul>
1126

1227
<ul class="filter topics">
13-
{% for topic in site.data.topics %}
14-
{% assign type = topic.type %}
15-
{% assign count = alllessons | where:"topics",type | size }} %}
28+
{% for topic in site.data.topics %}
29+
{% assign type = topic.type %}
30+
{% assign count = alllessons | where:"topics",type | size }} %}
1631
{% if count > 0 %}
1732
<li id="filter-{{ topic.type }}" class="filter">{{ topic.displayname[page.lang] }} ({{count}})</li>
1833
{% endif %}
19-
{% endfor %}
34+
{% endfor %}
2035
</ul>
2136

22-
<div id="filter-none">{{site.data.snippets.reset-button[page.lang]}} ({{ alllessons | size }})</div>
37+
<div id="filter-none">{{site.data.snippets.reset-button[page.lang]}} ({{ alllessons | size }})</div>
2338

2439
<!--
2540
this div ('lesson-list', referenced in lessonfilter.js) needs to contain the sort button/elements AND the actual list for the sort buttons to work
2641
-->
42+
<div id="search-div" style="text-align: center; margin-bottom: 1rem; display: none;">
43+
<input id="loading-search" class="search-input" type="text"
44+
placeholder="{{ site.data.snippets.loading-search[page.lang] }}" style="background-color: #efefef" disabled>
45+
<input id="search" class="search-input" type="text" style="display: none;" placeholder="{{ site.data.snippets.type-search-terms[page.lang] }}">
46+
<button id="search-button" disabled>{{ site.data.snippets.search-lessons[page.lang] }}</button>
47+
<i id="search-info-button" class="fas fa-question-circle"></i>
48+
<div id="search-info">
49+
{{ site.data.snippets.search-info[page.lang] | markdownify }}
50+
</div>
51+
</div>
52+
<div id="enable-search-div" style="text-align: center; margin-bottom: 1rem;">
53+
<button id="enable-search-button" style="width: 100%;">{{ site.data.snippets.start-searching[page.lang] }}</button>
54+
</div>
55+
2756
<div id="lesson-list">
2857

29-
<!--
58+
<!--
3059
List.js uses button classes of asc and desc to control sorting functionality. It also toggles those classes off and on with click events.
3160
To not interfere with that, we use my-asc and my-desc to control the arrows, since our desired behavior is different from what list.js does.
3261
More concretely: to sort asc, the button class needs to contain asc, but we use the arrow ON THE BUTTON to indicate what WILL happen,
@@ -35,18 +64,22 @@
3564
-->
3665
<ul class="sort-by">
3766
<li id="sort-by-date" class="sort" data-sort="date">{{site.data.snippets.sort-by-date[page.lang]}}</li>
38-
<li id="sort-by-difficulty" class="sort" data-sort="difficulty">{{site.data.snippets.sort-by-difficulty[page.lang]}}</li>
67+
<li id="sort-by-difficulty" class="sort" data-sort="difficulty">{{site.data.snippets.sort-by-difficulty[page.lang]}}
68+
</li>
3969
</ul>
4070

4171
<input id="date-sort-text" type="hidden" label="{{site.data.snippets.date[page.lang]}}">
4272
<input id="difficulty-sort-text" type="hidden" label="{{site.data.snippets.difficulty[page.lang]}}">
4373

44-
<h2 class="results-title">{{ site.data.snippets.filtering-results[page.lang] }}: <span id="results-value">{{ site.data.snippets.all-lessons[page.lang] }} </span> <span id="current-sort" class="sort-desc">{{site.data.snippets.date[page.lang]}}</span></h2>
74+
75+
<h2 class="results-title">{{ site.data.snippets.filtering-results[page.lang] }}: <span
76+
id="results-value">{{ site.data.snippets.all-lessons[page.lang] }} </span> <span id="current-sort"
77+
class="sort-desc">{{site.data.snippets.date[page.lang]}}</span></h2>
4578

4679
<ul class="list">
4780
{% for lesson in alllessons %}
4881
{% capture author_string %} {% include author.html %} {% endcapture %}
49-
<li>{% include lesson_describe.html authors=author_string %}</li>
82+
<li>{% include lesson_describe.html authors=author_string %}</li>
5083
{% endfor %}
5184
</ul>
5285

@@ -56,10 +89,15 @@ <h2 class="results-title">{{ site.data.snippets.filtering-results[page.lang] }}:
5689
<script src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
5790
<script src='//cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js'></script>
5891
<script src="{{ site.baseurl }}/js/URI.min.js"></script>
92+
<script src="https://unpkg.com/lunr/lunr.js"></script>
93+
<script src="{{ site.baseurl }}/js/vendor/lunr.stemmer.support.js"></script>
94+
{% if page.lang != "en" %}
95+
<script src="{{ site.baseurl }}/js/vendor/lunr.{{page.lang}}.js"></script>
96+
{% endif %}
5997
<script src="{{ site.baseurl }}/js/lessonfilter.js"></script>
6098

6199
<script>
62-
$(function() {
100+
$(function () {
63101
wireButtons();
64102
});
65103
</script>

_includes/lesson_describe.html

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
{% endcomment %}
1010

1111
<div class="lesson-description clearfix">
12-
1312
{% if lesson.original %}
1413
{% assign canonical_slug = lesson.original %}
1514
{% else %}
@@ -23,7 +22,9 @@
2322
<h3 class="above-title">{{ include.authors }}</h3>
2423
<a href="{{ lesson.url }}"><h2 class="title">{{ lesson.title }}</h2></a>
2524

26-
<p class="abstract">{{ lesson.abstract | markdownify }}</p>
25+
<p class="abstract">
26+
{{ lesson.abstract | markdownify | remove: '<p>' | remove: '</p>'}}
27+
</p>
2728

2829
{% comment %}
2930
Activity and topic are hidden via CSS as a hack to let JS sorting by activity and topic work. Note that the date sort is based on translation date first, falling back to publication date.
@@ -32,5 +33,13 @@ <h3 class="above-title">{{ include.authors }}</h3>
3233
<span class="topics">{{ lesson.topics | join: ' '}}</span>
3334
<span class="date">{% if lesson.translation_date %}{{ lesson.translation_date }}{% else %}{{ lesson.date }}{% endif %}</span>
3435
<span class="difficulty">{{ lesson.difficulty }}</span>
36+
<span id="{{lesson.url}}-content" class="content"
37+
style="display: none;">{{ lesson.content | markdownify | strip_html }}</span>
38+
<span id="{{lesson.url}}-score" class="score"
39+
style="display: none;">0</span>
40+
<p id="{{lesson.url}}-search_results" class="search_results"
41+
style="display: none;"></p>
42+
43+
3544

3645
</div>

css/style.css

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,74 @@ Lessons Index
316316
background-color:#ededed;
317317
}
318318

319+
/*****************
320+
SEARCH
321+
*****************/
322+
323+
.search-input {
324+
width:55%;
325+
clear:both;
326+
margin-bottom:1rem;
327+
background-color:#fefefe;
328+
color:#666;
329+
border:1px solid #999;
330+
font: .9rem/1.1rem 'Open Sans',
331+
sans-serif;
332+
padding: .4rem .6rem;
333+
border-radius: 3px;
334+
display:inline-block;
335+
text-transform:uppercase;
336+
text-decoration: none;
337+
}
338+
339+
#search-button,
340+
#enable-search-button {
341+
background-color: #efefef;
342+
color: rgb(153, 143, 143);
343+
width: 35%;
344+
font: .9rem/1.1rem 'Open Sans',
345+
sans-serif;
346+
padding: .4rem .6rem;
347+
border: none;
348+
border-radius: 3px;
349+
display: inline-block;
350+
text-transform: uppercase;
351+
text-decoration: none;
352+
}
353+
354+
@media only screen and (max-width: 767px) {
355+
/* phones */
356+
#search-button,
357+
#enable-search-button {
358+
width: 80%;
359+
}
360+
}
361+
362+
363+
#search-info-button {
364+
padding: 0.5rem;
365+
color: rgb(153, 143, 143);
366+
}
367+
368+
#search-info {
369+
display: none;
370+
height:0px;
371+
background:#efefef;
372+
overflow:hidden;
373+
transition:0.5s;
374+
-webkit-transition:0.5s;
375+
width: 100%;
376+
text-align: left;
377+
box-sizing: border-box;
378+
}
379+
380+
#search-info.visible {
381+
display: block;
382+
height: fit-content;
383+
height: -moz-max-content;
384+
padding: 10px;
385+
margin-top: 10px;
386+
}
319387

320388
/*****************
321389
SORT BUTTONS
@@ -426,19 +494,27 @@ Lessons Index
426494
clear:none;
427495
}
428496

429-
p.abstract {
430-
font: .8rem/1.2rem 'Open Sans', sans-serif;
431-
margin:0;
432-
}
433-
434497
.list .date,
435498
.lesson-description .activity,
436499
.lesson-description .topics,
437500
.lesson-description .difficulty {
438501
display: none;
439502
}
440503

441-
504+
#pre-loader {
505+
visibility: hidden;
506+
display: flex;
507+
justify-content: center;
508+
align-items: center;
509+
height: 100vh;
510+
width: 100%;
511+
position: fixed;
512+
top: 0;
513+
left: 0;
514+
z-index: 9999;
515+
transition: opacity 0.3s linear;
516+
background: rgba(211, 211, 211, 0.8);
517+
}
442518
/* =============================================================================
443519
Top Navigation Bar
444520
========================================================================== */

0 commit comments

Comments
 (0)