02/26/2010

happy Friday... here's yer debugger

Category xpages
Medusa 0.7 has been released. The release package includes detailed installation instructions. Here's a brief list of features the plugin contains:
  • Server-side DOM Tree: similar to the HTML inspection of the base Firebug plugin, Medusa allows you to navigate the structure of the XPage as it exists in memory on the server. Clicking any node in the tree displays a ridiculous amount of property information for the corresponding control; if the control has an equivalent client-side HTML element, and that element can be located on the page, Medusa will highlight that element in the page.
  • Log Console: gone are the days of having to settle for print() and _dump() to send debugging information to the server console / log. Medusa includes a method for collecting error reports and purely informational debug statements for the active page... so the debug data you're viewing is not only limited to your session, it's specific to the page you're viewing. Say goodbye to filling up the server log with stack traces and fighting with coworkers over whose debug statements are whose.
  • Command Line: issue SSJS or EL commands within Firebug to be executed in the context of the open page. And not just the context of the page... if you've selected a control node in the DOM tree, the command will be executed in the scope of that control. For example, if you have a label with a "value" attribute (display text) of "First Name:", select that label in Medusa's DOM panel, and execute the following SSJS:

    this.setValue("Given Name:");

    When you click "Send", Medusa will execute the command, trigger a partial refresh specific to that control, and you'll see the label's display text change. Just as the core Firebug feature set allows you to tweak the client-side rendering of a web page to determine what your server-side code should be, Medusa's command line actually allows you to tweak the server-side page structure until it looks/behaves the way you want, drastically reducing development time.

If you develop with XPages, you need this. That's why we wrote Medusa, and now we release her into the wild to see what she will become.

02/25/2010

Medusa is coming...

Category xpages



02/22/2010

@GoogleSuggest()

Category xpages

During AD111, I mentioned that SSJS supports custom @Functions, but advised against defining your own. My primary reason for advising against it is the possibility that IBM may, in a future version of Domino, implement their own version of whatever custom function you decided to define. Back when version 6 was released, I saw far too many apps break because developers had defined their own LotusScript Replace() function in previous versions.

On the other hand, XPages are capable of so much by comparison to traditional Notes apps that it's inevitable that we'll occasionally identify functionality we'd like to encapsulate into a function that IBM probably will never make a part of the core product. So here's an example of a handy custom @Function that I doubt will ever be native to the XPages implementation of SSJS:

importPackage(javax.xml.parsers);
var @GoogleSuggest = function(partial:string) {
    var resultKey = "googleSuggest-" + partial;
    if (!(applicationScope.containsKey(resultKey))) {
        var results = [];
        var baseUrl:string = "http://google.com/complete/search?output=toolbar&q=";
        var factory = DocumentBuilderFactory.newInstance();
        var parser = factory.newDocumentBuilder();
        var domResult:DOMDocument = parser.parse(baseUrl + partial);
        var resultNodes:DOMNodeList = domResult.getElementsByTagName("suggestion");
        for (var nodeIndex:int = 0; nodeIndex < resultNodes.getLength(); nodeIndex++) {
            var resultNode:DOMElement = resultNodes.item(nodeIndex);
            results.push(resultNode.getAttribute("data"));
        }
        results.sort();
        applicationScope.put(resultKey, results);
    }
    return applicationScope.get(resultKey);
};

If you add that to a SSJS script library, then add the library as a resource on an XPage, then you can easily set the typeahead for any edit box to be the Google Suggest results for whatever value the user types:

<xp:inputText id="search">
    <xp:typeAhead mode="partial" minChars="3" var="partial"
        valueList="#{javascript:@GoogleSuggest(partial)}">
    </xp:typeAhead>
</xp:inputText>


02/15/2010

slides and example database from AD111

Category lotusphere
Sorry it's long overdue, but in response to several inquiries I've posted the slides and example database from my Lotusphere session with Stephan. Be sure to check out his post about rendering ODF documents in XPages; it provides step-by-step instructions for using one of the features included in our example database.

01/23/2010

a year of firsts

Category musings
For the past few years, I've posted some form of "annual review" on, or in the vicinity of, the last day of the calendar year. This year when the proverbial ball dropped I was simply far too busy to engage in such reflection.

Over the past week, while at Lotusphere 2010, I lost count of how many times some remark from a colleague prompted from me some variation upon, "this really has been an amazing year," prompting from them, in turn, a reminder that the year to which I was most likely referring was already over and a new year had begun. And finally it struck me: in many ways, my year now starts and ends at Lotusphere, just as believers of many faiths choose to treat a worship service as the close of one week and the beginning of another. Hence, I thought it fitting to spend some time over the course of the conference to reflect upon the experiences that I considered significant since the last time I'd wandered those halls, sat in sessions, and, yes, "serenaded" my fellow Yellowbleeders at Kimono's.

