Description
Adding a function search
into static website made with Hugo can be done in differents ways.
We will code this simply with JQuery+UI, in few minutes.
We will use the Hugo site.Pages
variable, and the JQueryUI autocomplete()
method.
I assume you known how to add correctly the both JQuery and JQueryUI librairies on your site.
Codes
JQueryUI
As explain into the description section, we use the events of the method autocomplete()
.
We build the $projects
variable to iterate over the Hugo $pages
variable
with the Hugo range
function.
The JQuery code:
<script>
$(function() {
var projects = [
{{- range site.Pages -}}
{{- $url := .RelPermalink -}}
{{- $title := .LinkTitle -}}
{
value: "{{ $title }}",
label: "{{- if eq $url $baseURL }}{{ site.Params.description }}{{ else if in $url "tags" }}{{- T "pageListTitle" }}{{ $title }}{{ else }}{{- safeHTML .Params.description -}}{{ end -}}",
url:"{{ $url }}"
},
{{- end -}}
];
$("#search").autocomplete({
minLength: 0,
source: projects,
focus: function( event, ui ) {
$("#search").val( ui.item.label );
return false;
},
select: function( event, ui ) {
$("#search").val( ui.item.label );
$("#replyer").val( ui.item.value );
return false;
}
})
.data('ui-autocomplete')._renderItem = function(ul, item) {
return $('<li>')
.append('<a href="' + item.url + '" alt="'+ item.label + '">' + item.value + '</a>' )
.appendTo(ul);
};
});
</script>
HTML
And for the simplest code HTML, we use two elements input
as:
<input class="form-control" id="search" placeholder="{{ T "searchHolderTitle" }}">
<input aria-hidden="true" id="replyer" class="hidden">
- the first catch the searched text
- the second return all found titles, and in the background the equivalent URL.
- the syntax
{{ i18n "searchHolderTitle" }}
exists for the multilanguage context on this website; You can replace with your personal text.
TL;DR
The fully code:
<div id="search">
<input class="form-control" id="search" placeholder="{{ T "searchHolderTitle" }}">
<input aria-hidden="true" id="replyer" class="hidden">
{{- $baseURL := site.BaseURL | absLangURL -}}
<!-- Javascript -->
<script>
$(function() {
var projects = [
{{- range site.Pages -}}
{{- $url := .RelPermalink -}}
{{- $title := .LinkTitle -}}
{
value: "{{ $title }}",
label: "{{- if eq $url $baseURL }}{{ site.Params.description }}{{ else if in $url "tags" }}{{- T "pageListTitle" }}{{ $title }}{{ else }}{{- safeHTML .Params.description -}}{{ end -}}",
url:"{{ $url }}"
},
{{- end -}}
];
$("#search").autocomplete({
minLength: 0,
source: projects,
focus: function( event, ui ) {
$("#search").val( ui.item.label );
return false;
},
select: function( event, ui ) {
$("#search").val( ui.item.label );
$("#replyer").val( ui.item.value );
return false;
}
})
.data('ui-autocomplete')._renderItem = function(ul, item) {
return $('<li>')
.append('<a href="' + item.url + '" alt="'+ item.label + '">' + item.value + '</a>' )
.appendTo(ul);
};
});
</script>
</div>
Demo
Voilà ! In few minutes, an “internal search engine” is born on your static website Hugo.
See, the search holder on the menu navigation, at top right side ;)
Documentation
- Hugo Documentation: Tools > Search
- Hugo Documentation: Functions > Range
- Hugo Documentation: Functions > I18n
Others Documentations
- Inspired by Dot theme - (cf : banner.html)
- JQuery UI
autocomplete()
method: https://jqueryui.com/autocomplete - More explains about JQueryUI
Autocomplete()
method: See the documentation - Another method to build internal search engine, with VueJS + Axios librairies