-
-
Save nybatista/7909cd7d10fe03c495ef052fe92ca8dd to your computer and use it in GitHub Desktop.
Integrate lunrjs with a Hugo (gohugo.io) site.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require('fs').promises; | |
const {promisify} = require('util'); | |
const frontMatterParser = require('parser-front-matter'); | |
const parse = promisify(frontMatterParser.parse.bind(frontMatterParser)); | |
async function loadPostsWithFrontMatter(postsDirectoryPath) { | |
const postNames = await fs.readdir(postsDirectoryPath); | |
const posts = await Promise.all( | |
postNames.map(async fileName => { | |
const fileContent = await fs.readFile( | |
`${postsDirectoryPath}/${fileName}`, | |
'utf8' | |
); | |
const {content, data} = await parse(fileContent); | |
return { | |
content: content.slice(0, 3000), | |
...data | |
}; | |
}) | |
); | |
return posts; | |
} | |
const lunrjs = require('lunr'); | |
function makeIndex(posts) { | |
return lunrjs(function() { | |
this.ref('title'); | |
this.field('title'); | |
this.field('content'); | |
this.field('tags'); | |
posts.forEach(p => { | |
this.add(p); | |
}); | |
}); | |
} | |
async function run() { | |
const posts = await loadPostsWithFrontMatter(`${__dirname}/content/post`); | |
const index = makeIndex(posts); | |
console.log(JSON.stringify(index)); | |
} | |
run() | |
.then(() => process.exit(0)) | |
.catch(error => { | |
console.error(error.stack); | |
process.exit(1); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
node ./build-lunrjs-index.js > static/search-index.json |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"devDependencies": { | |
"lunr": "^2.3.6", | |
"parser-front-matter": "^1.6.4" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<form method="get" action=""> | |
<input id="search" name="q" type="text" /> | |
<button type="submit" class="button">Search</button> | |
<a href="/search">Clear</a> | |
</form> | |
<div id="#app"></div> | |
<script src="https://unpkg.com/lunr/lunr.js"></script> | |
<!-- Generate a list of posts so we can display them --> | |
{{ $p := slice }} | |
{{ range (where .Site.RegularPages "Section" "==" "post") }} | |
{{ $post := dict "link" .RelPermalink "title" .Title "content" (substr .Plain 0 200) -}} | |
{{ $p = $p | append $post -}} | |
{{ end }} | |
<script> | |
const posts = JSON.parse( | |
{{ $p | jsonify }} | |
); | |
const query = new URLSearchParams(window.location.search); | |
const searchString = query.get('q'); | |
document.querySelector('#search').value = searchString; | |
const $target = document.querySelector('#app'); | |
// Our index uses title as a reference | |
const postsByTitle = posts.reduce((acc, curr) => { | |
acc[curr.title] = curr; | |
return acc; | |
}, {}); | |
fetch('/gen/search-index.json').then(function (res) { | |
return res.json(); | |
}).then(function (data) { | |
const index = lunr.Index.load(data); | |
const matches = index.search(searchString); | |
const matchPosts = []; | |
matches.forEach((m) => { | |
matchPosts.push(postsByTitle[m.ref]); | |
}); | |
if (matchPosts.length > 0) { | |
$target.innerHTML = matchPosts.map(p => { | |
return `<div> | |
<h3><a href="${p.link}">${p.title}</a></h3> | |
<p>${p.content}...</p> | |
</div>`; | |
}).join(''); | |
} else { | |
$target.innerHTML = `<div>No search results found</div>`; | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment