Skip to content

Commit

Permalink
offline search for mirror drives (#1175)
Browse files Browse the repository at this point in the history
* add fuse and proof of concept of course search

* fix styling on search page and add search button

* display search icon with proper link on pages that aren't the search page

* make clicking the logo go to the index

* organize and comment code

* only pad the search results area on desktop

* use basic string templating instead of custom web component

* lower minimum match characters to 3

* add placeholders for empty search results

* search button of type button and remove preventdefault
  • Loading branch information
gumaerc authored Jun 23, 2023
1 parent 63b5b67 commit 3cde05d
Show file tree
Hide file tree
Showing 11 changed files with 166 additions and 14 deletions.
6 changes: 3 additions & 3 deletions base-theme/layouts/partials/header.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!-- navbar for mobile screens -->
{{ $siteRootUrl := partial "site_root_url.html" "/" }}
{{ $homeUrl := partial "home_url.html" }}
{{ $giveNowUrl := "https://giving.mit.edu/give/to/ocw/?utm_source=ocw&utm_medium=homepage_banner&utm_campaign=nextgen_home" }}
{{ $aboutUrl := partial "site_root_url.html" "/about" }}
{{ $zenDeskUrl := "https://mitocw.zendesk.com/hc/en-us" }}
Expand All @@ -18,7 +18,7 @@
<i class="material-icons display-4 text-white align-bottom">menu</i>
</button>
<div class="mx-auto">
<a href="{{ $siteRootUrl }}">
<a href="{{ $homeUrl }}">
<img width="250" src="/static_shared/images/ocw_logo_white_v2.svg" alt="MIT OpenCourseWare"/>
</a>
</div>
Expand Down Expand Up @@ -47,7 +47,7 @@
<div class="contents">
<div class="left">
<div class="ocw-logo mr-6">
<a href="{{ $siteRootUrl }}">
<a href="{{ $homeUrl }}">
<img src="/static_shared/images/ocw_logo_white_v2.svg" alt="MIT OpenCourseWare" />
</a>
</div>
Expand Down
2 changes: 2 additions & 0 deletions base-theme/layouts/partials/home_url.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{{ $siteRootUrl := partial "site_root_url.html" "/" }}
{{ return $siteRootUrl }}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
"expose-loader": "^4.0.0",
"fancy-log": "^1.3.2",
"file-loader": "^5.0.2",
"fuse.js": "^6.5.3",
"fuse.js": "^6.6.2",
"gulp": "^4.0.2",
"history": "^5.3.0",
"hugo-bin-extended": "~0.112.7",
Expand Down
3 changes: 3 additions & 0 deletions www-offline/assets/www-offline.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import "./css/www-offline.scss"
import Fuse from "fuse.js"
import Popper from "popper.js"

export interface OCWWindow extends Window {
$: JQueryStatic
jQuery: JQueryStatic
Popper: typeof Popper
Fuse: typeof Fuse
}
declare let window: OCWWindow

window.jQuery = $
window.$ = $
window.Popper = Popper
window.Fuse = Fuse
5 changes: 5 additions & 0 deletions www-offline/content/search/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
title: Search
type: search
renderSearchIcon: false
---
7 changes: 3 additions & 4 deletions www-offline/layouts/home.html
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
{{ define "main" }}
<div>
{{ block "header" . }}
{{ $renderSearchIcon := false }}
{{ partial "header" . $renderSearchIcon }}
{{ partial "header" . }}
{{ end }}
</div>
<div class="search-wrapper">
<div class="search-page row justify-content-center">
<div class="search-results-area col-9 py-4">
<div class="search-results-area col-12 py-4">
{{ $websites := where site.Pages ".Params.content_type" "==" "website" }}
{{ $sortedWebsites := partial "sort_websites_by_course_number.html" $websites }}
{{ $paginator := .Paginate $sortedWebsites }}
<section class="m-auto">
<section class="m-auto px-8">
{{ range $paginator.Pages }}
{{ $pathToRoot := strings.TrimSuffix "/" (partial "path_to_root.html" $paginator.URL) }}
{{ $urlPath := strings.TrimPrefix "/" .Params.url_path }}
Expand Down
8 changes: 8 additions & 0 deletions www-offline/layouts/partials/extraheader.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{{ define "extraheader" }}
{{ $renderSearchIcon := index .Params "renderSearchIcon" | default true}}
{{ if $renderSearchIcon}}
<a class="nav-link search-icon pr-6" href="/search.html">
<i class="material-icons">search</i>
</a>
{{end}}
{{ end }}
1 change: 1 addition & 0 deletions www-offline/layouts/partials/home_url.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ return "/index.html" }}
2 changes: 1 addition & 1 deletion www-offline/layouts/partials/include_css.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
{{ $urls := .urls }}
{{ range $url := $urls }}
{{ with $url }}
<link href="{{ printf "%s/%s" (strings.TrimSuffix "/" $context.Permalink) (strings.TrimPrefix "/" $url) }}" rel="stylesheet">
<link href="{{ printf "%s/%s" (strings.TrimSuffix "/" (path.Dir $context.Permalink)) (strings.TrimPrefix "/" $url) }}" rel="stylesheet">
{{ end }}
{{ end }}
134 changes: 134 additions & 0 deletions www-offline/layouts/search/section.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
{{ define "main" }}
{{ $pathToRoot := strings.TrimSuffix "/" (partial "path_to_root.html" .Permalink) }}
{{ $websites := where site.Pages ".Params.content_type" "==" "website" }}
{{ block "header" . }}
{{ partial "header" . }}
{{ end }}
<div class="search-wrapper">
<div class="search-page row justify-content-center">
<div class="search-results-area col-12 py-4">
<div class="container-fluid">
<main>
<div class="container-fluid p-0">
<div class="row m-0">
<div id="search-page" class="w-100">
<div class="container">
<div class="search-box py-sm-5 py-md-7 py-lg-5 row">
<div class="col-lg-3"></div>
<div class="col-lg-6 search-box-inner d-flex flex-column align-items-center mb-2 mb-sm-5 mb-md-4">
<h1>Explore OpenCourseWare</h1>
<div class="w-100 d-flex flex-column align-items-center search-input-wrapper mt-5">
<div class="w-100">
<form role="search" class="search-box d-flex flex-direction-row">
<input
id="search-input"
class="w-100 pl-2"
type="text"
aria-label="Search"
placeholder="Search OpenCourseWare"
/>
<button id="search-button" type="button" class="py-2 px-3">Search</button>
</form>
</div>
</div>
</div>
<div class="col-lg-3"></div>
</div>
</div>
<section id="search-results" class="m-auto px-lg-8">
<h3 class="col-3 text-center m-auto">Start typing to search</h3>
</section>
</div>
</div>
</div>
</main>
</div>
</div>
</div>
</div>
<script>
window.onload = function() {
if (window.Fuse) {
// an array of known websites generated at build time
const websites = [
{{ $websites := where site.Pages ".Params.content_type" "==" "website" }}
{{ range $websites }}
{{ $urlPath := strings.TrimPrefix "/" .Params.url_path }}
{{ $url := printf "%s/%s/index.html" $pathToRoot $urlPath }}
{{ $delimiter := ", " }}
{
"title": "{{- .Title -}}",
"primary_course_number": "{{- .Params.primary_course_number -}}",
"url": "{{- $url -}}",
{{ if .Params.level }}
"level": "{{- delimit .Params.level $delimiter -}}"
{{ else }}
"level": ""
{{ end }}
},
{{ end }}
]
// initialize Fuse and bind event listeners
const Fuse = window.Fuse
const searchOptions = {
shouldSort: true,
threshold: 0.4,
location: 0,
distance: 100,
matchAllTokens: true,
includeScore: true,
maxPatternLength: 32,
minMatchCharLength: 3,
keys: ["title", "primary_course_number"]
}
const fuse = new Fuse(websites, searchOptions)
const searchInput = document.getElementById("search-input")
const searchButton = document.getElementById("search-button")
const performSearch = searchString => {
const searchResults = fuse.search(searchString)
if (searchResults.length > 0) {
const searchResultComponents = searchResults.map(searchResult => {
return `
<article>
<div class="card learning-resource-card compact-view">
<div class="card-contents">
<div class="lr-info search-result">
<div class="col-2 course-num">
${searchResult.item["primary_course_number"]}
</div>
<div class="course-title">
<a class="course-link" href="${searchResult.item["url"]}">${searchResult.item["title"]}</a>
</div>
<div class="col-2 resource-level">
${searchResult.item["level"]}
</div>
</div>
</div>
</div>
</article>
`
})
const searchResultsSection = document.getElementById("search-results")
searchResultsSection.innerHTML = searchResultComponents.join("")
}
else {
searchResultsSection.innerHTML = `<h3 class="col-3 text-center m-auto">No results found</h3>`
}
}
const onInput = e => {
if (e.target.value) {
const searchString = e.target.value
performSearch(searchString)
}
}
const onSearchButtonClick = e => {
performSearch(searchInput.value)
}

searchInput.addEventListener("input", onInput)
searchButton.addEventListener("click", onSearchButtonClick)
}
}
</script>
{{ end }}
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8230,10 +8230,10 @@ __metadata:
languageName: node
linkType: hard

"fuse.js@npm:^6.5.3":
version: 6.5.3
resolution: "fuse.js@npm:6.5.3"
checksum: f7c14f4422000e7f7e3515c66f7cefdfc38adec4cf380097f4146a201ea438af60b67dc5849b3c0de0115ce3f9bc5afad6fc6570c08dcfcef5bf6e95eb8e6d6f
"fuse.js@npm:^6.6.2":
version: 6.6.2
resolution: "fuse.js@npm:6.6.2"
checksum: 17ae758ce205276ebd88bd9c9f088a100be0b4896abac9f6b09847151269d1690f41d7f98ff5813d4a58973162dbd99d0072ce807020fee6f9de60170f6b08eb
languageName: node
linkType: hard

Expand Down Expand Up @@ -12910,7 +12910,7 @@ __metadata:
expose-loader: ^4.0.0
fancy-log: ^1.3.2
file-loader: ^5.0.2
fuse.js: ^6.5.3
fuse.js: ^6.6.2
gulp: ^4.0.2
history: ^5.3.0
hugo-bin-extended: ~0.112.7
Expand Down

0 comments on commit 3cde05d

Please sign in to comment.