It took little time for a pattern to emerge: while the past year has, once again, been marked by personal growth and loss, professional development and challenges, this has been - more so than any other year I can recall - a year of many "firsts" for me. Here are just a few that came to mind:

  • I lost a parent. Before you ask, my mother and father are both, thankfully, still very much alive. My father-in-law, however, passed away in early November. I haven't spoken of this publicly before now for numerous reasons, but the experience of losing him had a profound impact on how I view my gratitude for the relationship I have with my own parents, my goals for the kind of person I hope to someday become, and how precious is each moment we have with the people who shape our lives, so I thought it fitting in this context to mention that experience - one that none of us can ever truly prepare for but must all eventually face.
  • I co-authored an article for THE VIEW with Nathan. (aside: I always feel a little silly capitalizing the entire name, since Internet etiquette considers that to be shouting... on the other hand, later in this list you'll see why, over time, I'm likely to become more accustomed to capitalizing a brand name in my blog posts.) Possibly because the article was about XPages, but more likely because of my co-author's reputation, the article received so much attention that we were asked to submit a follow-up article, which was published just a few weeks after the first.
  • At MWLUG in August, I had the chance to give a presentation about XPages. Not only was this the first time I'd presented a Domino-related session at a Lotus User Group, this was my first experience with public speaking since doing end user Lotus Notes training for new employees (typically 5 - 10 at a time in a small conference room) many years ago. My pacing was not what I'd hoped, so I blew through the last half of the content at approximately Mach 3 and still went over the allotted time by about 10 minutes... but it was a great experience nonetheless, and several people expressed to me afterwards that they found the session to be very informative.
  • I was given the honor of co-presenting (with Stephan Wissel) a session at Lotusphere. After all I'd heard about how much work goes into preparing these sessions, and judging by my experience at MWLUG, I had braced myself for a daunting task. With Stephan's help, however, the preparation was far easier than I'd anticipated, and - even better - the session itself was actually fun. I can't deny it was still a bit overwhelming presenting to several hundred attendees, but their response - both throughout the session and in the days since - made it clear that we accomplished the goals we'd established for the session despite being unable, in the short time we had, to demonstrate a couple of nuances we'd hoped to include.
  • I experienced an acquisition that actually proved mutually beneficial. As many of you are now aware, as of October 1, Lotus 911 officially became GROUP Experts, a division of GROUP Business Software. Unlike similar transitions I've experienced at previous employers, this acquisition truly was a merger: with practically no overlap in specialty but an identical vision and passion, our own branding has changed but our day-to-day operations have not. GROUP as a whole gained a services division, and we gained an incredible sales team with proven experience in successfully bringing products to market. In the past, we've written some pretty cool applications that weren't directly commissioned by a client, but until now, those have typically been proofs of concept to demonstrate our capabilities as a consulting services provider or to familiarize ourselves with (and, in many cases, push the boundaries of) some aspect of the Lotus Notes/Domino platform. But now that we're part of GROUP, those of you who would welcome such an occurrence will be excited to know that you will likely soon be able to actually purchase something that came out of our development lab. Which reminds me...
  • A patent application was recently filed listing me as an inventor. I'm sure you'll be seeing many mentions on Nathan's blog and elsewhere about our Innova framework, but here's the elevator pitch: it allows you to create entire XPage applications directly from the Notes client... no Designer, no Eclipse, no IDE of any kind. You simply create documents that define the structure of the database (such as the records that comprise it and the relationship between those records) and the application interface, and Innova handles the rest. </elevator> Other frameworks in Domino have used a similar conceptual approach, so why is this patent-worthy? Because - in addition to some crazy-cool interface rendering techniques - Innova uses a mutable 3NF data structure, providing not only atypical storage and performance efficiencies, but also allowing on-the-glass interaction with data relationships in a more intuitive fashion than is usually seen in "hard-coded" Domino applications... not to mention in a context where the application itself (be it CRM, help desk, ERP...) is defined entirely as data records with no modification to the underlying software at all. To our knowledge, not only has 3NF never been used this way in any XPage framework, this has never before been done in Domino, period. Again, I'm sure Nathan will tell you much more about this in the weeks to come, but I couldn't help bragging at least a little bit about how cool Innova is.
  • GROUP won the CTO Lotus Award for EMEA this year. This is the first time a project I was directly involved with resulted in a Lotus Award. However, something I wrote on my own (albeit with some CSS assistance from our graphic designer after the initial release) was also named as a finalist for a Lotus Award in another category.
  • On Tuesday, I had an opportunity to give a one-on-one demo of Innova for Alistair Rennie at his request. While this is not the first conversation I've had with a General Manager of Lotus, it certainly was the first time a GM walked straight across the Product Showcase floor to our booth specifically to ask me to show him something I'd helped to both architect and implement. Because Alistair is such a cool guy to begin with, after my short demonstration of what Innova currently looks like and description of our plans for what it will continue to become, he stuck around for a while and we just chatted about XPages and the state of Lotus in general. Then, after he wished me a good show and started to walk away, a "booth babe" from another vendor, who had been standing behind him throughout our conversation, asked him to come to their booth to watch a demo of one of their offerings... and he did. Alistair is (as jonvon would put it) unassailably cool. In fact, the best way I can think of to encapsulate how wonderful my week was is to stipulate that my conversation with Alistair was not the single biggest highlight of the conference... ANY other year (thus far), it absolutely would have been.
