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()
.
5 comments:
Thanks for the post!
Thanks for the post. I made 'getPageTitle' abstract and in the constructor I initialize the label with getPageTitle so i force every extended class to implement the getPageTitle.
Have you thought of this pattern?
Basically, you use a getter, not a setter.
I make it return a String (not a Component) and have some default text for my Label in case the String is null.
By that I have a nice fallback when I forget to set an individual page title.
Starting from Wicket 1.4 (?) components can be initialize in an onInitialize() method which safely can use overridden/abstract methods.
...thanks for a tip with Label.
Post a Comment