I know of two ways to add content to the <head>
section of the page in wicket. You can use HeaderContributor
s and you can use the <wicket:head></wicket:head>
at the top of your wicket panel's html.
My problem is this: I need to add particular meta tags to particular pages of my site for web analytics purposes, but I need them to appear BEFORE an analytics script that I am including in the <head>
section of every page. I have a base abstract page that gets extended by every other page. I want to include the analytics script in the base page and add the meta tags in the panels which are located in pages that extend it. However, by default wicket adds the content you put in the <wicket:head></wicket:head>
of those panels AFTER the content included in the <head>
section of the base page.
Is there a way to tell wicket to prepend that <wicket:head></wicket:head>
content instead of appending it?
UPDATE: I'm using Webtrends, not Google Analytics, which requires 2 scripts: one in the head
section as well as one at the bottom of the page.
In Wicket 1.5, they're experimenting with different IHeaderRenderStrategy
implementations, such as ChildFirstHeaderRenderStrategy (experimental) or ParentFirstHeaderRenderStrategy (default). It seems that reordering header contributions was a problem in 1.4, so they're adressing it.
However, for Wicket 1.4, there is some kind of solution. The idea is to reorder the list of behaviors (header contributions are just yet another IBehavior). Each component has a protected getBehaviors()
method which can be overwritten. The trick is to find the behavior which corresponds to your special JS file which should be included first. I did this by creating my own instance of an HeaderContribution object, so I could perform an instance comparison and then use an ArrayList to move the HeaderContribution object from in the middle of the behavior list to the top of the behavior list:
public abstract class BasePage extends WebPage {
public BasePage() {
add(HeaderContributor.forJavaScript("foo-base.js"));
}
}
The HomePage adds the additional script, which should be rendered first. The HomePage also overwrites the geBehaviors() method:
public class HomePage extends BasePage {
private static final long serialVersionUID = 1L;
private final HeaderContributor contrib = new HeaderContributor(
new IHeaderContributor() {
public void renderHead(IHeaderResponse response) {
response.renderJavascriptReference("foo-first.js");
}
});
public HomePage(final PageParameters parameters) {
add(new Label("message", "If you see this message ..."));
add(contrib);
}
@Override
protected List getBehaviors(Class type) {
List behaviors = super.getBehaviors(type);
ArrayList sortedBehaviors = new ArrayList(behaviors);
boolean moveToTop = true;
if (moveToTop) {
if (!sortedBehaviors.remove(contrib)) {
throw new IllegalStateException();
}
sortedBehaviors.add(0, contrib);
}
return sortedBehaviors;
}
}
Now, the end result will be that the script added by HomePage is rendered first, and the script added by the BasPage comes afterwards.
<html xmlns:wicket="http://wicket.apache.org/... >
<head>
<title>Wicket Quickstart Archetype Homepage</title>
<script type="text/javascript" src="foo-first.js"></script>
<script type="text/javascript" src="foo-base.js"></script>
</head>