Tuesday, August 31, 2010

Trying out the Amazon Associates Program

As my book will be available for sale on Amazon soon (currently, you can only pre-order it), I have decided to try out their affiliates program. The idea is that I place an ad to a product on Amazon on my site, and I get some fraction of the sale, if one occurs. Although the concept is straightforward, setting up the ad is not.

Setting up the ad is awkward, as the HTML snippet I am instructed to embed is:
<a href="http://www.amazon.com/gp/product/1449381871?
ie=UTF8&tag=bolinfestcom-20&linkCode=as2&camp=1789&
creative=9325&creativeASIN=1449381871">
<img border="0" src="517mVDCbOtL._SL160_.jpg">
</a><img src="http://www.assoc-amazon.com/e/ir?
t=bolinfestcom-20&l=as2&o=1&a=1449381871"
width="1" height="1" border="0" alt=""
style="border:none !important; margin:0px !important;" />
As I have highlighted in red, the source of the first image is a relative URL. That means you have to host the image yourself in order for this to work. Amazon has instructions that tell you as much:

IMPORTANT: Save this image to your server, then cut and paste the HTML code in the lower left textbox into your web page.

But...why? I can think of three possible reasons:
  1. Amazon requires the image to be on a foreign server because they have some bizarre tracking JavaScript that requires it.
  2. Amazon is too cheap to host the image themselves.
  3. Amazon is being dumb.
Neither of the first two reasons make a lot of sense to me, so I'll have to assume it's the third. Having created embeddable advertising units for web pages and helped users set them up, I can say with certainty that this additional step will make embedding the ad substantially more difficult for the average web site owner.

(Another nit: one of the image tags is self-closing while the other is not. Is Amazon trying to embed HTML or XHTML? I don't really care which, I'd just like them to be consistent!)

The image that Amazon provided me with was small and grainy, so I decided to use a different book cover image that I cropped from O'Reilly's web site (that is why it still has the Rough Cuts branding on it). At 56K, I really need to use Pngcrush, but I'll save that task for another day. By changing the source of the image tag from 517mVDCbOtL._SL160_.jpg to http://plovr.com/cover.png and embedding the HTML, everything seems to work just fine.

Except...then I wanted to enable the fancy Product Previews feature that enables a user to mouse over the book cover to get a hovercard with more product details. I followed the instructions and added the script tag to enable Product Previews on my page:
  • On Firefox, the script works as intended.
  • On IE 8, the hovercard appears briefly, triggering the progress bar. Once the progress bar finishes loading, the hovercard disappears again.
  • On Webkit-based browsers (i.e., both Chrome and Safari), the hovercard appears, but it is empty. When I inspect it, the hovercard appears to contain an iframe with all of the appropriate content, except the CSS of the iframe is visibility:hidden, which is why nothing is displayed.
Also, the snippet of JavaScript that you are instructed to use is:
<script type="text/javascript" src="http://www.assoc-amazon.com/
s/link-enhancer?tag=bolinfestcom-20&o=1">
A blocking script tag? Gross! As Steve Souders explains on his blog, Google Analytics has gone async and so should you! I wrote some JavaScript that would load Amazon's JavaScript asynchronously, but that did not work because Amazon's script contains a call to document.write(), so it must be executed while the page is still being written.

For a company like Amazon, this is pretty pathetic. Again, they need to:
  1. Host the images for their products so the HTML snippet is easier to embed.
  2. Clean up the HTML snippet so it is consistent with its use of closing tags.
  3. Get a higher quality image for the cover of my book!
  4. Fix the JavaScript for the Product Previews feature so that it works on all modern browsers, including IE6 and later.
  5. Rewrite the Product Previews JavaScript so that it can be run after the page loads (i.e., so it does not depend on document.write()).
  6. Change the Product Previews snippet that users have to embed so that it loads the Product Previews JavaScript asynchronously.
This is fairly basic stuff that could easily help Amazon drive more traffic to their site. What are they waiting for?

Monday, August 9, 2010

plovr: Lowering the Barrier to Entry for Closure

In drafting Closure: The Definitive Guide, it became pretty obvious that it was not easy to get up and running with Closure. Currently, using the full suite of Closure Tools requires checking out three projects from code.google.com via Subversion, and a combination of Python and Java to compile JavaScript code.

Over the past month, I have been working on a build tool that integrates the Closure Compiler, Closure Library, and Closure Templates into a single download. It is named plovr, and can be downloaded as a single jar file that can be run with the JRE.

