Tuesday, April 22, 2008

Extending a Struts2 theme

"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
          +fieldError
We can now start using the new template: And the result is following: Here's the entire template directory for you to download.

9 comments:

Anonymous said...

wow

Anonymous said...

I think this was a really great simple example of how to modify Struts2 themes. Thanks a lot!

pavan said...

thank very much ur detail theme customization . iam searching past one week ,even i didn't find what i want.i found from ur message i done some extend changes by changing java script in validation.js in xhtml theme and created new theme.so the messages it will dispaly the after text area(field).
thanking you
pavan kumar.
india

Jonathan Gerhard said...

awesome, love it, am using this technique now in a production struts2 application, exactly what I was looking for

Gautham said...

Hi, the explanation was awesome.I am totally new to struts2 and i am facing a few issues. I downloaded the template code from your link and created a folder structure under WEB-INF like: WEB-INF/src/main/resources/template
In this, i included the folder mentioned in the link of your blog. I added an entry in the struts.xml as mentioned. But it throws a Jasper Exception saying :

Template /template/fieldError/text.ftl not found. - Class: freemarker.template.Configuration

Could you please guide me asap ?

Kindest Regards,
Gautham

gautham said...

Also what is the xml file you have included in the struts.xml in the code snippet u have mentioned?

Justin said...

I just want to say thank you very much! I wasn't getting how powerful themes were in Struts2 until I read this post!

Kaleeswaran said...

Really fantastic tutorial...Thanks a lot...

Kaleeswaran said...

Great tutorial... Thanks...