2. Application Structure

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.

_images/screenshot-homepage-structure.png

Screenshot: Home page containing navigation panel.

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.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public class HomePage extends BasePage {
    public HomePage() {
        Link movieListPageLink = new Link("list_movies") {
            @Override
            public void onClick() {
                this.setResponsePage(new MovieListPage());
            }
        };
        this.add(movieListPageLink);
    }
}

Note

You can see the changes from the previous version at the address: https://pikacode.com/uyar/wicket-application-development/commit/46c3bd6d99f7. You can get a copy of this version by clicking on the download link on that page.

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.
1
2
3
4
5
6
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.
1
2
3
4
5
6
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%;
}

Note

You can see the changes from the previous version at the address: https://pikacode.com/uyar/wicket-application-development/commit/146972c319ad. You can get a copy of this version by clicking on the download link on that page.

2.3. Exercise

  • Arrange the movie list page so that it will use the same navigation panel and footer. (Solution)

Table Of Contents

Previous topic

1. Basics

Next topic

3. Data Model