Background

In any sport, one of the most important things to considered when building a team is none other than the team's uniform. Designers spend countless hours experimenting with color scheme, logos, and overall aesthetic. Similarly, today you will be designing a UI for our Autocorrect service using HTML and CSS!

Overview

Getting Started

You will be using another Github classroom repo for this lab. To get started, you'll need to create a new repository for the lab with the stencil code and clone this repository. This link will take you through these steps:

Stencil code!

Part 1: HTML, Templating, and Web Servers!

In today’s lab, we will be using our code to create a simple webserver that we will build on in later labs. A webserver is (in software terms), a program that takes and receives user input over the internet. For this lab and other projects in 32, we will be using FreeMarker and Spark to help create our webservers.

Writing HTML

HTML (HyperText Markup Language) is the language used to define the content and structure of web pages. HTML elements can contain text, images, other content, and other HTML elements. Each element is enclosed in a pair of tags, usually of the form: <tag>content</tag>. Your browser will attempt to render any HTML tags you give it, even if they're malformed. This can make debugging tricky if you're not careful.

The most basic tags in HTML are <html>, <head>, and <body>. The html tag defines the whole document and must wrap the entire file. The head tag defines metadata that is not displayed on the page, such as the title text which appears in the tab for this page or links to CSS stylesheets. The body tag defines the portion of the web page this is displayed. Below, we've included an example HTML document. What do you think it will look like when it's displayed in your browser? Copy and save the HTML below into a file named sample.html. Then, open it in a browser (you can use chrome sample.html) to see how it is rendered. Note that comments are defined in HTML by <!-- and --> tags.

<!-- DOCTYPE is an instruction to the browser about what version of HTML
the page is written in -->
<!DOCTYPE html>
<html>

  <!-- Head contains meta data and imports -->
  <head>

    <!-- define character set in use -->
    <meta charset="utf-8">

    <!-- Title appears in tab -->
    <title>Title</title>

  </head>

  <!-- Body contains the page content -->
  <body>

    <!-- Paragraph of text -->
    <p>Hello world.</p>

  </body>

<!-- Make sure to close all your tags! -->
</html>

FreeMarker and Spark

FreeMarker files have the ".ftl" extension and can be found in the main/resources/spark/template/freemarker folder. These files are called FreeMarker templates and are written and act like HTML files except they can also contain variables – which have the syntax ${variable_name}. Using these variables, values in Java can be inserted into these templates which then gets translated into HTML. We will be giving our webserver these templates to generate the front-end, which is the what the user interacts with.

Spark is what we will be using to turn our Java code into an actual webserver, so that we can send and get information from the front-end of our webserver. Using Spark, we output HTML pages to display (using our FreeMarker templates), and can also receive information back from HTML forms, which we will cover in a minute.

Setting up a Webserver

First, we’re going to edit the FreeMarker template file that will act as the main page for our webserver. Open the “main.ftl” file in src/main/resources/spark/template/freemarker. Notice that this has the basic structure of an html file. Insert an h1 element in the body of this document containing the text “AUTOCORRECT” or whatever else you want to be the title of your webpage.

Now, we’re going to write the code in Java to host this page using Spark. In your Main class, go to this method added in the stencil:

private static void runSparkServer(int port)

In this method, you must first tell the server the port number and where to host static resources such as images, CSS stylesheets, and JavaScript files. To do this, add the following lines at the beginning of the method

Spark.port(port);
Spark.externalStaticFileLocation("src/main/resources/static");

Also, add the following lines to show exceptions in the browser and create an instance of the FreeMarker engine:

Spark.exception(Exception.class, new ExceptionPrinter());
FreeMarkerEngine freeMarker = createEngine();

Now, we’re going to define what our server gives to the browser on certain URLs using a GET request. (You can read more about GET requests here.) We want a page to load when the user visits “/autocorrect” in the browser, so add the following line inside the method:

Spark.get("/autocorrect", new AutocorrectHandler(), freeMarker);

When the user visits "/autocorrect", the browser will request some information from our Spark server, which will give back the AutocorrectHandler, which is meant to be a custom handler that contains the information on what to load for that page. Now, we need to define this AutocorrectHandler so that the page loads correctly.

Inside the Main class, create an inner class with the signature

private static class AutocorrectHandler implements TemplateViewRoute

TemplateViewRoute is an interface that requires one method to be implemented, which is

public ModelAndView handle(Request req, Response res)

This is where we give the server the FreeMarker template we want loaded as our page as well as define any variables inside the template. For now, there shouldn’t be any variables in “main.ftl”, so the only line of code needed inside the ModelAndView method is

return new ModelAndView(null, "main.ftl");

