"Oh, so that's what a theme is!" - I exclaimed in my mind when I finally found out why my jsp page didn't look as I expected. I had the theme="simple"
set in my <form>
tag, as I had blindly copied it from some tutorial long ago, but expected the page to render as if it had the xhtml
theme applied.
Struts2 themes are the Fairy Godmother who may turn a plain looking form made out of Struts2 tags to a full-fledged table. Or in general - they may decorate any struts2 tag it with any html you wish, using Freemarker template engine.
For example, the xhtml
theme puts the <s:form>
tag into a table containing two columns: one holding labels, the other one holding inputs. Having a plain form like that:
will result in generating the following html:
It's the xhtml theme, too, who is responsible for rendering form validation errors next to the appropriate fields. Before I learned this, I had been experimenting furiously with my simple-themed form, wondering where my validation messages go!
Well, at least I've found them :). But setting my form's theme to xhtml wasn't really appealing to me. I'd have to rearrange it completely, as I have already designed it as a table. Still, I wanted the errors to appear next to the erroneous fields.
Encouraged by Mark Menard's great post, I decided to extend the Struts2's simple
theme. Nah, just tweak it a little bit, to be honest.
So I started with downloading the original simple
theme from Struts2's repository and copying it to my application under the name fieldError
. In Maven2's directory tree, it went in src\main\resources\template\fieldError
. I then replaced the text.ftl
file with the one from xhtml
theme - this is the template responsible for decorating <s:textarea>
tag. If you look inside it you'll see all it does is "calling" three other templates - controlheader.ftl
, text.ftl
from the simple theme and controlfooter.ftl
. These templates in turn extend other templates - and if you dig in, it becomes clear that all the error handling logic resides in controlheader-core.ftl
. This is the fragment that interests us the most:
Even if you're as much a Freemarker ignoramus as I am, it should be clear, that in the snippet there is a check if there are are errors and then - some kind of iteration. In each iteration there's a table row being rendered. I'm not into having any additional cells in my table, though - say, a html list would do. So here's what I replaced this fragment with:
Just one more thing and we're done. When I tried to run the app at this point, I got a message from Freemarker who was confused as of where to look for the templates. So I had to inform him of that in my struts.xml
file:
The entire directory with simple
theme also needs to be copied to the template
directory so that Freemarker can include them:
src +main +resources +template +simple +fieldErrorWe can now start using the new template: And the result is following: Here's the entire
template
directory for you to download.