So... uh... sorry that turned into such a sales pitch. I really didn't mean for it to be. But after years of trying to keep this blog purely technical and not a blatant marketing channel for my employer, I can't honestly reflect on everything that's happened over the past year without expressing how excited I am about what we are now jointly capable of and the role I have the good fortune to play in that. It's thrilling and overwhelming and I can't wait to see what new opportunities this year will bring (if the latest code drop of 8.5.2 that was just delivered to design partners and managed beta participants is any indication, it's gonna be cuh-ray-zee... and y'all know I don't use that word lightly).

As I return to the "normal" life that connects one Lotusphere to another, and envision the possibilities for what this year might contain, I want to thank the people in my life that make it so fulfilling, exciting, and hopeful, especially my wife, my family, and the literally hundreds of folks who pleasantly blur the distinction between colleague and friend. I'm incredibly fortunate to have you in my life. May 2010 bring you countless blessings and opportunities to bless others... you've certainly blessed me.

01/06/2010

sessions I'll be attending at Lotusphere

Category lotusphere
Now that the full session agenda for Lotusphere 2010 has been posted, I've actually planned ahead this year and decided in advance what sessions I want to attend. While this may of course change, please consider this both my recommendation for each of the sessions listed and a roadmap to find me at the conference should you (for whatever reason) wish to do so... of course, outside of the timeslots listed below, I'll likely either be hurriedly cramming for my own session or holed up in Kimono's.

Sunday

8am-10am JMP101 IBM Lotus Domino Designer 101
1:30pm-3:30pm SHOW112 How to Build an XPages Application from Start to Finish
Monday

8am-10am OGS101 Lotusphere Opening General Session
11am-12pm AD101 IBM Lotus Domino Designer: Full Speed Ahead!
1pm-2pm AD206 Filthy Rich User Interfaces with IBM Lotus Notes 8.5
2:15pm-3:15pm AD109 XPages Performance and Scalability
3:45pm-4:45pm AD110 Unleash the Power of Xpages
5pm-6pm AD205 Developing and Deploying Secure Java Applications for the IBM Lotus Notes Client
6:15pm-7:15pm BOF201 Lotus Domino Designer
Tuesday

8:30am-9:30am BP103 "Top Chefs" Share Recipes for Avoiding Everyday Server Disasters
10am-11am KEY101 The Lotus Application Development Strategy
11:15am-12:15pm BP108 Worst Practices 4.0: "Orlando, We Have a Problem"
1:30pm-2:30pm BP207 Make Your XPage Apps "Pop!" with CSS and Themes
3:30pm-4:30pm AD108 XPages in the IBM Lotus Notes Client - A Deep Dive!
4:45pm-5:45pm AD107 Enhance Your Existing Applications with XPages
6pm-7:30pm GEEK101 SpeedGeeking!
Wednesday

7am-8am BOF204 Object-Orientated Programming in IBM Lotus Notes and Domino
8:30am-9:30am BP201 Meet "The Grumpies": Eschew Obfuscation!
10am-11am AD102 Extreme Makeover -- LotusScript and Java Editor Edition
11:15am-12:15pm AD106 XPages Just Keep Getting Better
1:30pm-2:30pm AD111* Harnessing the Power of Server-Side JavaScript and Other Advanced XPage Techniques
3pm-4pm AD104 DXL Re-invigorated
4:15pm-5:15pm INV107 An Oral History of IBM Lotus Notes: The First Twenty Years
5:45pm-6:45pm BOF203 Movin' On Up With IBM Lotus Xpages
Thursday

