The pages in a web application share some components such as global navigation
panels. In this chapter, we will see how to implement such components without
repeating code. We will create a base page that will contain the components
that all pages in the application will acquire. See
Screenshot: Home page containing navigation panel. for the screenshot of the resulting
home page.
2.1. Base Pages
Adding shared components to multiple pages in an application is a tedious and
error-prone approach. Therefore, we would like to be able to specify these at
one point and let pages get them from that single source. For instance, we
want all our pages to use the same footer that contains the date and time but
we do not want to add a footer component to every page separately. Instead, we
would like to add it to a base page and extend all pages from this base page.
Add a new Java class named BasePage to your package (careful: a
Java class, not a Wicket page; there will be no template for this class). The
code of the class is given in
Listing: Base page class with standard footer.
Note that, the date and time label is already contained in this page
(lines 15-17).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | package wicket.quickstart;
import java.util.Date;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.model.IModel;
public class BasePage extends WebPage {
public BasePage() {
this(null);
}
public BasePage(IModel model) {
super(model);
Date now = new Date();
this.add(new Label("datetime", now.toString()));
}
}
|
Now the HomePage class will extend this BasePage instead of
the generic WebPage (see
Listing: Home page class extending the base page class)
and it will not contain the label component for the footer anymore.
Listing: | Home page class extending the base page class. |
| public class HomePage extends BasePage {
public HomePage() {
Link movieListPageLink = new Link("list_movies") {
@Override
public void onClick() {
this.setResponsePage(new MovieListPage());
}
};
this.add(movieListPageLink);
}
}
|
2.2. Panels
Another improvement concerns the navigation. We might need links to the home
page or the movie list page from many pages in the application. So, having a
global navigation mechanism where all such links will be available in all
pages might be a good idea. Wicket provides panels which let us handle
components as a group. Add a NavigationPanel class and its template
HTML file to your package with the contents given in
Listing: Navigation panel template and
Listing: Navigation panel class. In the
HTML template, we are only interested in the lines 9-14, the part where we
describe the content of the panel. The corresponding NavigationPanel
class places the link components into this panel component.
Listing: | Navigation panel template. |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | <!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
<head>
<meta charset="utf-8" />
<title>MovieDB</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<wicket:panel>
<ul>
<li><a href="#" wicket:id="home">Home</a></li>
<li><a href="#" wicket:id="list_movies">List movies</a></li>
</ul>
</wicket:panel>
</body>
</html>
|
Listing: | Navigation panel class. |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | package wicket.quickstart;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.Panel;
public class NavigationPanel extends Panel {
public NavigationPanel(String id) {
super(id);
Link homePageLink = new Link("home") {
@Override
public void onClick() {
this.setResponsePage(new HomePage());
}
};
this.add(homePageLink);
Link movieListPageLink = new Link("list_movies") {
@Override
public void onClick() {
this.setResponsePage(new MovieListPage());
}
};
this.add(movieListPageLink);
}
}
|
To make this panel available in all pages, we add it to the base page
(see Listing: Base page class constructor with navigation panel,
line 3).
Listing: | Base page class constructor with navigation panel. |
| public BasePage(IModel model) {
super(model);
this.add(new NavigationPanel("mainNavigation"));
Date now = new Date();
this.add(new Label("datetime", now.toString()));
}
|
Now the templates of our actual pages (the home page and the movie list page)
will only add this panel instead of the links (see
Listing: Home page template with navigation panel,
lines 3-5). Besides, since all components on the page are now inherited from
the base page, the constructor of the HomePage class becomes
completely empty
(see Listing: Home page class with navigation panel).
Listing: | Home page template with navigation panel. |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | <body>
<header>
<nav wicket:id="mainNavigation">
navigation links
</nav>
</header>
<h1>MovieDB Homepage</h1>
<footer>
<div id="datetime" wicket:id="datetime">
Wed Sep 4 15:32:40 EEST 2013
</div>
</footer>
</body>
|
Listing: | Home page class with navigation panel. |
| package wicket.quickstart;
public class HomePage extends BasePage {
public HomePage() {
}
}
|
To display the navigation links side by side instead of as a list, let us add
the following lines to the style sheet:
nav li {
display: inline;
margin-right: 1em;
font-size: 80%;
}