All posts by ajohnson
Hacking WebWork Result Types: Freemarker to HTML to JavaScript
I threw all of my past experience with Struts out the window when I started my new job because we use WebWork. WebWork is approximately one thousand times better though so I’m not complaining. One of the unique to WebWork features (as compared to Struts) is the notion of a result type which is the process responsible for combining the model with a some kind of template (usually JSP or FreeMarker) to create a view.
Anyway, for various reasons we’ve found it useful at work to output some pieces of content usually rendered as HTML instead as JavaScript via document.write()
. Because it would be a nightmare to maintain two FreeMarker templates, one for HTML and one for JavaScript output, I figured out a way to transform a FreeMarker template that normally renders HTML to render JavaScript using a custom WebWork result type. Simply extend the FreemarkerResultdoExecute()
method with code that will look extremely similar to the existing doExecute() method. I’ll highlight the differences by showing you two lines from the existing doExecute() method:
// Process the template template.process(model, getWriter());
and then the updated version that transforms the HTML into JavaScript using the StringEscapeUtils class from the commons lang library:
// Process the template StringWriter writer = new StringWriter(); template.process(model, writer); getWriter().write("document.write('" + StringEscapeUtils.escapeJavaScript(writer.toString()) + "')");
The xwork config file changes a bit as well. Here’s both the HTML version and the JavaScript version:
<result name="html" type="freemarker">foo.ftl</result> <result name="javascript" type="freemarkerhtml2javascript"> <param name="location">foo.ftl</param> <param name="contentType">text/javascript</param> </result>
The end result is that with a little logic added to your WebWork action, you can include the result of that action in your own site:
<ww:action name="viewSnippet" executeResult="true" />
and enable other people to use the same result via embedded JavaScript:
<script src="http://yoursite.com/yourSnippet.jspa?format=javascript"></script>
Links: 8-24-2006
- Jive’s Open Source Corporate IM Solution – First Look – ebizQ
Matt was recently interviewed by ebiz, this is the resulting podcast. They talk about open source and enterprise IM.
(categories: podcasts IM jive enterprise opensource )
Links: 8-21-2006
- Chart Demo (WebFX)
Create rich charts in the browser, no server necessary.
(categories: graphing canvas visualization graph chart charting )
JSON: Making Content Syndication easier
At work we’ve been having some discussions about sharing content between two websites: the natural first option was an XML solution, in this case RSS. Site A would subscribe to the RSS feeds of the site B, periodically retrieving the updated feeds, caching the contents of each feed for a specified period of time all the while displaying the resulting content on various parts of site A.
A couple months ago (December 2005 to be exact), Yahoo started supporting JSON (a lightweight data interchange format which stands for JavaScript Object Notation), as optional result format for some of it’s web services. The most common thing said about JSON is that it’s better than XML, usually meaning that it’s easier to parse and not as verbose, here’s a well written comparison of XML and JSON if you don’t believe me. While the comparisons of simplicity, openness and interoperability are useful, I think JSON really stands out when you’re working in a browser. Going back to the example I used above where site A needs to display content from site B, as I see it, this a sample runtime / flow that bits travel through in order to make the syndication work:
every_n_seconds() --> retrieve_feed() --> store_feed_entries()
and then per request to site A:
make_page() --> get_feed_entries() --> parse_entries() --> display_entries()
. There are a number of libraries built in Java for creating and parsing RSS, some for fetching RSS and you there’s even a JSP taglib for displaying RSS. But even with all the libraries, there’s still a good amount of code to write and a number of moving parts you’ll need to maintain. If you do the syndication on the client side using JSON, there are no moving parts. To display just the title of each one of my del.icio.us posts as an example, you would end up with something like this:
<script type="text/javascript" src="http://del.icio.us/feeds/json/ajohnson1200"></script>
<script type="text/javascript">
for (var i=0, post; post = Delicious.posts[i]; i++) {
document.write(post.d + '<br />');
}
</script>
I’m comparing apples to oranges (server side RSS retrieval, storage, parse and display against client side JSON include) but there are a couple of non obvious advantages and disadvantages:
- Caching: If used on a number of pages, syndicated JSON content can reduce the number of bits a browser has to download to fully render a page. For example, let’s say (for arguments sake) that we have an RSS feed that is 17k in size and a corresponding JSON feed of the same size (even though RSS would inevitably be bigger). Using the server side RSS syndication, the browser will have to download the rendered syndicated content (again let’s say it’s 17k). Using the JSON syndicated feed across a number of page views, the browser would download the 17k JSON feed once and then not again (assuming the server has been configured to send a 304) until the feed has a new item. Winner: JSON / client
- Rendering: Of course, having the browser parse and render a 17K JSON feed wouldn’t be trivial. From a pure speed standpoint, the server could do the parse / generate once and then used an HTML rendering of the feed from cache from then on. Winner: RSS / server
- Searching: Using JSON on the client, site A (which is syndicating content from site B), wouldn’t have any way of searching the content, outside of retrieving / parsing/ storing on the server. Also, spiders wouldn’t see the syndicated content from site B on site A unlike the server side RSS syndication where the syndicated content would look no different to a spider than the other content on site A. Winner: RSS / server
- Ubiquity: JSON ‘only’ works if the browser has JavaScript enabled, which I’m guessing the large majority of users do have JavaScript enabled. But certain environments won’t and phones, set top boxes and anything else that runs in a browser but not on a PC may not have JavaScript, which means they won’t see the syndicated content. Server side generated content will be available across any platform that understands HTML. Winner: RSS / server
So wrapping up, when should you use JSON on the client and when should you use RSS on the server? If you need to syndicate a small amount of content to non programmers who can cut and paste (or programmers who are adept at JavaScript), JSON seems like the way to go. It’s trivial to get something up and running, the browser will cache the feed you create and your users will see the new content as soon as it becomes available in your JSON feed.
If you’ve read this far, you should go on and check out the examples on developer.yahoo.com and on del.icio.us. Also, if you’re a Java developer, you should head on over to sourceforge.net to take a look at the JSON-lib, which makes it wicked easy to create JSON from lists, arrays and beans.
Links: 8-17-2006
- loc.alize.us – Explore your world through everyone’s eyes
Pretty cool way to explore flickr photos… Here’s Portland…
(categories: portland flickr community )
Links: 8-15-2006
Links: 8-12-2006
- Internationalization/plural forms –
Who knew that there were 19 different ways to format plurals?
(categories: i18n internationalization plural plurals ) - Free Geek: Community Technology Center
I dropped off a couple old PCs that I wasn’t using a couple weeks back. It’s a great idea (volunteer for a couple hours and you qualify for a free PC) and reminds me of the techmission.org (back in Boston).
(categories: activism computers oscon2006 portland recycle recycling ) - Django | Documentation | URL dispatcher
How Django handles RESTian URLs
(categories: django python restian uri url urlconf ) - Perspectives – insights into the world of technology for the IT Professional
Quote: “For much of the corporate world, documenting who has access to what version of the truth and when is becoming a matter of survival.” via Sam Ruby
(categories: cms content content_management corporate ) - Oregon Parks and Recreation: Tryon Creek State Natural Area
Jogged this trail tonight with the dog, beautiful area.
(categories: dogfriendly jogging oregon outdoors portland trails ) - Shirky: Ontology is Overrated — Categories, Links, and Tags
AKA: why categories suck.
(categories: classification information ontology reference tagging tags theory ) - Improving an XML feed display through CSS and XSLT | xefteri.com
I always assumed that the FeedBurner feeds were sniffing the browser and showing me a different page than the RSS / ATOM feed… Everyone should be doing this… very few people know what to do with an RSS feed once they see a bunch of XML.
(categories: atom css design rss xml xslt )
Links: 8-11-2006
- [that was aaronland] 2006
The timeline mashup applied to blog posts… so obvious in retrospect.
(categories: ajax blogs mashed timeline ) - the show with zefrank – 08-10-06
Quote: “… leveraging our inability to understand risk.”
(categories: quotes terrorism )
Links: 8-11-2006
- [that was aaronland] 2006
The timeline mashup applied to blog posts… so obvious in retrospect.
(categories: ajax blogs mashed timeline ) - the show with zefrank – 08-10-06
Quote: “… leveraging our inability to understand risk.”
(categories: quotes terrorism )