blob: eb7c25582757e6b04ae528c9fc58122d64caa56d [file] [log] [blame]
Some web developers prefer to put their <script> tags at the end of page body instead of inside the <head> tags:
{code:html}
<html>
<head>
//no <script> tag here...
</head>
<body>
...
<script>
//one or more <script> tags at the end of the body
</script>
</body>
</html>
{code}
In Wicket we can achieve this result providing a custom @IHeaderResponseDecorator@ to a our application and using Wicket tag <wicket:container/> to indicate where we want to render our scripts inside the page. Interface @IHeaderResponseDecorator@ defines method @IHeaderResponse decorate(IHeaderResponse response)@ which allows to decorate or add funtionalities to Wicket @IHeaderResponse@. Our custom @IHeaderResponseDecorator@ can be registered in the application with method @setHeaderResponseDecorator@. Anytime Wicket creates an instance of @IHeaderResponse@, it will call the registered @IHeaderResponseDecorator@ to decorate the header response.
In the example project @ScriptInsideBody@ we can find a custom @IHeaderResponseDecorator@ that renders CSS into the usual <head> tag and put JavaScricpt header items into a specific container (tag <wicket:container/>)
Wicket already comes with class @JavaScriptFilteredIntoFooterHeaderResponse@ which wraps a @IHeaderResponse@ and renders in a given container all the instances of @JavaScriptHeaderItem@.
The following code is taken from the Application class of the project:
{code}
//...
@Override
public void init()
{
setHeaderResponseDecorator(new JavaScriptToBucketResponseDecorator("footer-container"));
}
/**
* Decorates an original IHeaderResponse and renders all javascript items
* (JavaScriptHeaderItem), to a specific container in the page.
*/
static class JavaScriptToBucketResponseDecorator implements IHeaderResponseDecorator
{
private String bucketName;
public JavaScriptToBucketResponseDecorator(String bucketName) {
this.bucketName = bucketName;
}
@Override
public IHeaderResponse decorate(IHeaderResponse response) {
return new JavaScriptFilteredIntoFooterHeaderResponse(response, bucketName);
}
}
{code}
As you can see in the code above the "bucket" that will contain JavaScript tags is called @"footer-container"@. To make a use of it the developer have to add a special component called @HeaderResponseContainer@ in his page:
{code}
add(new HeaderResponseContainer("someId", "filterName"));
{code}
Please note that @HeaderResponseContainer@'s needs also a name for the corresponding header response's filter. The markup of our page will look like this:
{code:html}
<html>
<header>
//no <script> tag here...
</header>
<body>
<!-- here we will have our JavaScript tags -->
<wicket:container wicket:id="someId"/>
</body>
</html>
{code}
The code of the home page is the following:
{code}
public HomePage(final PageParameters parameters) {
super(parameters);
add(new HeaderResponseContainer("footer-container", "footer-container"));
}
@Override
public void renderHead(IHeaderResponse response) {
response.render(JavaScriptHeaderItem.forReference(new PackageResourceReference(getClass(),
"javasciptLibrary.js")));
response.render(OnEventHeaderItem.forScript("'logo'", "click", "alert('Clicked me!')"));
}
{code}
Looking at the code above you can note that our page adds two script to the header section: the first is an instance of @JavaScriptHeaderItem@ and will be rendered in the @HeaderResponseContainer@ while the second will follow the usual behavior and will be rendered inside <head> tag.