7am-8am BOF206 Application Architecture Based on Composite Application Technology
8:30am-9:30am AD105 Futures in IBM Lotus Domino APIs
10am-11am IDOL102 Lotusphere Idol Winner Session
11:30am-12:30pm GURU101 GURUpalooza!
1:45pm-245pm ASK101 Ask the Developers
3:15pm-4:30pm CSG101 Closing General Session

* While the rest of these may be subject to change, I'm quite certain I'll be attending this one.

12/24/2009

portable Lotus Symphony installation

Category symphony
As a followup to my last post, here's something that I somehow completely missed a few weeks ago (despite posts about if from Scott Treggiari, Mitch Cohen, Stuart McIntyre, and Arne Nielsen):

IBM, VMware and Keepod products family manufacturer NSEC, today announced that they have partnered to offer IBM's Lotus Symphony productivity software suite on Keepod devices for the first time.


What's a Keepod? Apparently, it's a roughly credit-card-sized portable hard drive with a built-in USB connector, designed to be the ultimate portable application/data container: plug it into any PC, Mac, or Linux machine and, not only can you access your portable data, but you can run a pretty comprehensive set of applications directly from the device, regardless of the host OS, without leaving a trace of those applications (or your data) on that host. Sounds pretty handy.

Since they range in price from 29 EUR ($42) for a 2GB card to 69 EUR ($101) for a 16GB (NOTE: these prices include shipping, so you might pay a bit less, especially if you live in Europe), I'm not quite intrigued enough yet to try one of these, given that I can snag a 16GB Micro SD card (with SD adapter) on NewEgg for about $40 or a 32GB thumb drive for about $65... then again, I've found both of those form factors prone to occasional disappearance, so I can certainly see the appeal of being able to store portable data in my wallet, not to mention the convenience of being able to access that data via their associated applications, even if the computer I'm currently at doesn't have those applications installed.

So I may pick one up at some point. If any of you have already tried one, I'd be curious to hear whether you would consider it a worthwhile purchase. In the meantime, the reason I finally noticed that they've packaged Symphony to run on these devices is that, motivated partly by the comment thread on my last post, I decided to refresh my memory regarding how many clicks it actually does take to download Symphony from its primary location (spoiler: despite already having an IBM ID, the total click count was 13), and noticed the Keepod press release. Intrigued, I checked out the site, and noticed that you don't actually have to own a Keepod to run their portable build of Symphony. After creating an account (which, admittedly, you do have to create in order to download Symphony from their site... but you also have to create one to even place an order for a Keepod, so by the time a device owner would come back to the site to download portable applications, they would already have an account), I went back to the Symphony page on their site, then started counting the clicks it took to actually download the software.

4.

Yes, you read that correctly: it takes more than 3 times as much clicking on a site IBM directly controls to get the software they're giving away for free as it does to obtain a custom distribution of the same free software on a partner's site. Naturally, there's still some teasing going on:

  1. The first click is a link labeled "Free Download"... sounds like that's a direct link to the ZIP file, yeah? Nope.
  2. Second click is the checkbox indicating acceptance of the license agreement (add an optional click to actually read the license agreement; I didn't... naughty user)
  3. Third click is a link labeled "Download". This even has a title attribute of "Download IBM Lotus Symphony 1.3". This will definitely be the ZIP file. Uh... nope.
  4. Fourth click is on a link labeled "Download IBM Lotus Symphony 1.3 Now!" (same hover text as the previous link). This must be the real download link. I mean, sure, the very first link had an animated down arrow graphic (this one, to be precise: ), but this one's even bigger, even though it's not animated. And they used an exclamation point in the link text... yeah, I'm sure they mean it this time.


And apparently they did, 'cause that's when the save prompt actually showed up and I finally got to download the ZIP. But even with all that teasing, it never stopped being immediately obvious how to proceed to the next step in the teasing. I didn't have to choose an operating system (maybe because on the Keepod it doesn't matter... or maybe because HTTP request headers tell the server what operating system you use, and some web servers actually pay attention to that), I didn't have to choose a language (maybe they only support English in this build, or maybe they checked the request headers and assume I speak English), and I didn't have to choose between downloading via HTTP or the vendor's proprietary download manager. In other words, despite spending perhaps more time than the average end user manning a laptop, when I got to the real download link, even I was nearing an "ugh, never mind" conclusion... despite the download process being both less tedious and more obvious than IBM's. Which reminded me that the only reason I persevered through the 13-click process when I originally downloaded Symphony was that I'm a Yellowbleeder, and Yellowbleeders know that, if we just push through this sort of thing, good software awaits us on the other side. And we're used to it. The "Facebook Generation", on the whole, is not. Just sayin'.

