Creating a Search Feature for your HUGO static website with Fuse. js and JavaScript | Sean Emerson | Skillshare

Playback Speed


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Creating a Search Feature for your HUGO static website with Fuse. js and JavaScript

teacher avatar Sean Emerson, Web Developer and Static Site Specialist

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

    • 1.

      Intro

      0:38

    • 2.

      Getting Started

      2:42

    • 3.

      Add fuse.js

      5:34

    • 4.

      JS.Build options

      4:10

    • 5.

      Add search HTML

      6:03

    • 6.

      Retrieve URL parameters

      12:28

    • 7.

      Create search index

      8:32

    • 8.

      Create search function

      6:26

    • 9.

      Show results

      12:01

    • 10.

      Create links to taxonomies

      14:49

    • 11.

      Add images to serch results

      4:54

    • 12.

      Separate search index

      11:50

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

36

Students

--

Project

About This Class

This class is all about how to search a static HUGO site with JavaScript.

I take you through the basics of javascript, and use an easy to use search library called fuse.js.

I provide you with a HUGO template to get you started. Some experience using HUGO is required. See my intro to HUGO course.

Meet Your Teacher

Teacher Profile Image

Sean Emerson

Web Developer and Static Site Specialist

Teacher
Level: Intermediate

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Intro: Hi, Shawn, my website developer and teacher and welcome to my course on searching with Hugo. I'm excited to bring you this course as it's one most requested course on Skillshare, is if meeting a dynamic search on your website just like Google, but with a static, you guys saw it. Throughout the course project. I'll be showing you how to set up a circuit system on here again. And you'll be dynamically generating the results using JavaScript and diffuse dot js library. With a small amount of JavaScript, you guys said Excited can perform just like a dynamic website coded in the back-end language like PHP. See you in the course. 2. Getting Started: Getting started. Let's do YES, even get started, you can download these thought he dot zip file and extract it. The other option is I left the link for the heat Hub repository on the master branch, which comes up by default. You can download a zip file there for the code. Once you've got that code open in Visual Studio Code, the whole photo, you'll have to start up a new terminal and run the command npm install. What that will do is it will go into the file called package.json, and it will look at the dependencies and it will install them into a file folder called node modules. In particular, it will install the version of Hugo, which is specified here. If you go to the website and you can look what the most current version is and you can actually change that to a new version of Hugo. I've set this up so simplify the process of installing. Hey guys, you don't have to worry about doing it in a bunch of scripts on left-hand side. They will be running based on the version of Hugo that's been installed into Node modules. Really quickly. We've got the dev script day which we use for adding the dev server preview for running falls that have the parameter of drafts it or the date which is in the future. We've got billed for building to the public folder. We've got render to disk that's very similar to build, except you're actually running the service so you can view it in the browser at the same time, we've got div, preview and production of options there for written to disk. Npm check is for updating NPM dependencies, but it will not be Hugo. And post install is descriptives run after you run into him stall, which installs you go. If you're after the false for any subsequent lessons, just follow the link to the GitHub repository and then change the branch doesn't for example, we've got a problem in less than four branch for. Then from there, you can download the zip folder for that lesson. If you are trying to upload your work to GitHub, you have to make sure that you delete the folder and then rerun the command git in it. After you've deleted that doc folder. So it gets rid of all my personal get history and then you can write your own. Otherwise, it will try and upload it to my Git repository. And it won't happen because you haven't got commissions for it to make sure that docx keep folder if you're trying to upload your work to dot to get or GitHub. Otherwise, I'll see you in the next lesson. 3. Add fuse.js: So let's jump right in and add Vue.js link in the results section block. We're gonna go ahead and we're gonna use npm to install fuse dot js. So we're gonna copy that command there. My falls, I've been like I showed you in the getting started section, we'll make a new terminal and paste that code in. And will it npm install the package? You'll say it's only added one package. There are no dependencies on fused dot js. Let's go ahead now and have a look at how we're going to import Vue.js. Different builds we can use. Well, looking at the ES modules builds, they've had modern bundle as they ESM packages or ES6. And there's a few options. We've got the full and basic, and then we've got the minified versions. We're going to use minified because there's something wrong, at least with the unmodified version. So we can at least gallon and have a look at it easily. Scroll down, you'll see that the full version includes extended searching and logical query operations. We're not covering those in this course. If you were to need them, you'd have to upgrade to the full version. But until then we're gonna use the basic build to make things a lot easier. We've put these basic text T import fees from fused dot js. We'll copy that. And then we'll make a new folder called assets. And a folder inside that cool JS and will make up our file Search dot-dot-dot, AS we'll call our file search, jot paste that lawn in. But then we'll go back and grab basic dot ASM dot js. Now we're going to work out where that fall actually leaves, will open up node modules. And fuselage IS. And we've got and we can see it leaves in there. So we need to modify, be fused dot slash. That's the follower after. We'll save that. And now we need to actually import this JavaScript file into our search page. We'll do, we'll go into the layouts and partials and script footer. Down the bottom. We went around and conditional P500 q dot top with a capital T. The top will be searched. I'll put the n tagging straightaway. The basic function will be called search colon equals, because we're initializing the variable resources dot get the capital G. And this is relative to the assets holder. So it's js slash GIS. That's the basic code. We're gonna do a bit more to it. We're going to use a fake tree, guy pipes, which is creating a resource from a template. Because in a few lessons Tom are gonna be creating an index. And to keep things simple, we're gonna be using the index in line in JavaScript. So again, each cheek allow you to actually generate part of that JavaScript for us, C, index of all the pages and all the keywords and texts and categories and whatnot. In this website. The way it works is what our code down here we use. There's also stop good, we should just done. And then after that, we're going to use resources dot execute as template. We've got our output file. I have to provide the dot two. It will copy that. Put a popping, will output it as the same slash dot JS. That will provide the dot. And then we're gonna run js dot build. And then we're going to run fingerprint. You having trouble finding the pot character, It's Shift and the button above Enter. We were on fingerprint. It's going to add a hashtag into the fall. And that's great for when we generate a new file, the breathless false to download the newest version of the JavaScript file, we can also add an integrity property. We use dot-dot-dot integrity to generate the integrity hash. If you do my course on JavaScript building, you'll learn all about these things. Then we're going to put a script tag. So we'll do script source. That will be permalink makes you have capital R and capital P will do integrity. Will be such dot, dot it with a capital D. Don't have integrity. Save that. And we'll, we can't actually run that statistic because we haven't got a page with the top of search that's coming up. So we'll save that and I'll see you in the next lesson. 4. JS.Build options: We're now going to be sitting up some JavaScript with building options. You go, you go uses ESBL to build JavaScript. And we're looking at different options for development and production. And also looking at the code where to make sure it is compatible with the majority of browsers out there. Go into our script footer, HTML. And then just above where we've defined search, we're going to create a new variable called Ops, options and what we call an equals. And then we'll create a dictionary with dict. Then after JS duck-billed will insert our options variable. Now let's link to the hago docs page for JavaScript building. Let's say he uses ESBL and its number of options we're gonna be looking at. The first one will be minify for production. We're gonna be modifying our code to reduce the size. You can also do that with asset magnification because you get pipes but you won't get the same result. We get a much better result with ESBL as it's designed for ES6. Next option we're gonna be doing is we're regenerating an inline source map during development so we can see where our code is come from if we're trying to debug. The next one is target, and that's for both development and production. And we're going to be outputting to ES 2015. That's as low as we can go with Hugo, you get doesn't let us go down to ES five. Unfortunately, there are some browsers like Internet Explorer that do require a x5. You'll have to use Babel for that. And babble is an option that you can actually do with Hugo, an option of running Bible. And I do cover that in my JavaScript building course. I go through all of these options in great detail back in our HTML file. The first option that we're going to be setting is minify. And we'll set that to true. You didn't need inverted commas around true because it's Boolean true or false. And the next one is target. And we're gonna set that to ES 2015. We'll just put a comment in there that this is our production options for ESBL. Will put some dashes and start an end. There's no new spaces and it will do that to the rest of our file to going to end up with extra white-space or new lines in our HTML code. We only want to output HTML. We'll indent in because we're inside the if statement. And then we'll look at for development, we use a conditional statement. If EQ, if equals guide dot environment with a capital E. Looking to match development, make sure you use inverted commas around it and it's all lowercase for development. Put our antagonists straightaway with dashes. There's no new lines or spaces. More copy our ops line and we'll paste it in and type it in. We'll get rid of the colon because we've already initialized opposite the first time where we assign it at above. Now going to be modifying it will take out minify because it defaults to false. We'll put in source map with a capital M and it's a singular map. Then put in source maps, it went work. And the only option is inline. Recap for production, we're looking at magnifying to keep our file size down. And we've got our targeted ES 2015. I'll just put a comment in above our development options. We've got our source maps it to inline so we can see where our code is coming from. We've got our target therapies, 15. We're going to be go with Hugo and ear is filled. Like I said, I've got my course on JavaScript building. If you'd like to learn more about any of these topics in greater. 5. Add search HTML: So I'm going to create some templates for the HTML, for the search function. To content. You'll see I've got some character setup from Futurama, got the companies and species pages to display the taxonomy terms. Let's go ahead and let's create a new page, will open up a new terminal and moron Hugo, new search slash index dot md. Then I'll create a new page for us based on the archetype template. Got to help our page and we'll call it search results. We'll give it a type. I'll search. Then we need to add a parameter of private. And we'll make that true using that when we create our index so that this page isn't indexed. We'll save that. We'll go into our layouts, hold up and look into underscore default. Will copy and paste out a single dot HTML or to make a new folder called Search. We'll paste it in there. They'll make a couple of changes to the page. Then underneath content will create a new div, and we'll name it JS dash. Search results makes use of capital R. It's camelCase. Then we'll save that and then we'll go and run our dev server Control. Click on the link and we'll check it out in the browser. Go to slash search. We've got our search results page or inspect, and we'll save our JavaScript file is being pulled into the footer. So you'd have a look. We've got the script source at the bottom, and it's the search dot js with the hash. We'll go to sources and search dot js. There's nothing there yet. Once we create a new shoes instance when we're creating our JavaScript to run the actual search, then the fuse library will actually be important for now because we haven't used, the variable. Variable hasn't been used yet. So for that reason, it hasn't been important by the bundler. So you have to create the search feature on the navbar. So I've used a bootstrap five navbar. I don't normally have the search on most of my websites. So for that reason we've got an edit and we're looking at adding this a picture here. You can customize it as you scroll down, you'll have to grab the whole form. We'll copy that. And then we'll paste it after the closing unordered list tag. Well then got to go through and customize the HTML is the first thing we'll do on the form. We'll do the method. We use GET and then action. And that's where the form gets sent to. And we'll do slash search slash index.html, and that's the page we just created. We're then going to go ahead and customize the input for that. We'll go and see what Google uses. Just don't google.com. We'll right-click and inspect. I'll have a look what they've done. They've used the name equals q, gets q for query. Go and set that. This way. When we hit the Go button, the Search button Q will appear up in the URL with the contents of the input. And then we can then grab that content using JavaScript. Normally you'd use it using some backend languages like PHP, but in this case, we're going to use it on the front end. And we've got to use JavaScript to access cue from the URL. And that's all using Git because it's put all of this data into the URL. Let's have a look in here. We've got auto capitalize ease off. Grab that we're trying to do is disable a lot of the features that are automatically turned on by browsers. The next one they've got 0s auto-complete and more often more copy that. And then auto correct. To get rid of that. We're not going to use autofocus because we don't want the search box to be focused by default because it's just gonna be a small part of the website. But we'll get the spell check false. I'm just targeting a hallway, put different browsers, going to try and turn off all the fixtures that they enabled by default. Last thing we'll do is on the actual form will add role equals search. Will go and check that in the browser. On any page of the site we can put a query in heat. So do you test, for example, search then brings us to the search results page, and we've got our q equals test up in the top. So for example, here on the homepage and we put it in Futurama. Then takes us to the search results page. We've got a query API, so we can then pull that query into the page because there's no direct connection. We're just loading a static IG. And then we'll use JavaScript to grab that parameter, run it through the index of all the pages. Do the actual search, and then produce some HTML dynamically on the page. That's it for this lesson, I'll see you in the next one. 6. Retrieve URL parameters: I'm gonna look at retrieving the URL parameters with JavaScript. Open up OUT such AS hall. And we'll go down a few lines and put a comment in. And there'll be params, function, function, and we'll call it params. And then we'll put in the name of the parameter. Now understand that for most people, getting started with JavaScript isn't gonna be a strength. I understand this isn't a tutorial, which is an introduction to JavaScript, but I am mindful of the fact that myself who are watching this tutorial won't have much experience with JavaScript. So I just do your best to follow along and I'll do my best to make everything as simple as possible. What we're doing here is we're creating a function. We've named it params. And when we call that function, for example, below, params, within going to tell a function which name, which primarily to actually get will be getting the Q parameter that we're passing that through as a variable. So that Q will let me pass it in and you'll see how that works in a second. Now, we're going to be creating a constant, and that's a variable which doesn't change. We're going to call it query string. You should always CamelCase. In your variables, your functions. The query string constant will be equal to window, location dot search. And what that will do is it'll pull the URL out of the URL of the page. It's like why should I do for when we hit the search button that goes to the search page. And we've got our URL at the top of the query string. Put a semicolon at the end of that. Now currently Visual Studio Code, it's called query string in a light gray. And if you put your mouse over, it'll say it's been declared, which is what's happening, but it hasn't actually been read. I'm also say that the name parameter has been declared with it's never been read. So we use these variables. You'll see it in the dark. I'm going to create another constant called URL params. That's kinda pull the parameters out of the URL. To make that happen. We're going to create a new instance of URL search pounds and make sure you get the capitalist correct that should autocomplete for you if you're in Visual Studio Code. We've got to provide that function, the string. And that's gonna be query string. That's the constant that we use credit, you'll see that we just geocoders picked out that we credit a constant so we can tap that. And it's no longer light gray. When we run this function down here, when we call it, value will be returned in place if this word, and to make that happen, we use a keyword called Return. We're going to return URL, params, dot get. And we're going to use nine. What's happening? He first line, we're pulling the URL, the URL bar, and the browser will then getting the part after the question mark to search amps. Then from there search pounds, we only want one of them. That's the Q. What we're creating here is a reusable function that you can copy and paste into any application. It hasn't got q hard-coded into it. That's q, meaning the search query for when we hit the Search button, we providing Q and we actually call the function down HE. We can test this. Now. We can do a console.log or inlet. We'll do console.log for now. So console.log. Then we've got params q. The way I like to do it is I put in backticks and I'll put search. Query is we do dollar sign and a single clearly price around our actual JavaScript code. So let's add JavaScript code. Usually you'd be putting a variable and we can do a function or a new life. But for texts, it's inside the back ticks. So there's our back ticks for the whole the text. We wrap our JavaScript in, dollar sign and the curly braces. We'll save that and we'll check out the search query and save it works. Let's put testing there and we'll search. It brings us to the search page. There's a question mark. So everything after the question mark is the queries and we just want the queue query, the q equals test. You could have multiple queries in there. In this case we don't. But with journal write everything. So you've got some reasonable functions that you can use. Now the projects, you've right-click and inspect. Got a console. You say console.log has Don't be asked it to search query is then its pulled in test from the top. And that's what we're going to use to run our search, will go about checking whether it is actually a query in that bar or whether the users just ended up on the search page. We'll do, we'll put another comment in B, check to see if a search has taken place. We'll just get rid of all that ticks there will make the constant and it'll be search query that will equal params. For example, before it was test, that was our search query. We can access that now with that constant search query because we've got these reusable function that you can copy and paste into any project and that extracts the query here and the query we're extracting use the queue query and that's pretty standard for searching. Using conditional to check if a search has taken place. If and then in brackets search query. Let's see if there's actually text in. If, if this function returns some texts, that means is I search query up in the URL bar. This function doesn't return any texts. That's because the search hasn't taken place. So we'll start off with the if it actually has taken place and then we'll do an else. We'll put a comment in their search query. We'll display a message. If no, such as taking place. If I search has taken place, if there's a query there, we'll add the query search bar to search. So it looks like it's dynamic website. And then we'll run the search. Let's go ahead now and make these things happen. We have to do, we've got to make some contents up here. So we'll do search, input, document dot, get element by ID. We'll look for JS dash search input. Then we'll do search results equals document.getElementByID by ID. Vgs search results. Link I back into our single button, HTML. And you'll see we've got our div with the ID of search results. We'll go into our header, back to our search input. And there's currently no ID on it. Add an ID to it. Audibly JS input. I use a JS dash before all of my IDs, which I used in JavaScript. So that I know that I should never remove that ID unless I know exactly where it's being used in JavaScript. Whenever I see a JS dash in an ID, I know that I shouldn't modify it because JavaScript will stop working. The idea is pretty much solely used for targeting the element in JavaScript. We've got two atoms setup. Let's go to the display message, displaying a message first. To display the message. It's a simple search results. Dot innerHTML equals. Then we've just got to put the HTML in here. We can write it in. Please. Input your search into the search box. Above. Put a semicolon at the end of the line. We'll save that and we'll test it out. We'll take off the query. You'll see what our texts there please, and put your search into the text box above. Why did a bit of padding to the bottom there, a margin below that div, open up our search page. Some padding at the bottom of the row, PB five. Let's have a go at adding the query to the search in port. So we'll do search input. Value equals search query. We're not going to look at running this search it. Save that and have a look. We'll get back to home test. And you'll see that test is still up in that search box. You can go back and you can modify it to, for example, if we run it without anything, we get our error message. Say for example, the user just ended up on this page. Well now what they've got to do to do the search. Next we can do is we can put them lighting texts team will copy that. Pop it in there. We'll change it to loading. Some temporary texts. Test it out. We've got loading and then the search will take place and the texts will get replaced. That's it for this lesson. I'll see you in the next one. 7. Create search index: So now we're gonna look at creating a search index, as I hinted at before, we're gonna be creating this index initially in line inside the JavaScript file. That way we can search directly to it and we don't have to worry about the code required to get the index from an external file. But later on in the course, I'll show you how you can split off your index into an external file. Speed things up a bit, because you don't have a JavaScript file which is weighed down by the index that allows your JavaScript file to load quickly. But for now we'll credit inline, make things easier. Let's get started. We're gonna be using Scratch to work with our data. The reason we scratch rather than just plain variables is apparently it works with FASTA. There are few things you can use scratch fall to work around limitations in Qie Gei, but we're just using it purely for spade. Now we're gonna be using a liquid scratch again for speed is not required to read on other pages. That's one of the reasons why we use Scratch. To create a new scratch. We define a variable and then we assign to it new scratch. And then we can use all of the methods we've got, sit, get, and add we're gonna be using and we'll make our variable. They'll assign in Scratch just so it works in with the docs. We're going to first of all create our new scratch instance. What we'll do at the top, we were defining a constant, we'll put a comment in there. And we'll do such index and that's Jason. Whenever we do in these clear about that. So put dashes at the start and the end so we don't end up with any extra white-space. Will do. They'll assign scratch colon equals mu, scratch. Within any scratch dot step. We have to define the key we're working and we're gonna call that index. And we're going to assign a slot so we can keep adding clips losses. We go scratch dot. We're looking at index k and we'll add a slot, make you put a dash at the end. We aren't going to range through our pages and add some Dada to that slice from eight page. Before we can do that, we have to define what are our pages. Double-spaced pages. Colon equals u dot, dot, regular pages. And that's sort of a shortcut that's included in HE guy. And it will add all of the irregular pages from your site to that variable called Pages. Then going to narrow it down with where we'll do. Page is equal. So a modifying the variable is time. Away. Pages. Params dot private, not equals, which is exclamation equals entry makes you put a space in the dash. Gonna do is if you set a parameter of private and true on any of your pages, then they won't be included in the set data because we're only including pages where params dot private isn't set to true. Which is, if you don't set it at all, It's not going to use it to true. You could also narrow down the content pages you could use.com, for example, the kind of page you might want to be set to two products. For example, you can look up, he goes away and you'll see how that works. Within range either our pages. And I'll put in the intact before I continue every page, we're going to do a scratch. Now we're going to add a dictionary. In the dictionary are going to put in the first week, that will be a total. We're gonna get that from dot title you got before, which told us that makes sense. We'll then look at a summary that comes from dot summary. All of these built-in ego variables have capitals. We're looking at content. And normally it you thought content that's full of HTML tags. We're going to use plane. If you look at the content, you'll see that we've got companies and switches also. We'll pull those in. So we'll do companies. Simple way to start with later on, we'll make it more complex. Terms. Companies. Then species will be dot, params, dot species. And last of all, we'll need the link, so we'll use permalink so we can display the full page on the safe results. That'll be done per milliliter. Normal ideas, permanent to shorten it a bit, but we want to put the whole permalink on this F results just like Google. The kindly nothing is actually being printed to the screen. So we'll just put a comment in there. And we creating such index with Scratch when actually writing any data to our JavaScript, especially now that we've got those dashes and start and the end. That prevents any knee lines or spaces being at a twelv JavaScript file. Now what we'll do is we'll create a variable and data to file. And we'll do const index equals. And we're going to use Git. So it will be scratch.mit.edu, a capital J. We're getting the index k that we've been writing to add that in there. We're going to turn it into JSON. Json. If you don't put commas, inverted commas, double Communists, back ticks anything around this because it will not work. You have to leave it as it is. And heat I will handle that for you. We will put a semicolon at the end, but then do a console.log. If you were to just put search index in there, it'll work. But you weren't actually got a signaling because console.log doesn't work with Jason. I have to use a function and that's capital JSON in stringify. And you have to open and close brackets around your JSon data. And to make it more obvious, and putting them back, take JSon data colon, and then we have a string literal, dollar sign, curly bracket around that javascript. Close that curly bracket, close that back tick. Got dollar sign curly brackets around JavaScript, back ticks around the whole string literal will save that and we'll have a look in the browser, run a search, and you inspecting the console, you'll see that It's pulled up for us. Json data. Let's get back will make it more obvious. Entire quantile I will do a back tick, JSON data colon, and then dollar sign, curly bracket. In another curly bracket around all of our JavaScript day would go back tick before we close out bracket full console.log that and have a look at JSON data coming up there. That's what we're going to use for searching. As you can see, it is quite big and it's not going to get longer. And the biggest site, and for that reason will be screening it out into a followed for a small site with no, I thought I you can leave it in JavaScripts and you wouldn't have too many issues with speed. 8. Create search function: We're going to create the search function and run few dot js to get some results on the fee sought JS website. Under live demo, you say I've got the actual index the data was searching on. And then what we have to do is we have to define our options and we've got all of the default slide out. He they will come into that because they defaults. Provided the keys we're gonna search on in the actual index. Then we have to create a new instance and we have to pass to it the index the data was searching on, and the options that we've just defined. Then we'll assign fused dot search to a variable. And we can access our results through there. If you want, you can go ahead and you can copy the options constant. Then underneath what we've already done, we'll create a new function and we'll call it search. Will have a data property that gets pulled in and open and close brackets. Then we can paste in our options. Once it I like to modify is final matches. You can go through these on the fuse website, and that means fuse will keep searching even if it finds a perfect match. And we're saying got matched character length. I'll set that to two so it doesn't just match individual characters impute ion, you end up with some results and ignore location. I'll set that to true, so it will search anyway in the strings. And threshold on only need to make that a little bit finer, will set it to 0.4. For now, you can always play with that many. And to look at our keys were definitely doing total. And we're also doing summary, content, companies and species. And we'll be refining companies and spaces later on. Now let's look at assigning some whites to the case because some kids are less important or this part of fault few thought JS looks at the length of the cake. Mix. Keys which are shorter, that gives them a higher importance and Kaizen longer, for example, the content which is quite long, you'll give it less important and we've got a short summary and then it'll have more important. But we've also got companies and spaces in there. They're not that important when it comes to searching for a character. So what we'll do is we'll create some maps. And we're going to need a name k, which is summary, then a white key. And you've got to aim for less than one because i total has been given a default of one. So we'll make our summary that 0.8 because it is quite important for Tata. We'll just put a comment in there reminding us who go to default white of one. We didn't need to worry about changing that. And then content will give that 0.6. Then run some tests and changing it seems companies, we'll get into white of zero-point for that important and we'll see what happens. We'll run some tests at the end. Then need to create our new instance. And then we'll return our results. Paste that in below the options variable. If you look at closely, we've got fuse equals new issues. And we're passing in the list and options. We put options already here, but we haven't got list. List is actually going to be dada. Dada. That's for all such data. And then we've got our search pattern and we'll set that up. Will pop pattern in as well. Then we'll go back to what we're calling our function. We'll add our search pattern and I'll search pattern is the variable called search query. So add that in. Now instead of returning will make a new constant results. Then we'll check what kind of data is being returned. So we'll do console.log. And then the results. Javascript will tell us what we're looking at. Javascript tongue, I said, what's being returned as such results is an object. So let's go ahead and we'll do a console, log that object and we will check it out. We'll do is. Instead of top of results, a string literal, the results back tick. And then we'll print our results object to a string. We'll have a look in the browser. There's our results object. Then next lesson we'll look at how to print these results via HTML onto the screen. 9. Show results: It's now look at how to share the results were gonna be printing HTML to the browser window via JavaScript. If we continue, we'll add a quick comment t results, which is an object. We'll get rid of that console.log. Need that anymore. And we'll call a function and we'll call it show results will pass. If we continue, we'll add a quick comment t results, which is an object. We'll get rid of that console.log. Need that anymore. We'll call a function and we'll call it show results. Will pass him to share results. Results will then make our function share results. We'll access the results. Motors put a heading on it. We can find it easily. First thing we'll do is we'll check if there is a length property on the results. We'll start with if there is no results. So if not, the explanation results dot length because results will always exist. Checking if there's a length on it. There's always be some sort of results generated. The variable, we're just going to check if there's any, if there's no links, will do what's coming in first and then results. Search results. Dot innerHTML equals no. Results. Found. That's a string. Just to rephrase the search results variable. We find that at the top. And that's our div where our search results are displayed. And previously we already wrote to it if there is no search query, we are marked the user search query into the search box. Now I writing this, no results found. Then we'll do an else. Let's see if there are results. So I'll put a comment in their results found. The results object. It's an array. We'll do, is we'll look at each object in that array. Will do the results for each. This is using the ES6 syntax. Displace. What we'll do is we'll make clear our HTML start with rid of the search. Searching texts will make that a blank string, empty string. We'll do, we'll credit temporary constant. We'll call that equals the element. And then we'll do search results. Dot HTML plus, equals. Plus equals means we're adding to it. It's a shorthand for adding. The long hand would be the search results. Dot innerHTML equals search results plus output. As you can see, it's much shorter to use plus, equals or just adds on. We'll save that. I'll have a look. I'll have to turn the objects into strings to eat them, so we'll do that. And then we had to put them into HTML. It's temporarily we'll use JSON dot stringify on the element just so we can see it. You can see we've got now autumn and inside the autumn we've got all of the information that we pulled out. A few guys who have bought companies content. Carefully scroll past content. Got permalink, species summary, total. Let's go through and we'll try and extract some information out of that. We'll do through and constant and it'll pop in all those items. So we've got total summary. Permalink. Content, companies, spaces, put these in prices. And that will equal element dot autumn because we've tried to access everything inside autumn. What we'll do for our output, create a string literal that ticks can start putting in some rough ticks. So we'll do title, Lexis, total. Pay off a new line just for now. We'll do permalink. Will do companies. You'll notice as I do this, the gray tends to black, which means y variables being read. Then we'll do species. In summary. Then content. That will have a look. Now I've got some much more readable information, title and that's the best match their family, companies, species. And then we've got our summary and then we get down into content. You guys, there is one problem. We haven't put a new line before title, so we'll just fix it up. New laundry for the next entry. You'll see we've got a second entry in the third 13 matches come up. Now we'll go and look at creating some HTML to format our search results. For example, on Google here, and we'll look at how their search results are being formatted. We'll look at images in a later lesson in this course. But we'll look at putting in the permalink and they move put in the title, the summary. So let's go ahead and we'll get that sorted out. It sounds like what we've done. We'll do a div class of PB free to add some padding to the bottom. Padding. And we'll do a div class equals row, class equals call, add two more columns later on when we look at putting a photo in, our heading in HCI will override the bootstraps. Margin, will put B1 touch with smaller. Then from here we can put in the title, this is a wide stream literals are really useful. So toddling slash h3. Then we'll do our link again to margin below. It can always customize. The slider. Will do put a cost in there. And the dark link, because I liked the Bootstrap default, will display the permalink called link the title as well. So I can copy that. Close out dude. I'm putting out summary, outline hearts more so l put the summary and now I'm going to put in the companies and spaces neither aren't provided. It will come back as undefined. So put that in for now. So with that company for now and later on we'll look at making it plural. Singular. Company will put species. We can delete everything. Above. Normal clothes are tags. We're going to bring that back because I've been spice. Save it and have a look in the browser. Let's look in. Great, I think we'd like to get rid of the underlying on the link to go back and change the class. I'll leave the title at the primary color. That's a great start. The only thing I was going to say it is we'll end up with a problem where if a company hasn't been set, if you turn up as undefined and if there's multiple companies, then we're going to run into some issues there with pluralize thing, but we're going to fix it up in next lesson. For now. Let's complete any. If you're not trying to deal with data that comes over rays, then you've pretty much got your search sorted out. 10. Create links to taxonomies: We're going to look at creating taxonomy links. And we'll say conditionally pluralize the heading for the taxonomy. And we'll hide it altogether if the taxonomy doesn't exist. So first we need to do is modify our index. Inside the range. We're going to create a new variable. We'll call it company's Terms and more initialize it and all equal dot get Tim's, I'm looking for the company's Terms. Going to create a blank slide. Just call IT. Companies will initialize it and it's just gonna be a slot for now. Actually you put dashes and style into these so we don't end up with extra space. Now JavaScript file and the range IVR out tombs. In tagging, enjoying put dashes all the time. Then every time iterating, we're going to add to the company slice. So we'll do companies equals companies and then more pinned. And then we'll append a dictionary and we'll put in total. Total. And then we'll do real PM link. Rel, permalink. I'm not doing family because it's a lot longer we can save with rapamycin, have less data, the permalink for the actual search result because I wanted to display it on the screen without thought a weekend clean that up a bit. So we'll put some brackets around that title. Then put in a pipe. And the first one we'll do is human eyes to get rid of any dashes inside the title. Then we'll do titled to capitalize each letter. We want that not just for companies, but also for species. We use Alt click. Then we'll go down into our scratch dot add. Instead of dot powerapps, dot companies, it will be dollar sign companies in Dallas on species to access those slices that we've just created. I'll save that and then we'll have a look at the search case. Now we need to look at targeting what we've just credit. So we've inside companies and inside species, we've now got dot title companies and also for species we've got species dot title. So we'll scroll down here. Company's total so we can access that same four species. I'm talking about. What do console.log. We'll look at the search index and back ticks. So it's a string literal. I said index, that's our description. Dollar sign, open curly braces. We can't just write search index because it won't be displayed as a face on object, will run capital's JSON dot stringify. I've been brackets search index. Save it in the browser. Click and inspect our search index. If we go to Show more, then we will copy it. Create a new file with Control N, highest ID in and then Alt, Shift F to Format. And then we'll have a look at the structure of the data. We've got content, summary and total and weight targeting. Nice. Just with content, sorry and total. But for companies and species, their total, for example, the total for spaces is a child of species. So we target that with species dot title. For the company's total, we targeted with companies dot title. That's how I've set it up. And so I'll remove the console.log. Come into that. If it was for production code, I would take the line. And then we'll go down into our HTML. We weren't company in spaces there. What we'll do inside the foreach will make a function. We'll call it Taxonomy HTML. We'll pass in the taxonomy name. The title singular. The total plural. Plural, logging. We'll check is actually a length on the taxonomy. To check this taxonomy. Taxonomy. Links. Comment. Print. An array of links. Taxonomy array equals function, array dot from that creates an array for us. And we're creating that right from our taxonomy slots that we pass them, which is also called an array. And then we have to look at the value that we're gonna use. Our function. Then we use returned to add the following to the array that we've created to cortex on me REI, credit string literal with back ticks. Won't do HREF equals b, value dot m links we added reopen linked to the dictionary. The dictionary becomes value. Then we'll put it in the title. Title. Look at our singular or plural total. Let taxonomy, total, equal. Total, single. Do a conditional. If taxonomy dot length is greater than or equal to two. Taxonomy. Total will equal. Total plural. Sorry if there is two or more atoms in our taxonomy, right? Then we're looking at a pleural total. Now it's one other thing and that is what if the plural title isn't provided? So we can actually handle that. We will do total n. Let me put some brackets around operation. The pleural total has been provided when we calling taxonomy HTML. If there is two or more automated, knew right, then we will change our taxonomy title. Put it on the pluralize. Total, will generate HTML. Taxonomy, HTML. Back take class equals Pb. One more property and small texts. We'll put in our taxonomy texts. So the total where it's singular or plural. Taxonomy total. Then put in our text on me. All right, we'll get rid of small now with that array, we want to put commas in-between each item in the array so we can actually date structure and put comments in-between it with dot join, and then we specify the color space. All of this has to go inside the conditional. If there's actually a length to taxonomy. At the start of the function will print a blank string. Let HTML. Equal blank string. Then if there are taxonomies terms present, we're going to add some HTML to it. And then after the conditional, we will return taxonomy the HTML, whether it's a blank string, or whether we've added some HTML to it. And then we'll close off the neural. Be very careful because if you used to working with Emmett, you didn't really have to. Close off. Html tags. Happens for you. We can do is we can go down into our HTML down here. And we'll start with companies. Put in taxonomy HTML function. Then we've got a pass now options. The first one is taxonomy. So what's the taxonomy? Taxonomy is going to be companies. Companies will be the array which were getting at. If you go, then we have to look at the singular total and the total provide those a string. So thought, company as singular, coma, companies as plural. Then below it. We'll do it again. I'm going to pass in species. The total will be spaces for singular. And because it's for plural as well, we'd have to worry about providing your parole. Because if the reason I plural, this step will not take place through this you singular for both. And we'll take out the loan for species, and then we'll save it and have a look in the browser. We've got our links getting pulled in. Let's go and add some extra data. For example, companies under Bender and we'll say if he comes up with a coma, go into our content and we'll go into characters in Bender. And under companies will put it in a second one. So I'll put a comma in. It will just make one up. I taste company. Save that. Now we've got the test company coming up. Actually clickable links and all take us to the page to view the taxonomy term. Let's see if we click on sexual ten page. We can see what other records share that data back and I'll take out that test company. If you're in trouble getting both of those terms to camp in the browser. This a few ways we can fix that. First one it easily we can kill the Hugo, say well, with the pin there or control C, restart the server. The next thing we can look at fixing it is right-click and inspect. Then go to network and cookies I will cache. And then while you've still got the screen open, the available tools, hold down the mouse button on the refresh and go to a hardware load. That will do its best to get totally new data out of Hugo. I've already removed that record center, can see it there. But if you follow either or both those steps, you'll probably fix your problem. Certificates lesson. In the next lesson, we'll look at adding photos to our search results. 11. Add images to serch results: If I look at adding photos to our search results, we have looked in the content, you'll notice that the images are being set up as paid resources. The ceiling, the images themselves are sitting next to the markdown files. What we're gonna do is we want to, first of all look at changing our search index. So we're going to add some photos and the answer inside the range will create a new variable called image. Will just turn it into a blank string. For now. We'll start by checking if there is an image parameter. Just for a minute. And then we'll check if we've got at least one image defined in that greater than or equal to length of dot dot images. If it's equal to or greater than one, will put out in tagging, we'll use a whip which is like an if. Resources dot get match. And the Tim will be matching will be the first item defined in dot powerapps. Dot pages will be the 0 index item. Tagging. We're going to use our image variable that we initialized Alia, thought, fill. And we'll try 120 pi size and we'll resize it for an hour to 200 and wide. Let's put some dashes in it to prevent extra white-space. Then we'll convert our image variable into a relative permalink, the mortgage down into dictionary image. Image, which is actually a permalink relative permalink. Save that down into our HTML. We modify our column, make that S him and put another column in SM2. We can always change this if it doesn't work. Div class equals call. Sam will make it four, and then we'll do col, md. That change here as well. Hop our image in the image. One g dash fluid. Then we got into our constants and more. You mean, we'll save it and have a look in the browser. There. I mean, it is coming up. I'll have a look at re-sizing the screen. That's on the small. And then when we get on extra small, and then we get to small, it comes in as four. We get an MD. It'll change to two and you can customize it however you like that. You can pull in images which are page resources. 12. Separate search index: I'm going to separate the search index of the JavaScript fall and into its own JSON file. Speed up the letting time of the JavaScript file. We'll do, we'll go into layouts and we'll create a new folder and we'll call it search index. Then they will make a file called single dot JSON. We're going into our search. Dot js will highlight everything that we are using. For our search index. We will cut that, paste it in the single dot JSON file. You'll have to get rid of that JavaScript. Lonnie and the semicolon, the cleanup out JSON file so that it's not minified. There's an option we can use and we have to pass in a dict. And then the option is indent. This is the amount of indentation. And our preferred two spaces you can put in for. If you're for space. Indent quite a person will save that. Needs to go into content. And we'll make a new folder called search index. Will make if our code index dot date. Total search index, JSON. Taught index. Private is true because we don't want it to come up in search results. Now we've changed the output format. We do that we outputs part of photo will be HTML. We don't want that, we just want JSON. Now you could do this in the search. You can put outputs of HTML and JSON. But if you've done my SEO course, you'll have a meta for alternative output format. And we don't want to be letting search engines now that we've also got these index, that reason we're doing a separate file. We're gonna hot it using private equals true. It doesn't hop in search results. Or if you've done my SEO course, it will not appear in the sitemap either. If you can figure that will then go down and we will run render to disk div. And we'll have a look in our public folder. Because we can watch what happens while the dose of his running. We'll have looking search index. And then you can see the output. And it's been indented with two spaces. Wherever a tag would normally be saying. If we didn't include that indent option, that wouldn't happen. It would have been basically identified that this is fine because it will be modified when it's exported. From now on you must use the reference desk option if you're trying to test the search functionality. Because if you use the standard dev server, it won't actually compile the search index because the browser hasn't requested the fall. For that reason, you must use render to disk. That way. It will render every single file to the public quota. And the following way they're ready to go. Run past the flag dash, dash render to DSC with you guys said. Then if I run the renders, this production that includes the minify command, will go in back in public folder, open up our index.js and you notice it has been minified. You got white minified JavaScript or CSS. Would that mean if I come in, but it will unify basic texts like XML, HTML, JSON, et cetera. I'm going to go into our search dot js. Instead of the search index, we're going to look at get JSON search index x. That's XML HTTP requests we're gonna be using. First thing we have to do when we're using XHR, we have to create a new instance. So create our function. Jason will first look at the path that we're gonna be getting. Then we'll do the callback function and the error callback function will do. Xhr equals new XML HTTP request. We'll put a comment on that. Second thing we'll do is we will open, configure. The XHR. Says we have to do when we're using XHR, we have to create a new instance. So create our function, Jason. And we'll first look at the path that we're going to be getting. Then we'll do the callback function and the error callback function will do XHR equals new XML HTTP request. We'll put a comment on that. Second thing we'll do is we will open, configure the XHR dot open for the method in which we get. Then the URL to the path will do is send it. We'll do a conditional. Data is sent and received. It's XHR. On load in. You can use start on load. But the problem with dot onload is you've got a status of 201st success. You've got other status numbers for failure and they are all onload. You can also do XHR dot on, dot on timeout. But for the purpose of this application, that's quite simple. We've got an a status of 200 and we've got other statuses. We'll do dot onload end, and then we'll do create a function. If XHR status equals 200. That's supposed success will do. For a file. Success will do const data equals JSON, not pass XHR dot response text. Then we'll do if callback has been provided, We're on callback and more passing data files will run the error callback function. Len cried out error callback function. So we'll call it get error. For example. The function will do search results dot HTML connectivity era. We then got to go into what we're calling the search. Instead, we're gonna be fetching the JSON. So we're gonna be running the getJSON and put it in a path, the callback and the error callback get JSON path. So it will be slash index slash index dot. And you can see that over here on the left in our public photo. Then we've got our callback, which will be search and our error callback, which will be get error. Now if you go down into the search function, you'll notice we had to provide a pattern which is not happening anymore. We'll get rid of that. The data is still being pushed in from inside out. Callback with data that is still being pushed in. And we'll get on each pattern and we'll change that to search query. The search query remains the same. It never changes. It's not dependent on the previous function that we use to call search. So that's fine. We can just hard code that in. We'll say that I'll have a look in the browser. Let's working, Let's go through and simulate a connectivity issue with the users Internet cuts out before the index file is downloaded. We're going to modify that filename. Look. And you'll see it comes up as connectivity era. We'll go back and we'll fix that up. There's one last thing we'll do then is we'll configure the Tommy out. Xhr dot Tawny out. For now we'll use a variable code, Tommy up top where we define the function, put in a variable of timeout and we can put a default in here. So put four seconds, it's in milliseconds, would come in four seconds as our default. So if we don't actually specify the time and he say for example, you put in three seconds. If that isn't specified, That's okay because of what our default setup. Save that and that's all ready to go.