In creating plovr, I tried to address problems that frequently appeared in the discussion groups, such as:To this end, plovr can be run both as a server during development that dynamically recompiles Soy and JavaScript files when you reload a web application that depends on them. It can also be used as a command line build tool to generate compiled JavaScript. Because there are so many configurable options when using Closure, options are specified in a JSON config file rather than on the command line.

Like many open-source projects, the documentation is still under development, though hopefully it is enough to get you started. I am also reluctant to commit to official documentation before getting feedback from more developers, so please download it and try it out! I have found plovr to be particularly effective in facilitating my Closure development, but I would like to hear whether it is meeting your needs before I promote it from alpha to beta software.

And if you are planning on entering the contest to see what you can build with 1K of JavaScript, I strongly urge you to use plovr to help you stay under the 1K limit. I am planning to release a new feature of plovr in the next week or two that will expose more features of the Compiler that will help you minify your code for the contest. Stay tuned!

Wednesday, July 14, 2010

Manuscript Submitted!

On Monday, I submitted my manuscript for Closure: The Definitive Guide to O'Reilly for copyedit review. The past two months of revisions were extremely stressful, so I can't even begin to describe what a huge relief hitting that milestone has been for me. Honestly, I thought the draft was in reasonable shape when I finished it back in May, so I ended up doing a lot more work than I expected to get it into a state suitable for submitting for copyedit.