Now that we have everything set up, run mvn package to compile this new code and run it using the --gui option (note that in the run() method, this option means that runSparkServer() is called). You will also need to include the --data flag when you run the GUI. Try visiting http://localhost:4567/autocorrect in your browser and check if the page you put in “main.ftl” shows up. If it does, you’re ready to move on! If not, go back and check what might be wrong or call over a TA.

Working with Variables

As mentioned before, FreeMarker templates allow for variables to inserted into these files. So, we’re going to create two of them in “main.ftl” – replace the text “Title” at the top with a variable using ${title}, and create a variable inside the body using the variable ${content}.

In order to maintain separation between different parts of the page, we’re going to put the actual content of the webpage in “autocorrect.ftl”, which should also be included in your lab stencil. If you look inside the file, you’ll find the tag <#assign content> <#assign>, which means anything you put in between these lines will be considered as one variable content. The last line <#include "main.ftl"> means that if we return the autocorrect file, it will also return the main file with the content variable assigned. Inside the assign tag in "autocorrect.ftl", insert a variable ${message}.

Next, go to the method ModelAndView for the AutocorrectHandler in the Main class – this is where the variables we just created will be defined, using a Map<String, String>. The variable names will be the keys, and the key value is what that variable is replaced with in the template. Create this variable map at the start of the method, picking whatever you what to be the key values:

Map<String, String> variables = ImmutableMap.of("title", "someTitle", "message", "whateverYouChoose");

Lastly, replace the return statement with this line:

return new ModelAndView(variables, "autocorrect.ftl");

Now kill your GUI in terminal, run mvn package, then restart the GUI. When you refresh http://localhost:4567/autocorrect, you should see that the title on the tab has changed to whatever you defined it as, as well as the text on the page for the message variable.

Note: You can do much more complex things with template variables that might come in handy for future projects, like iterating through lists or passing it entire Java objects! Check out the FreeMarker documentation for more info here.

HTML Forms

Now that we have the basic webpage set up, we want the user to pass information from the browser to our server. The user can submit information from the webpage using an HTML form. Create a form inside the content variable using the tags:

<form method="POST" action="/results"></form>

There are many different types of forms, but today we’re going to create a simple textarea where the user can type what they want. Insert the textarea inside the form using this code:

<label for="text">Enter words here: </label><br>
<textarea name="text" id="text"></textarea><br>

Make sure to use the label tag when adding new elements to a form, and that its for attribute matches the form element's id attribute. Here, for example, "for" and "id" are both set to "name." This lets screen readers and other assistive technology know that the element and its label are connected.

Next, create a submit button inside the form:

<input type="submit">

If you refresh the page on the browser, you should see a textbox and button appear.

Next, we want to actually process the information that the user has put into the form. The arguments in the form tag mean that the results will be POSTed at "/results", which we can retrieve using Spark. Under the Spark.get line in runSparkServer(), create a new method call:

Spark.post("/results", new SubmitHandler(), freeMarker);

Now, create a SubmitHandler class like we did with the AutocorrectHandler. In the handle method, you can access the text inside the textarea when the user pressed submit through the Request req argument:

QueryParamsMap qm = req.queryMap();
String textFromTextField = qm.value("text");

Using this information, you can generate autocorrect suggestions for the user’s text.

Create your AutoCorrector

With all of this information, implement your SubmitHandler so that whenever the user submits some input, autocorrect suggestions are displayed underneath the form. You should still return autocorrect.ftl as the template in your SubmitHandler, but this will mean making changes to the templates along with your Main.java class. The changes you make in Java you’ll have to run mvn package to recompile, but for template changes you can just refresh the browser to see the changes. Also, make sure that when you run your program you load in a corpus along with some autocorrect options like this as one example so that your program actually has an autocorrector to generate suggestions from:

./run --gui --data=data/dictionary.txt --prefix --whitespace

To do this, let's add a ${suggestions} below the form in autocorrect.ftl. You will now need a "suggestions" field in the map for both of the handlers you wrote. In AutocorrectHandler suggestions should map to the empty string because the user hasn't written anything yet. In SubmitHandler you will want to take the text the user input in the form from the query parameter, call the suggest method from Autocorrector.java, convert the returned set to some sort of string representation, and set the suggestions field to that parsed string you created with the suggestions.

A Quick Note on GET vs POST:

You’ll notice that the main page is loaded using a GET request but the form is submitted using a POST request. You can submit forms using a GET request as well, but the information that the user submitted will show up in the URL, which can be useful if you want to revisit the specific information passed in the form. In general, GET is used to request a new page and POST is meant to be used to submit data to the server (but not necessarily load a new page). Read more at MDN to learn more about their differences.

Part 2: Style and the Web Inspector!

In this part of the lab, you will be editing your web page to spice up the look of your webpage!

CSS

