Lesson Weekend

After our previous lesson we should be ready to embrace the world of templating and learn all about Handlebars. Cool!

In our templates directory, let's create a new file called hello.hbs. We'll move the following HTML out of App.java and into this new file:

hello-friend/src/main/resources/templates/hello.hbs
<!DOCTYPE html>
<html>
  <head>
    <title>Hello Friend!</title>
    <link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css'>
  </head>
  <body>
    <!--It's useful to put a comment at the top of your hbs file to help you keep track of what is what when things get more complex.-->
    <h1>Hello From Afar</h1>
    <p>Dear Friend,</p>
    <p>How are you? I hope that you are having a nice weekend. I'm vacationing in Iceland while I learn programming! </p>
    <p>Friend, you would not believe how cold it is here. I should have gone to Hawaii instead.</p>
    <p>But I like programming a lot, so I've got that going for me. </p>
    <p>Looking forward to seeing you soon. I'll bring you back a souvenir. </p>
    <p>Cheers,</p>
    <p>Travel Enthusiast Jane</p>
    <p><a href='/favorite_photos' >P.S. Check out my favorite travel photos here.</a></p>
  </body>
</html>

Also, notice our HTML no longer consists of multiple strings being concatenated together with +. When we include HTML directly in App.java it must be in a String format. .hbs files, however, can handle regular old HTML.

These template files are often referred to as views. In web frameworks, a view is simply an output or representation of information. That is, something the user views or sees on their screen. This name is derived from the term Model-View-Controller, which is a type of architecture for software and web applications.

Configuring App.java to Work with Handlebars

Back in App.java we have additional setup to complete. We need to ensure App.java can refer to our .hbs files containing the HTML for our pages. We'll import the following packages:

App.java
import java.util.HashMap;
import java.util.Map;
import spark.ModelAndView;

public class App {
  public static void main(String[] args) {
    staticFileLocation("/public");
…
  • import java.util.HashMap;: So far we've learned about several data types, including Array and ArrayList. HashMap is yet another data type used to store information in Java. We'll explore them in detail in the next lesson.

  • import spark.ModelAndView; is a Spark tool that allows us to pass dynamic information, like variables, from our App.java file to our template files.

These packages must be imported in every project's App.java file in order to use Handlebars templates.

Referring to Handlebars Templates

Now, we can tell the get() route for our root route in App.java to use a Handlebars template:

App.java
import java.util.HashMap;
import spark.ModelAndView;
import spark.template.handlebars.HandlebarsTemplateEngine;

import static spark.Spark.*;

public class App {
  public static void main(String[] args) {
    staticFileLocation("/public");
    get("/", (request, response) -> {
      return new ModelAndView(new HashMap(), "hello.hbs");
    }, new HandlebarsTemplateEngine());

...

After adding the code depicted above, we’ll notice that HandleBarsTemplateEngine is colored red and has an underline. This is because the HandlebarsTemplateEngine class needs to be imported.

To use auto-import, place the cursor near/next to the thing that you need to import, and hit Command + Enter (Ctrl + Enter on Windows, Windows key + Enter on classroom Macs) and IntelliJ will import the class we need.

There's may be content here we don't yet understand. That's absolutely okay. We'll explore the contents of App.java together in greater detail in upcoming lessons. For now, simply know that the "hello.hbs" line tells the program which template to render.

We should now be able to launch the project by running it and see our letter at http://localhost:4567:

letter-with-hbs

Next, let's also move the HTML for the /favorite_photos page of our application to a .hbs template. We'll create a favorite_photos.hbs file in the src/main/resources/templates directory, and add the following:

src/main/resources/templates/favorite_photos.hbs
<!DOCTYPE html>
<html>
  <head>
    <title>Hello Friend!</title>
    <link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css'>
  </head>
  <body>
    <h1>Favorite Traveling Photos</h1>
    <ul>
      <li><img src='/images/foggymountain.jpeg' alt='A photo of a mountain.'/></li>
      <li><img src='/images/rockycoast.jpeg' alt='A photo of a a rocky beach.'/></li>
    </ul>
  </body>
</html>

Then, we'll alter our /favorite_photos route to use this new template:

src/main/java/App.java
import java.util.HashMap;
import spark.ModelAndView;
import spark.template.handlebars.HandlebarsTemplateEngine;

import static spark.Spark.*;

public class App {

  public static void main(String[] args) {
    staticFileLocation("/public");

    get("/", (request, response) -> {
      return new ModelAndView(new HashMap(), "hello.hbs");
    }, new HandlebarsTemplateEngine());

    get("/favorite_photos", (request, response) -> {
      return new ModelAndView(new HashMap(), "favorite_photos.hbs");
    }, new HandlebarsTemplateEngine());
  }
}

Again, we can compile and launch our application and see that our photos page still works! But our App.java file is much cleaner now that we've separated our HTML into its own template. Moving forward, we'll use Handlebars templates for all Spark applications.

Also, before moving on, make sure you understand the differences between the various tools we're using here. Gradle manages our dependencies, Spark creates a web application we can see in our browser, and Handlebars allows us to create templates, and assists in loading them into our Spark application.