For this assignment, you will be creating web pages.
No, this didn't suddenly become a web page course, and we don't expect you to know more than very simple HTML. Read on to find out more.
Web Pages
Web pages are described with a markup language called HTML. For this assignment, you will create a system that generates .html
files that you can display with a web browser or upload to a web server.
HTML is a text-based format. That means that all you have to do to create HTML pages is output text files by using Writer
(and related classes).
This assignment requires only very basic knowledge of HTML. If you don't know any HTML, you might want to have a look at the HTML Tutorial.
Class Hierarchy
We will create classes to represent a very limited subset of HTML. Representing the full language quickly becomes quite complicated, so we won't go that far. (See the note below if you're interested.) You are only required to represent (and produce in .html
files) the elements as described below.
The classes needed to do this form a hierarchy, using inheritance and interfaces. The classes that you need to create are described below.
Blocks
The basic components of our web page will be blocks. Blocks will be form the body of the page (i.e. blocks are elements that will be placed inside the <body>…</body>
).
For example, Figure 1 shows a sample page layout that contains five blocks (pink). The blocks could contain more elements (green), but we will use the blocks as the basic building blocks.
The Block
Interface is provided for you and must be implemented by every class that represents a block on the page (as described below).
The interface describes only one method: toHTML
. This method should take no arguments, and return a string that represents the instance with HTML code.
Paragraphs
The first (and simplest) block we need will be a paragraph. A paragraph is just a simple block of text on a web page. (You're reading one right now, for example).
The Paragraph
class will implement the Block
interface. The constructor should take a string that holds the contents for the paragraph. For example:
Paragraph p = new Paragraph("This is my paragraph.");
The HTML tag for a paragraph is <p>
. So, when a Paragraph
object's toHTML
method is called, it should produce code like this:
<p>This is my paragraph.</p>
Headings
Headings in HTML (like the titles “Headings” and “Blocks” above) are used to mark the beginning of sections. There are six levels of headings in HTML, from <h1>
(the largest heading, “CMPT 125/6 Assignment 4” for this page) to <h6>
(a tiny sub-subheading, rarely used). The above headings “Headings” and “Blocks” are an <h3>
and an <h2>
, respectively.
The Heading
class will also implement the Block
interface. The constructor should take an integer representing the level (1–6) and a string that gives text for the heading. If the level is not in the range 1–6, the constructor should throw an IllegalArgumentException
, with an appropriate error message.
A Heading
object's toHTML
method should produce code like this: (two different Heading
instances)
<h3>A Level 3 Heading</h3>
<h1>Main Page Title</h1>
Lists
There are two different types of lists in HTML (that we will worry about). Again, lists will implement the Block
interface.
An ordered list (<ol>
) is a list of things that are in a particular sequence. Ordered lists are typically numbered when displayed by a web browser. For example, this is an ordered list:
- first thing
- second thing
- third thing
An unordered list (<ul>
) is a list of things where the order isn't particularly important. The items in an unordered list are typically bulleted. For example, this is an unordered list:
- something
- something else
- something unrelated
The two types of lists are similar enough that they can be represented with the same class, BlockList
(I would have called it “List
”, but that's already used for the collection interface. Since you might want to use both, it would be awkward to reuse the name.)
The constructor for a BlockList
should take a boolean argument, ordered
that indicates whether or not this is an ordered list. If no argument are given, an unordered list should be created.
When a new instance is created, it should be empty (have no items in it). The method add
will be used to insert a new Item
object at the end of the list. So, both of the above examples would result from instantiating a BlockList
, and calling add
three times, with three Item
objects.
Item
is described below. Code examples for lists are included there as well.
List Items
The Item
class that represents list items will be used to hold the actual contents of lists. They do not need to implement Block
, since they are not block-level elements of the page.
When constructing an Item
, you will need to specify the text for the item. Other methods are up to you.
For example, to construct a list like the above, the following code might be used:
BlockList example = new BlockList(false);
example.add( new Item("something") );
example.add( new Item("something else") );
example.add( new Item("something unrelated") );
When the toHTML
method on this list is called, it should produce HTML like this:
<ul>
<li>something</li>
<li>something else</li>
<li>something unrelated</li>
</ul>
As you can see, the <ul>
tag is wrapped around all of the list items for that list. Each list item is enclosed in a <li>
tag. The code for an ordered list is similar, with the <ul>
replaced with <ol>
:
<ol>
<li>first thing</li>
<li>second thing</li>
<li>third thing</li>
</ol>
List Items with Links
To allow us to put some links on our pages, we will create a subclass of Item
, LinkItem
, that allows creation of a list item that includes a link to another page.
For example, here is an unordered list that contains two items with links:
The HTML code for the first item above is:
<li> <a href="http://www.cs.sfu.ca/CC/125/ggbaker/">course home page</a> </li>
The <a href="">…</a>
tag is used to create a link. The URL (web address) of the destination goes in the href=""
quotes, and the text that appears on the page goes inside the tag itself.
The constructor for a LinkItem
should take two strings: the URL and the text. The toHTML
method should return code like the example above.
The Page
The Page
class will represent the whole HTML page. The way the class hierarchy is structured, a Page
is not much more than an ordered collection of Block
s.
There is some additional information that needs to be stored as part of the page:
- The filename. This is the file that should be produced.
- The page title. This is the title that is displayed at the top of the browser window. It is also typically included in a level 1 heading as the first element in the page itself.
- A stylesheet URL (optional). This is the name of a file (in the same directory that contains CSS information. The stylesheet gives information about what each tag looks like (font, size, colour, indenting, etc.). You don't have to write stylesheets; you can use the provided examples.
The Page
object should have a constructor that takes these three arguments (all strings). Another constructor should take the filename and title, but no stylesheet (since the stylesheet is optional).
Methods
Page
objects should have (at least) these methods:
add
. Takes any object that implementsBlock
, and adds it to the current page.write
. Takes no arguments. This method should write all of the data in thePage
to the filename given when the object was constructed.
Layout
If a Page
object is constructed with new Page("page.html", "Page Title", "style1.css")
, and no blocks are added, then calling its write
method should produce a file page.html
with these contents:
<html>
<head>
<title>Page Title</title>
<link rel="stylesheet" href="style1.css">
</head>
<body>
<h1>Page Title</h1>
</body>
</html>
If the stylesheet argument isn't included in the constructor, the <link>
tag shouldn't be included.
The top-level heading (an <h1>
containing the page title, as in the example above) should be automatically added to all pages.
The HTML code for any Block
s that are add
ed to this page should be inserted after the <h1>…</h1>
.
Example
Here are some examples of pages that might be produced by this system.
- example page with no stylesheet
- example page with a stylesheet applied
- example page source [Note: Internet Explorer will not display the source properly. This can be fixed by using Firefox instead.]
The stylesheet used in the example makes pages look not entirely unlike the course web site (in Firefox at least—doing it in IE takes some changes to the HTML). You can use it for the assignment if you want. You can create your own stylesheets, but you don't have to and there will be no marks for doing so.
Test Code
Create a class Test
with a main
function. It should create a Page
, add some content to it, and write to a file test.html
.
Your main
function must not have a throws
clause. You must catch any checked exceptions.
Notes
Escaping Characters
If you want to display text like “7<10” on a web page, you cannot just include the text 7<10
in an HTML file. The web browser will see the <
and assume you're starting a new tag, not that you want to display the less-than character.
In order to display a less-than character on a web page, you have to put <
in the HTML code. So, the code to display “7<10” is “7<10
”. Basically, the <
must be replaced with <
wherever it occurs. There are some other characters that need similar substitutions (called entities) as well.
Since you will have to do this a lot, a function has been provided for you. The HTML
class contains a function escape
that makes the appropriate substitutions in a string.
All of the text that is provided by outside code (including displayed text and link URLs) must be escaped before it ends up in the HTML file.
Advanced Version
The system described here allows you to create only a very limited subset of HTML. If you were going to make a “complete” HTML manipulator/generator, the basic structure would have to be quite different. talk to Greg if you'd like to find out how. [A page with a general outline may be added, if there's interest.]
Submitting
All of your assignments in this class will have some marks allocated for style. This will include easy to understand and modify code. In particular, you should use comments where appropriate, use good variable names, split your code into methods/functions logically, and indent consistently.
When you're done, create a ZIP file containing all of the files you created for this assignment (no .class
files) and any of the supplied .java
files that you used. Submit it with the submission server.