You may have noticed that the resources/css directory in the lab contains three existing CSS files. CSS stands for Cascading Style Sheets and is the language used to determine the look and layout of a document written in HTML. It's possible to insert CSS directly into your HTML by surrounding it with <style> tags, but using separate files for CSS is good practice because it separates ~content~ from ~aesthetics~ and because it allows you to reuse styles in multiple HTML pages. These lines in “main.ftl” import stylesheets to your webpage:

<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/main.css">
<link rel="stylesheet" href="css/html5bp.css">

The three provided files are boilerplate CSS, designed to standardize display for HTML5 and be compatible across different browsers. Edit main.css to add your own styling options. The following should change the background color of the entire body of your page:

body {
    background-color: #E3A6EC;
}

A CSS command consists of a selector, in this case body, that indicates the part of the page that you're altering. Commands also include a declaration block that modifies a series of properties of the page (e.g. background-color) with corresponding values (e.g. #E3A6EC). You can import as many CSS files as you'd like with any styling options, but keep in mind the “cascading” part of cascading style sheets. With multiple styles, the more specific selectors will override less specific ones. To learn more about the priority scheme of CSS selectors, check out this Wikipediaarticle.

Selectors

There are many different ways to select elements of your page in a CSS command. One option is to refer to existing elements, such as <body> or <p>. Often, you'll want to be more specific, so Often, you'll want to be more specific, so you can give HTML elements class or ID attributes like so:

<p id="some-id" class="some-class">

An ID should be used for a unique element (i.e. there should be no duplicate IDs on a single page), and a class should be used for multiple elements you want to have the same style. In CSS, you can select an ID with "#" and a class with "." Within a CSS file, this might look like:

#some-id {
    color: red;
}

.some-class {
    color: green;
}

CSS can be tricky, and there's way too much for us to cover in this lab alone. You'll probably need to frequently refer to CSS documentation online throughout your projects.

Inspector

It is often useful to see which parts of your HTML correspond to parts of the rendered web page in your browser. Most browsers have a built inspector/debugger package to help web developers, and we will be focusing on Google Chrome's Developer Tools (DevTools for short). Right-click on any element on this page and select Inspect. The Chrome DevTools window will appear in your browser. This tool has many useful features, such as viewing the page's HTML, tracking network requests between the page and its server, and viewing the JavaScript console. Make sure the "Elements" tab is selected and mouse over any tag in the HTML to see a bounding box for that element. Click on the element in the DevTools pane to view the applicable CSS styles. Double-clicking on the value of any CSS style allows you to change that value and see the effect the change has on your web page. This is very useful when experiment with styles before changing the actual values in your file.

Your Task

Use the DevTools to quickly experiment with different styles for your Autocorrector. Play around with these values and observe how your changes affect the look of your page. Once you've found the right ~aesthetic~ for your page, modify your CSS files to permanently save the styling changes you made. Please use both IDs and classes when customizing your css!

Accessibility Testing

Web accessibility is the process of making sure that a given website is usable for as many people as possible. This includes users with disabilities that impact their interaction with the internet, like those who are color blind or visually impaired. It also includes users who are on mobile devices, have slow network connections, or are running a version of Internet Explorer that hasn't been updated since the 1990s. We will talk about accessibility multiple times over the course of CS32, but for now, we're going to focus on screen readers.

Screen readers are an assistive technology that conveys the visual information on the computer screen through non-visual means. There are many types of screen readers: most use some combination of text-to-speech and sound icons; others come with a refreshable Braille display.

Your Task

The first step to basic accessibility testing is learning how to use the default screen reader on your computer. Follow the appropriate set of instructions for your computer:

Department Machine

The Department Machines don't have functional screen readers! (We're working on it). If you're not using a personal machine you can look on with a friend, or just tell the TAs.

Mac

Click here for instructions on enabling Voice Over for Mac. Some features are intuitive, but others are more complicated. The Voice Over Training utility (third bullet point of the linked instructions) is a useful resource and we recommend that you go through it if you have time left in the lab.

Windows

Click here for instructions on enabling Narrator for Windows. Some features are intuitive, but others are more complicated. This is the table of contents for the Narrator guide, and we recommend reading through it fully if you have time left in the lab.

Linux

Click here for instructions on enabling Orca Screen Reader for Linux. Most new distros come with Orca, otherwise you should search for installation instructions for your version of Linux. To get started using Orca, here's a quick reference of common commands.

Everyone

Now that you've turned on your computer's screen reader, go back to your Autocorrector site. Try to use it with just the keyboard. Make note of what tasks are especially easy or difficult, and whether your site retains full functionality. If you couldn't see the screen, would you know how to use the site?

Finishing Up and Check Off

Once you have a working Autocorrector site as we've described, and you are happy with the appearance of your interface, call over a TA for checkoff, and show them what you've made!