This is the first post in a series on writing cleaner code in your WCMS Velocity formats.
Next month, I’ll be starting work on my 6th (!) Velocity-powered framework in the WCMS.
This new framework will be my largest and most widely-used since I started developing for the WCMS back in 2014. Because of this, I’ve been thinking a lot about how to write my Velocity formats in a way that will make the framework easy to maintain and extend in the future.
Unfortunately, neither Hannon Hill nor Apache have made code standards or style guides available (that I could find), and the Velocity language itself doesn’t do much to nudge you toward any kinds of best practices.
This sort of thing makes me super anxious, so I decided to fall back on my two favorite resources when it comes to code quality: Clean Code by Robert “Uncle Bob” Martin, and the PSR Standard by the PHP Framework Interop Group.
In this series on writing cleaner Velocity code, I’ll pull out some practices from both Clean Code and the PSR Standard and talk about how we can apply them to write WCMS frameworks that are less of a headache to manage.
In an earlier post, I wrote about why it’s important to reduce and isolate side effects in our code — that is, things that push things to or grab things from the world.
While the above post was talking about side effects in the context of functional programming, I believe that the Velocity code powering our WCMS frameworks can benefit a lot from a clearer separation of formats that define the parts of our templates and how they work with data and the formats that actually snap those templates together and render them out to a thing the user sees.
In the most basic level of the PSR Coding Standard, the authors lay out the following best practice:
Side Effects: A file SHOULD declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it SHOULD execute logic with side effects, but SHOULD NOT do both. The phrase ‘side effects’ means execution of logic not directly related to declaring classes, functions, constants, etc., merely from including the file.
There’s 2 really good reasons for this recommendation:
- It enforces the separation of code that describes data and process with the code that actually does something to the world. Tangling this code together can cause problems.
- It ensures that you can use other people’s code (or your own code from another project) without worrying that the code will create unwanted output or mess with your program’s state.
Velocity isn’t as elaborate a language as PHP — it’s just a templating language that takes XML and turns it into something else (usually HTML). Still, the above recommendation can be applied to our Velocity code to help make it easier to think about, fix, and re-use — especially when we combine this recommendation with 2 others I’ll talk about in future posts:
- Treat Velocity macros as pure functions
- Keep Velocity formats at one level of abstraction
PSR-1, applied to Velocity
Here’s my restatement of the principle for Velocity:
A Velocity format SHOULD define a macro and cause no other side effects, or it SHOULD render output to the browser, but SHOULD NOT do both.