Change where wicket 6 gets the html templates

I have been using wicket for a long time. The one thing I don’t really like is the way the markup html is being handled. This is what “wicket in action” says:

Wicket’s default way of locating resources enable you to quickly switch between the Java files and markup files during development because they’re right next to each other. Also, with this algorithm, your package components are immediately reusable without users having to configure where the templates are loaded from; if the components’ class can be found in the class path, so can their resources. It’s powerful default, and you may want to think twice before you implement something custom

Partly I agree with it. It’s clear and it wreaks havoc for pure front-end designers. They prefer not to have to root through several layers of packages directories to find the html they need to prettify. When you run in a maven project (and you should) you could put all the html files in the src/main/resources directory structure. You will still have quite a bunch of directories to go through, it’s quite normal to have package structure several layers deep com.mycompany.mavenproject1.users.admin is not strange at all. This would translage to src/main/resources/com/mycompany/mavenproject1/users/admin.

The last few projects I did with Wicket I used version 1.4.x and I used both ways. the default Wicket way where the html is right next to the java files in src/main/java/.... and the where it’s placed in the resources area of the maven project. Both ways felt awkward. When you create a new html page in Netbeans for example it will automatically create it in the webapps area.

I am gearing up for another project with wicket and as extra bonus I have completely junior developers on the team. Good and willing people, but novices in just about everything java related. So I decided to make it a little easier for them.

I have a very strict setup. Everything related to pages starts at com.mycompany.mavenproject1.pages, everything related to panels starts at com.mycompany.mavenproject1.panels. So the example above would be com.mycompany.mavenproject1.pages.users.admin. I want the last part of the package naming to be used. Basically strip the com.mycompany.mavenproject1 away from the path and serve the html from webapp area. My first idea was to use WebApplicationPath but that only moves the area where wicket uses the package system to find the markup file. Apart from that WebApplicationPath is final, you can’t override it and re-use it.

So you have to create your own implementation of IResourceFinder. And that actually proved to be quite easy:

 public class StripPackageResourceFinder implements IResourceFinder {  
   private ServletContext context;  
   private String replacement;  
   public StripPackageResourceFinder(ServletContext context, String stripPath){  
     this.context = context;  
     if (stripPath.contains(".")) {  
       replacement = stripPath.replaceAll("\\.", "/");  
     } else {  
       replacement = stripPath;  
     }  
   }  
   @Override  
   public IResourceStream find(Class<?> clazz, String pathname) {  
     IResourceStream resourceStream = null;  
     String path = stripPath(pathname);  
     try {  
       URL url = context.getResource(path);  
       if (url != null) {  
         resourceStream = new UrlResourceStream(url);  
       }  
     } catch (MalformedURLException ex) {  
       // dont do anything, file was not found  
     }  
     return resourceStream;  
   }  
   private String stripPath(String pathname) {  
     return pathname.replace(replacement, "");  
   }  
 }  

Initialize this in “WicketApplication.java” like this for example:

   @Override  
   public void init() {  
     super.init();  
     IResourceSettings settings = getResourceSettings();  
     settings.getResourceFinders().add(  
         new StripPackageResourceFinder(  
           getServletContext(),  
           HomePage.class.getPackage().getName()));  
   }  

The stripPath determines what part of the package name gets chopped off. Hope this helps a bit.

comments powered by Disqus
comments powered by Disqus