Saturday, April 24, 2010

April PenWag Update

It's been a while since the last post here, and quite a few things have changed on, so I'll just hit the highlights.

The most significant change is a change in who's in the driver's seat when it comes to site navigation. PenWag has for some time followed the examples where GWT runs the show. The new approach for PenWag is to let HTML control navigation, and use GWT where dynamic AJAX functionality is needed. There are a few important factors that lead to this change.

First, search engine visibility. To get maximum exposure via search engines, there has to be static content. Search engines such as Google just aren't going to see your snazzy stuff that's in a dynamically populated div. It's also very important that search engines' robots have links that they can follow to all the nooks and crannies of your site. If they can't navigate to a page via an href, that page's content will never be searchable by potential visitors.

Second, gadget integration. As you look around for gadgets to add to your site, they almost all, across the board, will be easier to integrate into a site that's using HTML for navigation instead of GWT buttons or other wizardry. One reason for this is that a lot of the gadgets depend on scripts that run when a page is loaded. If they're embedded in a dynamically-loaded div, the script, in general, will not be executed and the gadget won't work. This leads to the need for web-site funkiness such as the use of iframes to hold script-dependent gadgets.

Third, maintainability. It's just way, way easier/faster to make changes to layout and content and try different things when HTML is the driver, typically because it means a browser refresh instead of a module build then browser refresh. Module rebuilds are then only necessary when changing the dynamic parts.

Fourth, browser compatibility. This is largely an issue due to the iframe stuff mentioned above. Since browsers don't automatically size iframes like they do divs, you have to load your content then use a script to size it. This means you have to deal with browser compatibility directly. Yuck.

Fifth, analytics integration. If HTML is the driver, whatever you're using for analytics (such as Google analytics) will give a nice, clean page breakout automatically. If the site is GWT-driven from one or a few pages, you have to explicitly call out the navigation for the analytics, and that means more work.

Sixth, advertising. It's easier for the advertising engines to deliver content-relevant ads when there's static content.

Saturday, December 19, 2009

Adsense Ads and GWT - Making it work.

It seems like a lot of people have had this same problem, but I haven't found anywhere on the net where someone has found a solution. Here's how I got it to work. If you find this post helpful, I would ask the favor that you check out, and ask your friends to do the same.

I struggled for a long time trying to get an Adsense ad to appear in a <div>, but that seems to be the wrong approach. Divs are nice for styling reasons, but it seems that Adsense knows when it's in a div, and won't display.

I avoided IFrames (which is what the GWT Frame object compiles to) because sizing isn't automatic. Eventually, though, it became apparent that IFrames were the way to go, since Adsense ads will load in them. I create an IFrame and point it at a static page that contains the necessary Adsense script. That just works. The content loads correctly, and ads will display.

But here's the rub. IFrames need to be sized with custom javascript. I use this javascript: This works easily for all browsers except - you guessed it - IE. Below is the GWT code that I use to bring it all together, including a work-around for IE.

public static native String getUserAgent() /*-{
return navigator.userAgent.toLowerCase();

private Widget buildMainPanel() {
Widget mainPanel;
if(getUserAgent().contains("msie")) {
mainPanel = buildIEPanel();
} else {
mainPanel = buildNonIEPanel();


return mainPanel;

private Widget buildNonIEPanel() {
Frame mainPanel = new Frame();
mainPanel.getElement().setAttribute("onLoad", "resizeCaller();");

return mainPanel;

private Panel buildIEPanel() {
Panel mainPanel = new VerticalPanel();

HTML adBar = new HTML("Loading...");

try {
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, GWT.getModuleBaseURL() + "ie_ads/index.html");
builder.sendRequest(null, new RequestHandler(adBar, null));
} catch (RequestException e) {

HTML content = new HTML("Loading...");

String errorMessage = "Failed to load content, please try again later.";
try {
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, GWT.getModuleBaseURL() + getRootPage());
builder.sendRequest(null, new RequestHandler(content, errorMessage));
} catch (RequestException e) {

return mainPanel;

Saturday, November 14, 2009

New Feature - Updated Layout

Today's new feature is really a few new features. The layout's completely revised to allow for better growth and a broader, richer experience for visitors that are interested to share stories and grow as writers. As the new layout is filled in, writers, storytellers, student, and poets should expect to have a place on the web where they can try their craft in front of an audience, and have many of the tools and resources they need to grow as writers.

Saturday, October 31, 2009

New Feature - Author Contact

Actually, there have been quite a few changes since the last post, mostly in the area of infrastructure changes. I switched the VPS from RapidVPS to Linode. Also in there somewhere I switched over from two old-school engines (Tomcat and Apache) to more advanced solutions (Jetty and Nginx) that support a leaner, meaner application, which in the end means a better user experience.

The new feature for today is Author Contact. Authors can now be available for contact to editors, readers, and anyone else that might want to make contact. Authors control this setting through their Profile. Author's emails are kept private. This option is turned off by default. If you want to be contacted, you have to log in and turn it on.

For readers, this means that you can now contact your favorite authors, and ask for more great stories, poems, whatever. Editors/publishers can browse the site, and contact promising authors.

Authors that are available for contact will have a little envelope next to their name in the story lists. Readers of stories will see a "Contact Author" button while they're viewing the story. The reader's email and message will be sent to the author, allowing them to reply directly to the reader.

Saturday, October 24, 2009

A New Star

I'd like to introduce you all to an up-and-coming star in the universe of photography. Also, he's my son, Taylor. I may be biased.

Please take a moment to visit his web site PhotoImageOgraphy. I think you'll be glad you did.

Sunday, September 27, 2009

New Features

Per Karen's excellent suggestion, you no longer have to be a registered user to explore the features of PenWag. There's now a visitor's mode that lets visitors read stories and generally explore the site before they commit to registering.

Other recent features:
- Switch from recover password to reset password for enhanced security.
- Passwords on now hashed and not stored in the clear (!), again, for enhanced security.
- Upgraded to GWT 1.7, which allowed me to get the story list grid styled correctly.
- The Teasers are now cached using ehCache, which improves performance across-the-board.

Friday, July 3, 2009

PenWag In The GWT Gallery

PenWag is now in the GWT application gallery. Does that make it official now? Whatever "it" is?