For a simple Wicket webapp, setting page title can be as easy as using the
wicket:message
tag, like this:
<!DOCTYPE html>
<html>
<head>
<title><wicket:message key="page.title"></wicket:message></title>
</head>
...
</html>
Where in the
.property
file, related to each page, the
page.title
property can be set to whatever the page is titled.
When you have a complex application, however, you might need to have more control over the page title, specifically when the title has to be dynamically generated depending on, e.g., product name.
There might be different approaches to this, but the one I'm using allows to have a default title for all pages which can be overriden for each particular page.
Most of the times, there's a base page for all the other pages. The
pageTitle
label is added to the page, HTML placeholder for which is the
<title>
tag.
BasePage.html
<!DOCTYPE html>
<html>
<head>
<title wicket:id="pageTitle"></title>
</head>
...
</html>
Then we add the component to the page.
The idea is to have a quick method to replace the
pageTitle
component model once the data required to construct title is loaded. So the
setPageTitle(IModel model)
method is added.
BasePage.java
public class BasePage {
public BasePage() {
add(new Label("pageTitle", new StringResourceModel("page.title", this, null)));
}
protected void setPageTitle(IModel model) {
get("pageTitle").setModel(model);
}
}
Now, in the
ProductPage
that extends the base page, we fetch the product data and update the page title:
ProductPage.java
public class ProductPage {
final int id;
public ProductPage(PageParameters params) {
id = params.getInt("id");
final Product p = productDao.get(id);
...
// add components or whatever
...
setPageTitle(new StringResourceModel("pageTitle", this, new Model(p)));
}
}
The
ProductPage.properties
has also to be updated, assuming the product has
getTitle()
and
getPrice()
methods:
ProductPage.properties
page.title=Shiny ${title} for just ${price}!
That's the basic idea. I'm not particularly happy with this approach as it requires to always remember to update the
pageTitle
component and push the title into the page. I'd actually prefer a way to override something so the title would be pulled for me. Ideally, that would look like this:
add(new Label("pageTitle", getPageTitle()));
Unfortunately, in this case if the label is added on the
BasePage
, even if the
getPageTitle()
is overriden in the
ProductPage
, since
BasePage
is constructed prior to any logic found in
ProductPage
, there is no data to return in
getPageTitle()
.