Excerpt | ||
---|---|---|
| ||
How to Control where HTML files are loaded from (or how do I change the strategy for naming HTML files) |
Panel | ||||
---|---|---|---|---|
| ||||
|
In Wicket 1.1
Disclaimer: I'm a Wicket Newbie, and this has only been tested on Wicket 1.1 B2. YMMV.
I needed a way to load up HTML files that are all inside the same directory. That directory happened to be /WEB-INF/html. Essentially, I needed to chop off the fully qualified class name and turn com/example/wicket/app/HomePage.html
into simply /WEB-INF/html/HomePage.html
.
Wicket allows you to define multiple directories to look for HTML files, but they all assume the HTML file is in a directory structure mirroring your classes.
To generate a new strategy for turning FQCN HTML files into simple names, you have to override the getResourceStreamLocator()
method of the Application
class.
Code Block |
---|
public ResourceStreamLocator getResourceStreamLocator() { final ResourceStreamLocator defaultLocator = super.getResourceStreamLocator(); return new ResourceStreamLocator(new AbstractResourceStreamLocator() { public IResourceStream locate(final String path, final String style, final Locale locale, final String extension) { IResourceStream stream = super.locate(path, style, locale, extension); if (stream == null) { return defaultLocator.locate(path, style, locale, extension); } return stream; } protected IResourceStream locate(String path) { String fullPath = "/WEB-INF/html"+path.substring( path.lastIndexOf('/'), path.length()); try { final URL url = getWicketServlet().getServletContext() .getResource(fullPath); if (url != null) { return new UrlResourceStream(url); } } catch(MalformedURLException e) { } return null; } }); } |
Of course, you can change the path prefix, /WEB-INF/html
to whatever you like.
There may be a better way to do this. If not, I suggest the ResourceStreamLocator implement the Chain pattern, so that in the future I could simple change the method to this:
Code Block |
---|
public ResourceStreamLocator getResourceStreamLocator() { ResourceStreamLocator defaultLocator = super.getResourceStreamLocator(); ResourceStreamLocator myCustomLocator = new MyCustomResourceLocator(); myCustomLocator.setNextInChain(defaultLocator); return myCustomLocator; } |
But of course, I'm combining two different actions here. The first is converting a class name to its HTML file representation. The second action is I'm locating that file in some set of locations.
Both strategies should be pluggable, thus reducing the complexity.
Again, maybe this is already implemented somewhere?
Hope this all helps,
Seth
In Wicket 1.2
Firstly, define the new IResourceStreamLocator class:
Code Block |
---|
public class WebPageResourceStreamLocator extends AbstractResourceStreamLocator { private IResourceFinder finder; public WebPageResourceStreamLocator(IResourceFinder finder) { this.finder = finder; } protected IResourceStream locate(final Class clazz, final String path) { final URL file = finder.find(trimFolders(path)); if (file != null) { return new UrlResourceStream(file); } return null; } private String trimFolders(String path) { return path.substring(path.lastIndexOf("/") + 1); } } |
Secondly, override Application.init() method to add the new IResourceStreamLocator:
Code Block |
---|
public class CizelgemApplication extends AuthDataApplication { @Override protected void init() { super.init(); CompoundResourceStreamLocator locator = (CompoundResourceStreamLocator)getResourceSettings().getResourceStreamLocator(); WebApplicationPath resourceFinder = (WebApplicationPath) getResourceSettings().getResourceFinder(); resourceFinder.add("src/main/webapp"); //this path should be changed locator.add(0, new WebPageResourceStreamLocator(resourceFinder)); } |
Mert Nuhoglu
In Wicket 1.3
1.2 instructions updated for 1.3:
Firstly, define the new IResourceStreamLocator class:
Code Block |
---|
public class PathStripperLocator extends ResourceStreamLocator { public PathStripperLocator() { } public IResourceStream locate(final Class clazz, final String path) { IResourceStream located = super.locate(clazz, trimFolders(path)); if (located != null) { return located; } return super.locate(clazz, path); } private String trimFolders(String path) { return path.substring(path.lastIndexOf("/") + 1); } } |
Secondly, override Application.init() method to add the new IResourceStreamLocator:
Code Block |
---|
public class CizelgemApplication extends AuthDataApplication { @Override protected void init() { super.init(); IResourceSettings resourceSettings = getResourceSettings(); resourceSettings.addResourceFolder("src/main/webapp"); //this path should be changed resourceSettings.setResourceStreamLocator(new PathStripperLocator()); } |
David Rosenstrauch
In Wicket 1.4
Two lines in your Wicket init are enough so you can put the HTML in your Maven webapp
directory:
Code Block |
---|
IResourceSettings resourceSettings = getResourceSettings(); resourceSettings.addResourceFolder(""); |
This works because the default IResourceSettings looks on the servlet context root if the path does not start with a "/". This resource resolution happens in addition to the classpath resolution, so you don't lose any functionality this way.
Brian Topping
Simple Partitioning in Maven Projects
With a simple change in your Maven pom.xml file, you can get clean separation of the Java and HTML source directories. (The Java class and HTML markup are still in the same package, though, unless you also use one of the strategies mentioned above.
No Format |
---|
<project> [...] <build> <resources> <resource> <directory>src/main/resources</directory> </resource> <resource> <directory>src/main/html</directory> </resource> </resources> [...] </build> [...] </project> |
Then, put all the HTML template files in:
No Format |
---|
<your-project>/src/main/html |
Sualeh Fatehi