Nevertheless, I am really excited with how much better the book has gotten in the past two months (it's probably one Amazon star better than it was before), though what is even more exciting is that I am already able to share the latest version with you via O'Reilly's Rough Cuts program. What I submitted for copyedit on Monday was just made available on Rough Cuts today! (Apparently you can see the Table of Contents and read the Foreword and Preface without paying for the book.)

Since the last update to Rough Cuts (mind you, that is when I thought I had a complete first draft), I have added an additional 91 pages for a whopping total of 546 pages. The following are some of the new sections that were added:

  • Detailed example of dividing compiled code into modules and loading them with the Closure Library (appears in Chapter 12).
  • Rewrite of the complex component example at the end of end of Chapter 8.
  • More hidden options in Chapter 14, which has been renamed to "Inside the Compiler."
  • An explanation of goog.events.KeyHandler in Chapter 6.
  • A section on goog.Uri in Chapter 7.
  • A section on mock objects in Chapter 15.
  • A new appendix on plovr (appears as Appendix C).
  • Acknowledgments in the Preface.
As part of the revising process, I (with the help of contributing author, Julie Parent) responded to all 100+ comments made on the Rough Cuts web site, which were a big help in improving the quality of the draft. Thank you so much to everyone who contributed so far! (Special thanks to Derek Slager, who filed the overwhelming majority of the corrections.) As the manuscript has not been finalized yet, you can still submit feedback now to help improve the final version of the book, so don't be shy!

For the next month or so, the manuscript will bounce back and forth between O'Reilly and me. According to Amazon, my book will be out on September 15, 2010, though I think that may be a little optimistic. Fortunately, the beauty of Rough Cuts is that you don't have to wait until the fall to get the help you need with Closure today!

Saturday, May 15, 2010

All Chapters Drafted!

This past week, I published a new update to my book-in-progress, Closure: The Definitive Guide. This update includes new chapters on the Closure Inspector and Closure Templates, which means that now every chapter has been drafted, so if you have been holding off on subscribing to the book because you thought the Rough Cut was "too rough," now you no longer have an excuse!

Though there are admittedly some sections that are still marked TODO, such as the section on "mocks" in Chapter 15 on the Testing Framework. There are also some sections that are mentioned in the text but lack a reference because they have not been drafted yet, such as the one on creating multiple modules with the Compiler and understanding line joining in Closure Templates. (Though the latter is explained in the online documentation.) Although I have my own punch list of things to add, please feel free to add comments on the Safari books page, as the feedback I have gotten there so far has already proved useful!

Also, if you have been following along with my page count graph, you will notice that things have flattened out lately:



There is also a striking difference of the slope of the lines in the blue and white sections, though what you may find even more curious is the discontinuity in the blue section. That's because I decided to try working in finance, and after seven weeks, I decided that it wasn't for me. It was actually a great company with incredibly sharp people, but I just couldn't get excited about the problems there as I could for the ones in building Web applications.

I got a new job at Yext, which is a much better fit for me. I realize the home page of Yext does not look like much, but I think that this TechCrunch article tells the story better than I can.

Fortunately, Yext has been very supportive of my book, so I was able to take a bit of time before starting to focus on writing, and as you can see from the graph, it has really paid off! Clearly, working at a startup has slowed my rate of progress, but it has given me more experience training engineers (who have never worked at Google) how to use Closure, so I think The Definitive Guide will be a better book in the long run because of it.

Although now that I'm about to enter the revising stage, I think a real sign of progress will be when the line on the graph starts to go down, because as Blaise Pascal (apparently not Mark Twain) said: "I have only made this [letter] longer, because I have not had the time to make it shorter."

Sunday, March 21, 2010

I'm a Golden Plover!


Today's update to the Rough Cut is particularly momentous as it features the cover of my book for the first time: the mysterious cover-choosing-cabal over at O'Reilly has chosen a golden plover as my animal, and I could not be more excited! (Contrary to popular belief, no, you do not get to pick your own animal.)

Although the Rhino has long been an icon of JavaScript books from O'Reilly, some of the more recent releases appear to be birds, so I'm thrilled to be part of that group.

The latest installment to the Rough Cut are the chapters on Client-Server Communication (20pp) and User Interface Components (50pp), which are core modules to the Closure Library, so I'm sure that this new information will be of great use to Closure neophytes (and likely some veterans, as well.)

Over the weekend, I finished drafting the chapter on Working with the Compiler Source Code. I am quite happy with the code samples that I came up with, and I hope they encourage JavaScript developers to start thinking about more innovative uses of the Compiler. Also, guest author Julie Parent has been hard at work on a chapter on goog.editor, the rich text editor widget in the Closure Library that seems to be a popular topic in the discussion group. Hopefully both of those chapters will also hit the Rough Cut in the next few weeks.

This means that 12 of the 16 chapters have been drafted, and the topics for the remaining four chapters are not as complex as those of the existing chapters, so the end is in sight! My current estimate for the final page count for the book is between 450-500 pages, which is nearly twice as long as I originally anticipated. I'm doing my best to put the Definitive in Closure: The Definitive Guide!

Friday, March 5, 2010

toString() Might Not Return a String

I was reading NCZ's JavaScript quiz, and it occurred to me that toString() is not guaranteed to return a string because it is, after all, just a method. Try to guess what is printed to the console when the following JavaScript is executed:
var obj = {
nine: 9,
toString: function() {
return this.nine;
},
valueOf: function() {
return 10;
}
};

console.log(obj.toString() === '9');
console.log('' + obj === '9');
console.log('' + obj.toString() === '9');
console.log(obj + obj);
console.log(String(obj) === '9');
Because obj.toString() returns a number, not a string, obj.toString() is the number 9, not the string '9', so the first expression is false.

In the second example, I would expect that because '' is a string, the value on the right of the + would also be coerced to a string via its toString() method, which means the result would be '9'. But I am wrong! It turns out that valueOf takes precedence, so '' + obj evaluates to '10', which means '' + obj === '9' is false. It would be true if there were no valueOf method defined on obj, though.

Because toString() is called explicitly in the third example, '' + obj.toString() becomes '' + 9, which evaluates to '9', so the expression is true.

The fourth one is interesting because '99', 18, and 20 are all reasonable guesses, but it turns out that valueOf() takes precedence again, so this evaluates to 20. If there were no valueOf() method defined on obj, then the result would be 18.

In the final example, String() is used as a function (and not as a constructor function, which you should never do!), and it does, in fact, return a string, so String(obj) === '9' evaluates to true. I always assumed that the implementation of String was something like:
function(s) {
return '' + s.toString();
};
Though a few years back, I discovered that alert.toString() throws an exception on IE6 (also alert.toString evaluates to undefined on IE6), but '' + alert and String(alert) return 'function alert() { [native code] }', as expected. At least in that case, my proposed implementation for String() would not work, though IE6 has been known to be nonstandard and buggy...

Monday, March 1, 2010

Update to Closure: The Definitive Guide

Today I'm excited to announce a significant update to Closure: The Definitive Guide. The book contains complete drafts of two new chapters that focus on the Closure Compiler: Using the Compiler and Advanced Compilation. These two chapters contribute 80 pages of new content in addition to the 167 pages that are already available.

Because I was curious, I also created a graph of my progress on the book that is automatically updated every six hours:



When I put together the original proposal for the book, I projected that it would only be 250 pages long. Clearly, that was an underestimate. This presents quite the opportunity for you, the reader, since I'd argue that the book is now underpriced as you can preorder the print version for only $25.99. For only $14 more, you can also get online and PDF access to the book today. If you do, I strongly encourage you to provide feedback on O'Reilly's web site. Remember, the book is still in draft form, so if you have suggestions on how the book could be improved, make them now so they can be included in the final version!