Jamie Balfour

Welcome to my personal website.

Find out more about me, my personal projects, reviews, courses and much more here.

Official Velocity Web Server documentationWriting Velocity Web Server Modules

Purpose

The VelocityWebServerModule in plugins needs to be a class that acts as a request handler plugin for Velocity Web Server.

At a high level, it provides a bridge between Velocity Web Server and a dynamic page engine such as ZPE/YASS, so that when a request comes in for certain file types, the module:

  • reads the requested file
  • prepares server/request/session variables
  • runs the file through the parser/runtime
  • returns a VelocityHandlerData response back to the server

Required structure

The module should:

  • be a public class
  • implement VelocityRequestHandler
  • provide a handle(...) method
  • provide a getExtensions() method

Structurally it looks like this:

Java
public class VelocityWebServerModule implements VelocityRequestHandler {

  @Override
  public VelocityHandlerData handle(VelocityServerRequest request, String documentRoot, Object data) {
    // process request and return response
  }

  @Override
  public String[] getExtensions() {
    return new String[]{".ywp", ".yep"};
  }

}

1. The class declaration

The module must be declared as a public class implementing VelocityRequestHandler. This allows Velocity Web Server to recognise the class as a request handler plugin.

Java
public class VelocityWebServerModule implements VelocityRequestHandler

This tells Velocity that the class is responsible for handling requests for specific file types.

2. handle(...)

The handle(...) method is the main entry point for the module.

Java
public VelocityHandlerData handle(VelocityServerRequest request, String documentRoot, Object data)

This method is called whenever the web server receives a request for a file whose extension is handled by the module.

Parameters

  • request – contains information about the HTTP request including the file path, headers, query string, POST data, session, and remote address.
  • documentRoot – the root directory of the website being served.
  • data – optional server data that can be passed to the module.

Return value

The method must return a VelocityHandlerData object containing:

  • HTTP status code
  • response headers
  • page content
  • cookies
  • session updates

3. Create a response object

The module usually begins by creating a new response container.

Java
VelocityHandlerData result = new VelocityHandlerData();

This object will later be filled with the generated output and metadata.

4. Read and prepare the requested file

The module is responsible for loading the requested file itself.

Typically the module attempts to load a compiled page first, and if that fails it reads the raw source file.

Java
output = zenWebParser.runCompiledWebpage(
  YASSExecutablePage.load(request.getFile()).getStructure(),
  variables
);

If this fails, the module can fall back to reading the raw file:

Java
String content = FileHelperFunctions.readFileAsString(request.getFile(), "utf-8");
output = zenWebParser.parse(content, variables);

5. Prepare runtime variables

The module converts HTTP and server information into runtime variables that the page engine can use.

Typical variables include:

  • @@SERVER – server environment information
  • @@REQUEST_HEADERS – all HTTP request headers
  • @@GET – parsed query string parameters
  • @@POST – parsed POST data
  • @@POST_RAW – raw POST body when JSON is used
  • @@SESSION – session data

Example:

Java
ZPEMap $_SERVER = new ZPEMap();
$_SERVER.put(new ZPEString("REMOTE_ADDRESS"), new ZPEString(request.getRemoteAddress()));
$_SERVER.put(new ZPEString("SCRIPT"), new ZPEString(request.getFile()));

6. Run the parser/runtime

After variables are prepared, the page is executed using the parser runtime.

Java
ZENWebParser zenWebParser = new ZENWebParser(5);
output = zenWebParser.parse(content, variables);

The parser processes the dynamic page and produces the final HTML output.

7. Gather headers, cookies, and session changes

Once the page is executed, response metadata should be collected from the parser.

This includes:

  • response headers
  • cookies
  • session updates
Java
List<VelocityHandlerData.Header> headers = zenWebParser.getHeaders();
result.setCookies(zenWebParser.getCookies());

8. Set final response values

The response object is then populated with the generated data.

Java
result.setStatus(200);
result.setHeaders(headers);
result.setContent(output);

9. Error handling

A module should catch failures and return a safe HTTP response rather than crashing the server.

Java
catch (Exception e) {

  VelocityHandlerData fail = new VelocityHandlerData();
  fail.setStatus(500);

  fail.setContent("<h1>Internal Server Error</h1>");

  return fail;

}

10. getExtensions()

The getExtensions() method tells Velocity which file extensions this module should process.

Java
@Override
public String[] getExtensions() {
  return new String[]{".ywp", ".yep"};
}

Whenever the server encounters one of these extensions, the request will be handled by this module.

Comments

There are no comments on this page.

New comment

Comments are welcome and encouraged, including disagreement and critique. However, this is not a space for abuse. Disagreement is welcome; personal attacks, harassment, or hate will be removed instantly. This site reflects personal opinions, not universal truths. If you can’t distinguish between the two, this probably isn’t the place for you. The system temporarily stores IP addresses and browser user agents for the purposes of spam prevention, moderation, and safeguarding. This data is automatically removed after fourteen days. Your email address is stored so that replies can be sent to your email address.

Comments powered by BalfComment

Feedback 👍
Comments are sent via email to me.