How to write Java servlets and create HTML templates with WebMacro
WebMacro provides a very simple interface for both program author and web page designer--so you should be able to get simple things up and working quickly.
Download WebMacro hereIf you have any questions or comments about WebMacro, we urge you to join the WebMacro mailing list. Just send an e-mail message to webmacro-request@webmacro.org. It's there for technical support, feedback, bug reporting, and so forth.
WebMacro configuration is fairly straight-forward: you have to install WebMacro as a servlet, then edit its configuration file. In future versions configuration will be web-based, but until then please bear with us, you'll have to edit a couple of text files.
The best way to get going quickly is to look at the examples. WebMacro is both an application framework, and a script language--so be sure and look at both sides of it.
The API documentation contains some pretty comprehensive documentation which you should read as well.
This document will give you a very brief overview of the package.
How To Install
- You need to have a Java 1.1 VM in order to use this software; and if you want to compile it you'll also need JDK 1.1 as well. We developed it under JDK 1.1.6, so you should probably have at least that.
- Follow the installation instructions in the README.html text file included with the distribution. The short story is: You have to get a bunch of stuff into your CLASSPATH:
- The JSDK base classes have to be in your classpath
- WebMacro.jar has to be in your classpath
- The directory where you've put your handlers and other programs (or our example handlers) have to be in your classpth
- Of course the core Java classes have to be there too
In addition to that, you have to edit the WebMacro.properties file to reflect the settings on your system. Make sure this WebMacro.properties is in a directory from the same classpath as WebMacro.jar: WebMacro will use the ClassLoader (and therefore the classpath) which loaded it to try and find its properties file.
Finally, you have to configure your servlet runner to launch WebMacro under the names of the applications you want to use. See Below.
How to Configure
- If your servlet is a subclass of WMServlet (such as the Guestbook example), simply place it in your servlets directory or register it in the standard way. You must also ensure that WebMacro.jar and Webmacro.properties are in your classpath (and that you have edited WebMacro.properties to contain the correct values for your system.).
Note that this makes your derived class a Servlet, therefore you must put it in your CLASSPATH or register it with your servlet runner as you would with any other servlet.
Another way to use WebMacro is to create classes which implement the Handler interface, such as the TestWM example. This allows you to subclass from some other base class, but complicates configuration slightly. In this case you use org.webmacro.servlet.Reactor as your servlet. It is associated with your handler via the URL. Configure your servletrunner with the following property information. For the JSDK "servletrunner", that means adding the following lines to servlet.properties in the servlet directory:
servlet.APPNAME.code=org.webmacro.servlet.Reactor"APPNAME" is the name of your application, it is a single word. It becomes a part of the URL that people use to access your application. Install one line like this for every application you intend to write using the WebMacro package. Here is an example:servlet.list.code=org.webmacro.servlet.Reactor servlet.catalogue.code=org.webmacro.servlet.ReactorThis says you will have two appliactions. If you run WebMacro using the JSDK servletrunner they will appear under the URLS:/servlet/list/ /servlet/catalogue/The WebMacro package will take over the entire namespace under these prefixes, and view any URL in those areas as being part of that particular application.You will probably prefer the simpler method, of subclassing from org.webmacro.servlet.WMServlet, with its simpler configuration. Reactor is a subclass of WMServlet, so there is no real difference between these two approaches.
- Edit the WebmMacro.properties configuration file. It specifies some things like the directory where templates are stored--if you do not se this, WebMacro won't be able to return anything at all since it needs to find its templates to write data.
Writing Your Application
- Write the core of your application in Java. This means implementing the org.webmacro.servlet.Handler interface, or else subclassing from org.webmacro.servlet.WMServlet.
With the Handler approach:
When WebMacro calls your Handler.accept() method or WMServlet.handle() method it will pass you something called a WebContext. This is basically a big Map that you can put whatever you want into. The WebContext object also has a variety of helper objects within it that you can use to query things about the state of your application.
- String toString() must return the same name you registered in the servlet.properties file--if your application was called "list" there, then toString() must return the word "list".
- Template accept(WebContext) is the primary method you want to implement. Each connection to the server results in a call to your Handler's accept method.
The WebContext object is what you share with the Template.
Any variable that you put into the WebContext is available as a local variable to the template script. The WebContext is a JDK 1.2 style Map. (it will actually be a subclass of java.util.Map once JDK 1.2 is out).
Your accept() method returns a Template object. You can get these out of a TemplateStore. It is the responsibility fo the accept() method to decide which Template will be used to generate the HTML that is returned to the browser.
You choose what view you will send back to the user by choosing which template to return. It is your responsibility to ensure that you have populated the WebContext with all of the information the Template will require.
- Property Introspection: Templates use "Propety Introspection" to access the data you put into the WebContext. You should understand what that means.
WebMacro uses the introspection/reflection APIs to take a pretty deep look into the objects you stick in the WebContext. The template language has access to the properties of the objects you throw into the map.
For simple values, it will attempt this in two ways:
- it will use the bean approach and look for public fields or appropriately named get/set methods.
- if it hasn't found a specific method, it will try and view the object as a collection and use put/get methods.
- If you want to put in a list of objects into the template you have numerous options. The property introspection method is capable of iterating through any of the following types:
NOTE: We do not yet support the indexed properties in the Java bean specification, but we will. Also the iterator() method above only mimics the JDK 1.2 iterators--we will convert to using real iterators once the JDK 1.2 has been released.
- an array
- anything that has an elements() method that returns an Enumeration
- anything that has an iterator() method that returns an Iterator
The above introspection can be applied recursively, so all your objects have to do is provide a "customer[] getList()" method, for example, and template users can loop through it conveniently.
Creating Templates
- Write a set of Templates to handle the output of your application. Each Template represents one page view in the system.
If the Handler write put an object called "customer" in the WebContext passed to your template, then you can access its fields like this:
Customer $customer.name owes $customer.owing
- You can also loop through list values that may be part of an object:
<ul> #foreach $customer in $customerList { <li> $customer.name owes $customer.owing } </ul>
- We also support really simple conditionals. In the current version all you can do is test whether something is defined or not:
#if ($variable) { Yes we have variable: $variable } #else { Sorry, variable is not defined here }
- Other things you can do:
Note that some of the above are currently untested.
- #include "someUnparsedFile.txt"
- #set $variable = value
- #parse "includeSomeWebMacroTemplate.wm"
- #include "$variableFile"
#use 'text' until "--The End--" Text here is not parsed by WebMacro, up until the line matching the supplied boundary. You can use this to surround sensitive things like JavaScript, if you fear a conflict with WebMacro. In the long run we will use the #use directive to include support for inlining Java, Python, PERL, and other languages. For now the only supported parser is the "text" parser which passes its contents through unmodified. --The End--The WebMacro context includes a bunch of convenient variables that you can access. See the Javadoc comments for the WebContext class for details:
- $Broker allows you to read things from the ResourceBroker, an extensible resource manager which a programmer can plug components into on the back and.
- $CGI provides access to CGI-style variables
- $Form provides access to FORM data
- $Config provides access to properties in WebMacro.properties
- $Cookie allows you to get and set cookies from the template
- $Session allows you to get and set things in the JSDK session
- $Request is the HTTP request (HttpServletRequest)
- $Response is the HTTP response (HttpServletResponse)
More information
For more information consult the JavaDoc documentation for the various classes, and see our example code.You might also try asking on the mailing list:
Send a message containing the word "subscribe" on a line by itself to join the list.
api | design | faq | goals | links | license | othertech | quickstart | script | status