Skip to content

Commit

Permalink
Move site search to use an endpoint (github#17359)
Browse files Browse the repository at this point in the history
* Move site search to use an endpoint

* Update browser.js

* Update search.js

* Update lib/search/versions.js

Co-authored-by: James M. Greene <[email protected]>

* Fix URLs

Co-authored-by: James M. Greene <[email protected]>
  • Loading branch information
heiskr and JamesMGreene authored Jan 20, 2021
1 parent c5c2347 commit 2fb2e96
Show file tree
Hide file tree
Showing 30 changed files with 436 additions and 416 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.algolia-cache
.search-cache
.DS_Store
.env
/node_modules/
Expand Down
10 changes: 5 additions & 5 deletions contributing/search.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,10 @@ Why do we need this? For our daily shipping needs, it's tolerable that search up

### Code files

- [javascripts/search.js](javascripts/search.js) - The browser-side code that enables search using Algolia's [InstantSearch.js](https://github.com/algolia/instantsearch.js/) library.
- [lib/algolia/client.js](lib/algolia/client.js) - A thin wrapper around the [algoliasearch](https://ghub.io/algoliasearch) Node.js module for interacting with the Algolia API.
- [lib/algolia/search-index.js](lib/algolia/search-index.js) - A class for generating structured search data from repository content and syncing it with the remote Algolia service. This class has built-in validation to ensure that all records are valid before they're uploaded. This class also takes care of removing deprecated records, and compares existing remote records with the latest local records to avoid uploading records that haven't changed.
- [script/sync-algolia-search-indices.js](script/sync-algolia-search-indices.js) - The script used by the Actions workflow to update search indices on our Algolia account. This can also be [run in the development environment](#development).
- [javascripts/search.js](javascripts/search.js) - The browser-side code that enables search.
- [lib/search/algolia-client.js](lib/search/algolia-client.js) - A thin wrapper around the [algoliasearch](https://ghub.io/algoliasearch) Node.js module for interacting with the Algolia API.
- [lib/search/algolia-search-index.js](lib/search/algolia-search-index.js) - A class for generating structured search data from repository content and syncing it with the remote Algolia service. This class has built-in validation to ensure that all records are valid before they're uploaded. This class also takes care of removing deprecated records, and compares existing remote records with the latest local records to avoid uploading records that haven't changed.
- [script/sync-search-indices.js](script/sync-search-indices.js) - The script used by the Actions workflow to update search indices on our Algolia account. This can also be [run in the development environment](#development).
- [tests/algolia-search.js](tests/algolia-search.js) - Tests!

## Indices
Expand Down Expand Up @@ -136,4 +136,4 @@ Each record represents a section of a page. Sections are derived by splitting up
- It's not strictly necessary to set an `objectID` as Algolia will create one automatically, but by creating our own we have a guarantee that subsequent invocations of this upload script will overwrite existing records instead of creating numerous duplicate records with differing IDs.
- Algolia has typo tolerance. Try spelling something wrong and see what you get!
- Algolia has lots of controls for customizing each index, so we can add weights to certain attributes and create rules like "title is more important than body", etc. But it works pretty well as-is without any configuration.
- Algolia has support for "advanced query syntax" for exact matching of quoted expressions and exclusion of words preceded by a `-` sign. This is off by default but we have it enabled in our browser client. This and many other settings can be configured in Algolia.com web interface. The settings in the web interface can be overridden by the InstantSearch.js client. See [javascripts/search.js]([javascripts/search.js).
- Algolia has support for "advanced query syntax" for exact matching of quoted expressions and exclusion of words preceded by a `-` sign. This is off by default but we have it enabled in our browser client. This and many other settings can be configured in Algolia.com web interface. The settings in the web interface can be overridden by the search endpoint. See [middleware/search.js]([middleware/search.js).
8 changes: 3 additions & 5 deletions includes/search-form.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
- On all other pages, in the header
-->

<form class="mb-0" aria-hidden="true">
<div id="search-input-container">
<!-- Algolia instantsearch.js will add a search input here -->
</div>
</form>
<div id="search-input-container" aria-hidden="true">
<!-- will add a search input here -->
</div>
18 changes: 1 addition & 17 deletions javascripts/experiment.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import murmur from 'imurmurhash'
import { getUserEventsId, sendEvent } from './events'
// import h from './hyperscript'

const TREATMENT = 'TREATMENT'
const CONTROL = 'CONTROL'
Expand All @@ -19,23 +20,6 @@ export async function sendSuccess (test) {
})
}

const xmlns = 'http://www.w3.org/2000/svg'

export function h (tagName, attributes = {}, children = []) {
const el = ['svg', 'path'].includes(tagName)
? document.createElementNS(xmlns, tagName)
: document.createElement(tagName)
Object.entries(attributes).forEach(
([key, value]) => el.setAttribute(key, value)
)
children.forEach(child =>
typeof child === 'string'
? el.append(document.createTextNode(child))
: el.append(child)
)
return el
}

export default function () {
// const testName = '$test-name$'
// const xbucket = bucket(testName)
Expand Down
15 changes: 0 additions & 15 deletions javascripts/fake-hogan.js

This file was deleted.

44 changes: 44 additions & 0 deletions javascripts/hyperscript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const xmlns = 'http://www.w3.org/2000/svg'

const plainObjectConstructor = {}.constructor

function exists (value) {
return value !== null && typeof value !== 'undefined'
}

function isPlainObject (value) {
return value.constructor === plainObjectConstructor
}

function isString (value) {
return typeof value === 'string'
}

function renderChildren (el, children) {
for (const child of children) {
if (isPlainObject(child)) {
Object.entries(child)
.filter(([key, value]) => exists(value))
.forEach(([key, value]) => el.setAttribute(key, value))
} else if (Array.isArray(child)) {
renderChildren(el, child)
} else if (isString(child)) {
el.append(document.createTextNode(child))
} else {
el.append(child)
}
}
}

export default function h (tagName, ...children) {
const el = ['svg', 'path'].includes(tagName)
? document.createElementNS(xmlns, tagName)
: document.createElement(tagName)
renderChildren(el, children)
return el
}

export const tags = Object.fromEntries(
['div', 'form', 'a', 'input', 'button', 'ol', 'li', 'em']
.map(tagName => [tagName, (...args) => h(tagName, ...args)])
)
Loading

0 comments on commit 2fb2e96

Please sign in to comment.