Wednesday, June 06, 2007

Parameterizing a string in a Wicket panel based on a property in its containing page

I had a need to dynamically change a string in a header panel on a page. The page is used for both adding an editing an object, and the string needed to say "Add X" or "Edit X" depending on the context. I didn't want to complicate the constructor signature of the panel by adding the page instance, since the page is available to the panel. The trick however, was that the page instance is only available to the panel after construction, and so I had to add the resource model in onAttach(). Note that the panel is more reusable because it has no knowledge of the complexity of the message that's being embedded in it:

Panel Java code


public class PageHeaderPanel extends Panel
{
/** Cached to allow for variable page titles */
private Label titleLabel;

public PageHeaderPanel(String id)
{
super(id);

// Can't add StringResourceModel here, because this component has not
// been attached to its page yet.
titleLabel = new Label("title", new ResourceModel("title"));
add(titleLabel);
...
}
...
/** Override to allow for variable page titles */
@Override
protected void onAttach()
{
titleLabel.setModel(new StringResourceModel(
"title", this, new Model(this.getWebPage())));
super.onAttach();
}
}

Panel HTML code


...
<span wicket:id="title">Title</span>
...

Page class code


public class AddEditUserPage extends WebPage
{
/** Used to vary the page header title */
private enum Mode {Add, Edit};
private final Mode mode;

/** Constructor used for Create (Add) User */
public AddEditUserPage()
{
mode = Mode.Add;
...
}

/** Constructor used for Update (Edit) User */
public AddEditUserPage(final String userName)
{
mode = Mode.Edit;
...
}
...

public Mode getMode()
{
return mode;
}
}

Page properties file


title=${mode} User

To internationalize the Add and Edit strings, change getMode() and the properties file as follows:

Page class code


public String getModeString()
{
return getLocalizer().getString(mode.toString(), this);
}

Page properties file


title=${modeString} User
Add=Add
Edit=Edit

2 comments:

Jonathan said...

I think you can probably do this without any code at all using wicket:message tag because the search from the panel for the resource will head up the hierarchy to the page and it will discover the resource key exists in the page's properties file.

Blogstoyevsky said...

Jonathan, this didn't work for me, unless I'm misunderstanding your suggestion. The value of the mode variable was not picked up.