In any case, I followed their installation instructions (extract the ZIP file, then move the extracted folder to the Keepod), except instead of moving it to a real Keepod, I just moved the folder to an external USB drive. The first time I launched it from the external drive, it popped up a MessageBox saying something like, "Hey, that's not a Keepod!"... and then Symphony opened just fine. After playing for a bit, I closed it. After starting this blog entry, I'd forgotten the wording of that error, so I launched it again to transcribe it word for word... except this time, no error, only Symphony. YMMV, but I'm quite stoked... both that IBM decided to bundle Symphony this way, and that I can run it portably even though I don't own one of those devices. In fact, on second thought, maybe I will get a Keepod after all... it would be rather handy to have my slides in a form I can access from an alternate computer in case this one unexpectedly dies on me at the conference... as long as my co-presenter can still access all of our code demos, of course.

12/22/2009

suggest Lotus Symphony and Domino Designer to Ninite

Category grassroots
Earlier today, Carl Tyler posted about Ninite, a single site to go to for downloading a bunch of applications at once. For example, when setting up a brand new machine, you could check off Firefox, Pidgin, VLC, GIMP, OpenOffice, AVG, 7-Zip, and so on, and then click "Get Installer" and get a single executable that installs everything you need except your fringe applications... for example, for many of you, that includes Domino Designer.

But Designer is now free. And Lotus Symphony has been since its original release. At the bottom of Ninite's home page, they include a form to "Suggest an app". I've already suggested both Designer and Symphony, and am requesting that all of you do the same. Not only would it be quite convenient for us to include those apps in a bulk install the next time we need to outfit a new machine, wouldn't it be great if all of Ninite's visitors saw free Lotus products, treated as true peers to software they've already heard of, offered in a context where those visitors don't have to click through 37 pages on IBM's site just to download the software?

12/13/2009

how to implement the Konami easter egg in JavaScript

Category javascript
Here's a little weekend fun: a while back, word started spreading that Facebook had added an easter egg based on the old Konami code:



Specifically, they added a lens flare effect that only shows up while scrolling, and only after the above keystrokes have been entered in sequence, followed by the Enter key. For those who don't know (and haven't already clicked the link above to find out), this sequence was often used in old Konami video games to unlock something magical (extra lives, invincibility, etc.), and was so widely known that it's wormed its way into numerous other facets of popular culture.

Enabling this in JavaScript is actually easier than you might expect. Here's one possible implementation approach you could add to your own script:

var konami = (function(){
 var sequence = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65, 13];
 var progressIndex = 0;
 var easterEgg = function(){
  /*
   * Replace with your own easter egg code:
   */

  alert("KONAMI'ED!!!");
 };
 return {
  interceptKey: function(thisEvent){
   var keyCode;
   if (window.event) {
    keyCode = thisEvent.keyCode;
   }
   else {
    if (thisEvent.which) {
     keyCode = thisEvent.which;
    }
   }
   if (keyCode == sequence[progressIndex]) {
    progressIndex++;
    if (progressIndex == sequence.length) {
     this.trigger();
    }
   }
   else {
    this.reset();
   }
  },
  reset: function(){
   progressIndex = 0;
  },
  trigger: function(){
   easterEgg();
   this.reset();
  }
 }
}());


Then just bind the interceptKey method to the onkeyup event of whatever element you want to contain the easter egg, e.g.:

<body onkeyup="konami.interceptKey(event)">


NOTE: In case it's not glaringly obvious, this only applies to client JavaScript. For all you XPagers out there, this wouldn't work as a server-side JavaScript function. Not only does SSJS not have a window object, the event model is entirely different from that of browser-based JavaScript.

12/04/2009

someday I will be this cool too

Category humor

Contact Me

Hire Me

What the Quote?

"They're all after me lucky charms."

Declan Sciolla-Lynch

"A computer lets you make more mistakes faster than any other invention in human history, with the possible exceptions of handguns and tequila."

Mitch Ratcliffe

"I think the air shark would be nice to us, 'cause we freed him from the burrito."

Tim Tripcony

Elsewhere

Assorted Linkage

Apparel

Lotus Rocks

I write the code that makes the young girls cry

ClustrMap