Saturday, July 19, 2008

Side Notes

I tend to go off on tangents when making a point. In fact, there's already a trend emerging in the blog where I insert "side notes" into a train of thought. In retrospect, the tangents are informative and somewhat related to the topic at hand but as a default styled paragraph, it forces itself upon the reader and can wind up derailing them from the main topic. For example:

And now, I said, let me show in a figure how far our nature is enlightened or unenlightened: Behold! human beings living in an underground den, which has a mouth open toward the light and reaching all along the den; here they have been from their childhood, and have their legs and necks chained so that they cannot move, and can only see before them, being prevented by the chains from turning round their heads.

Side note: Speaking of topic, I like meat. Meat meat meat meat meat meat meat meat meat meat meat meat. Meat.

Above and behind them a fire is blazing at a distance, and between the fire and the prisoners there is a raised way; and you will see, if you look, a low wall built along the way, like the screen which marionette players have in front of them, over which they show the puppets.

What to do? Add a class to the "side notes" <p> tag and add a CSS rule to break out the text!

Here's the <p> tag with the new sidenote class:

<p class="sidenote">

Now the rule that will style this special paragraph:

.post p.sidenote {
    background-color: #eee;
    border: 1px dotted black;
    float: right;
    font-size: 0.9em;
    margin: 10px 0px 25px 10px;
    padding: 10px 10px 10px 10px;
    width: 250px;
    font-family: Tahoma;
    font-style: italic;
}

To prevent the "side note" from overlapping any formatted source sections, the prettyprint CSS class also needed an additional attribute:

.post-body pre.prettyprint {
    background-color:#FBFBFB;
    border:1px dotted #888888;
    margin-left:2em;
    margin-right:2em;
    padding-left:5px;
    clear:both;
}

This format allows the user to continue reading the main topic and then return to the easily identifiable "side notes" when they are ready to do so:

And now, I said, let me show in a figure how far our nature is enlightened or unenlightened: Behold! human beings living in an underground den, which has a mouth open toward the light and reaching all along the den; here they have been from their childhood, and have their legs and necks chained so that they cannot move, and can only see before them, being prevented by the chains from turning round their heads.

Side note: Speaking of topic, I like meat. Meat meat meat meat meat meat meat meat meat meat meat meat. Meat.

Above and behind them a fire is blazing at a distance, and between the fire and the prisoners there is a raised way; and you will see, if you look, a low wall built along the way, like the screen which marionette players have in front of them, over which they show the puppets.

Now I can start side conversations and follow tangents to my mind's content without utterly frustrating or losing the reader!

AdBlockCheck

As mentioned in this post, AdBlock Plus did its job and blocked the AdSense and QuickAds code that was placed on this blog. The incident reminded me how it is easy to forget that AdBlock is installed because it works so well. It also got me thinking about ways to politely remind people that the ads on this blog are being blocked. Why remind readers? When I remember to, I disable AdBlock on sites that I frequent in order to support those sites. I’m betting others out there feel the same way and that, like me, they tend to forget that ads on a site are being blocked.

Let’s be clear: I have no issue with people blocking ads; the ads are not something the viewer is interested in so why waste the bandwidth and annoy the readers that don’t want them? Hell, I run AdBlock and Squid with content filtering on my home network.

Side note: It’s perplexing to me why spammers are against some form of a spam “no-call” list (see: now defunct Blue Frog project by Blue Securities), which would save them time and money by not wasting resources sending spam to addresses that would never generate revenue. It might even let spammers keep their open relays and ISP accounts alive longer since it’s likely fewer people would spend the time to complain or report them.

Problem Definition

There needs to be a way to remind people that they have ad blocking software running and ask that if they enjoy the content to please allow ads to display on this site. Whatever means this is accomplished through, the requirements are:

  1. Determine that ads are being blocked
  2. Remind the user that they are blocking ads on the site
  3. Only target people who are interested in the content
  4. Humanize the site/content (remind readers that a person sits behind these pages)
  5. Not be intrusive or annoying
  6. Not be blockable by ad blocking software
  7. Not obscure or prevent access to the content in any way

Side note: I consider obscuring or making the content inaccessible a very bad idea. I typically open a large set of pages in tabs before going to and leaving from work so that I have something to read on the train. There’s nothing more frustrating than running into a tab with the “Server Not Found” message. 90% of the time this is due to scripts that periodically reload the page or redirect to a “please subscribe!” page after a delay; something that fails when the computer is off-line. I’ve even had it occur while I was reading the page on the train. Please, if you have a site, try to be aware of the different ways in which your viewers may consume your content! Not everyone is online all the time or has a high-speed connection to download your heavy (but oh so beautiful!) pages.

The Solution

Determining if a browser is running ad blocking software is the easiest part. AdSense and QuickAds work by including a JavaScript library in a page. When this library gets loaded it inserts <iframe> tags wherever ads are supposed to show. Ad blocking software typically works by looking at the URLs the browser intends to load and cancels those URLs that match a filter. When an ad blocker sees the library URL for AdSense or QuickAds it prevents the loading of the library, which means that the <iframe> tags for ads will never get inserted into the page.

Checking for the existence of the <iframe> tags will let us know if the ads on a page have been blocked. The <iframe> tag for AdSense looks like this:

<iframe name="google_ads_frame" ...>

QuickAds looks very similar:

<iframe id="scribefire_ad_frame" ...>

Thanks to jQuery this <iframe> check is very simple:

if (($("iframe[name = 'google_ads_frame']").length > 0)
  &&
  ($("iframe[id = 'scribefire_ad_frame']").length > 0)) {
  return;
}

Requirement #1: Complete!

For messaging the user I settled on a modal dialog box. After much searching I could not find a jQuery plugin that had the aesthetics and behavior I was looking for. Casting a wider net, I did find a nice looking set of dialogs but the accompanying JavaScript left something to be desired. Here’s an example of the slick looking originals:

Starting with this dialog box design, I set about rewriting the behavior using jQuery and then wrapped it all up into a jQuery plugin (jquery.modaldialog.js), which has been registered in the jQuery plugin respository. The CSS was also redone so that the dialog width can be configured, the height will adjust to the content inside it, and the background mask and dialog will appear on-screen no matter where the page has been scrolled to. An optional close button was added to the bottom of the dialog body (with plans to add a more complete set of OK/Cancel/Yes/No button options and event hooks in the near future). This takes care of requirement #7 and most of #2.

To complete requirement #2 (remind the user), we need to have a message to display. Thanks to the nice jQuery plugin we now have, this is another simple task:

$.modaldialog.prompt(
  "<p>You've been on this page for a while now so you're either reading the post or maybe just off peeing or getting something to drink.</p>" +
    "<p>I also noticed you're blocking ads. Don't worry, I use AdBlock Plus too! But I do enable ads for sites I like (when I remember to).</p>" +
    "<p>This is just a personal request that if you like what you're reading, please consider allowing ads for this website. At the very least subscribe to the RSS feed!</p>" +
    "<p>Thanks,<br/><img src='http://static.transisted.com/img/chris_sig_sm.gif' style='margin-top:6px; margin-bottom:2px; vertical-align:bottom;' /> (Chris)</p>" +
    "<p><i>ps - You won't see this message again...</i></p>"
  , { title: 'A Friendly Reminder' }
);

Here’s what the final product looks like:

By signing my name at the bottom and including my signature I’m hoping to associate this content in the reader’s minds with a real, live person. I am, after all a real, thinking thing just as you, the reader, are (well, I assume; leave some comments or feedback to help convince me!). We can check off requirement #4 as well now.

Now that there is something to show to the readers, some rules are needed to determine when to show it. To start off simple, I’ve set this message on a timer so that it shows after 1’10”. This is long enough that it should only hit people who are actually reading the content. The timer delay is a one-liner thanks to jQuery:

$().ready(function () { setTimeout("checkAdBlocking()", 70 * 1000); });

Down goes requirement #3 (only target those interested in the content)! It also happens to address part of requirement #5 (don’t be intrusive or annoying). The other part is the setting of a cookie so that readers don’t get pounded with this message every time they read an article. Instead, they see the message only one a week/month/year, depending ont he cookie expiration date. jQuery has a cookie plugin (jquery.cookie.js) that makes quick work of getting and setting cookies. Setting the cookie is done like so:

$.cookie('adblock', '1', { expires: 30, path: '/', domain: '.transisted.com' });

Checking for the cookie is just as easy:

if ($.cookie('adblock'))
  return;

Now to wrap this all up into a set of JavaScript functions:

function showAdBlockMsg () {
  $.modaldialog.prompt(
    "<p>You've been on this page for a while now so you're either reading the post or maybe just off peeing or getting something to drink.</p>" +
      "<p>I also noticed you're blocking ads. Don't worry, I use AdBlock Plus too! But I do enable ads for sites I like (when I remember to).</p>" +
      "<p>This is just a personal request that if you like what you're reading, please consider allowing ads for this website. At the very least subscribe to the RSS feed!</p>" +
      "<p>Thanks,<br/><img src='http://static.transisted.com/img/chris_sig_sm.gif' style='margin-top:6px; margin-bottom:2px; vertical-align:bottom;' /> (Chris)</p>" +
      "<p><i>ps - You won't see this message again...</i></p>"
    , { title: 'A Friendly Reminder' }
    );
}
function checkAdBlocking () {
  if ($.cookie('adblock'))
    return;

  if (($("iframe[name = 'google_ads_frame']").length > 0)
    &&
    ($("iframe[id = 'scribefire_ad_frame']").length > 0)) {
    return;
  }

  showAdBlockMsg();

  $.cookie('adblock', '1', { expires: 7, path: '/', domain: '.transisted.com' });
}
$().ready(function () { setTimeout("checkAdBlocking()", 70 * 1000); });

End Result

To see the live dialog, click here

Example #1: Error dialog

Example #2: Warning dialog

Example #3: Success dialog

Example #4: Prompt dialog

Friday, July 18, 2008

Moving to jQuery

In order to do some of the blog styling and the planned interactive stuff, a DHTML/AJAX library was really required. I've used many (custom, Prototype, Scriptaculous, MooTools, Ext2, YUI, etc.) but the current personal favorite is jQuery. It is clean, concise, and well supported (with many plugins, which will be explored in a later post). There's not much to say about hooking up jQuery except that it is being served by Google's AJAX Libraries API instead of the usual static.transisted.com. The inclusion was done using a <script> tag inside the <head> tag:

<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js' type='text/javascript'/>

Now that jQuery was in place, the call to the Google Code Prettify source code formatter could be redone. The prettyPrint() call was moved into the jQuery window onload event handler with the following bit of JavaScript inside the <head> tag:

<script language='JavaScript' type='text/javascript'>
  $().ready(function () {
    prettyPrint();
  });
</script>

Not exactly sexy but it does pave the way for doing lots of interesting things.

Thursday, July 17, 2008

AdSense and QuickAds!

There are a few ways to generate revenue from a site:

  1. Sell advertising
  2. Ask people to donate/subscribe
  3. Sell merchandise

This site will start off trying advertising through different ad networks and perhaps try the other options at a later date. Now, it might appear that Google's AdSense network is the only game in town but that is definitely not the case. There are Kontera, Advertising.com, CPX Interactive, Specific Media, and Vibrant Media (those annoying "Intellitxt" link mouseover popups) to name a few. There's also a new player on the scene called ScribeFire that is offering the QuickAds system, which aggregates many advertising networks and dynamically selects the most profitable ads to display on a site. I decided to try two systems, one that's proven but conservative in revenue earning potential (AdSense) and one that is new and unproven but with a higher earning potential (QuickAds).

Signing Up

Not much to say here, really. Both AdSense and QuickAds have a similar, simple signup process and then a period of waiting for account approval. AdSense took roughly four days to get approved while QuickAds took about a day.

Placing Ads on the Blog

Once accounts with the ad networks are confirmed, the next step is getting the ads hooked into the blog.

AdSense

Google owns both AdSense and Blogger.com and has done a good job of integrating AdSense placement into the blog control panel. In the layout editor, one can simply click to add a new element to the page:

Blogger Layout Editor: adding a new element to the page

Editing an ad's size and color scheme is just as simple:

Blogger Layout Editor: editing an adsense size and color scheme

QuickAds

ScribeFire maintains a Firefox blog editor extension named ScribeFire (previous known as Performancing). Integrated into this blog editor is a tab for managing a QuickAds account and the ads that display on a website. Just like Blogger.com/AdSense, placing ads on the blog is as simple and point and click. Unlike Blogger.com/AdSense, ScribeFire supports over a dozen blog services and platforms. Here you can see a new horizontal ad being placed below the blog's header:

ScribeFire Editor: adding a new ad to the page

At first, there was a problem getting ads inserted using the ScribeFire editor because of the custom domain that Transitech uses: the editor would not recognize feed.transisted.com as a valid URL for the blog and it prevented ads from being added to the blog. A bug report was filed and almost right away there was a reply from one of the developers with a fixed version of the extension. An unexpectedly pleasant experience, overall.

Note: while placing the ads I ran into the perplexing problem of no ads actually appearing. I thought that perhaps something was set up incorrectly or my accounts weren't fully ready yet. Then, I noticed the little ABP icon in the Firefox toolbar! I use AdBlock Plus, a Firefox extension that filters out advertising content to speed up the web browsing and remove those ridiculously annoying popups and text link mouseovers (*cough* Intellitxt *cough*). Adding an exception to the ABP filters for feed.transisted.com fixed the problem. The incident got me thinking about what to do with readers that also block ads. I think I came up with a good solution that is already implemented on the blog and will be covered in another post shortly.

Which is better?

AdSense has many ad sizes to choose from (24, actually) and their appearance is low-profile and non-intrusive. QuickAds has only three(!) ad sizes (vertical, horizontal, and box) and a very limited set of color scheme options. Some of the QuickAds ads also appear to be eye catching gouging flash pieces that don't exactly blend with the pages. To be fair, QuickAds has to work with various ad networks and their varying ad sizes so they probably had to target the lowest common denominator.

Inserting ads into the blog was easy with both systems so real litmus test will be which produces more revenue over time. The two systems remind of the two ends of the investment spectrum. On one end there is the more conservative system (AdSense) with the predictable, lower revenue and on the other end is the riskier, unproven system (QuickAds) with a much higher yield potential.

Making the Blog Mine

Have you ever been reading a good article only to realize you’ve already seen other good articles from the same site? If you’re like me you probably bookmarked the site or subscribed to the RSS feed. Making a blog/site stand out from all the crap is as much about the look and presentation as it is about the content. Avoiding the stock templates and default colors will help make a site easily recognizable and, therefore, stick out in readers’ memories.

Sites using stock templates usually lack a feeling of authenticity or legitimacy (permanency?) that one gets with a site that has obviously had some time, thought, and effort put into its design. Reader’s might wonder how serious or committed an author is if they can’t be bothered to spend time on the appearance of their site. Is it fair? No. But never underestimate the effect emotional response has on the decisions of otherwise rational people.

This article will cover a few ways in which one can make their site/blog a little less “stock”, starting with…

Favorite Icon

The favorite icon is a special image on a website that browsers will use when displaying references to that site (location/URL bar, bookmarks, desktop shortcuts, browser history, etc.). Think of it as a form of “branding” that makes your content easily identifiable in a browser’s bookmarks and history. This favorite icon is an image file typically located in the root of a website (/favicon.ico) but the browser can be told to look for this file in an alternate location by placing a special <link> tag inside the <head> tag:

<link href='http://static.transisted.com/img/favicon.ico' rel='shortcut icon'/>

Once an image was chosen (my Transisted logo) and converted to the ICO format, it was uploaded to static.transisted.com (in the /img/ folder, of course), and the site now had it very own favorite icon!

Side note: the favicon.ico image is not a GIF or JPG format so one needs to have a program that can save to the ICO format. Fortunately, the folks at Dynamic Drive have provided the world, free of charge, with the easy to use Favorite Icon Generator. Simply choose an image you’d like to use (think: logo) and click the button. Out comes your hot new favorite icon!

Background Image

The Minima Stretch template is nice and plain. Too plain, in fact. In order to give the page some “texture” a background image was added to the body tag. Don’t get me wrong, a clean layout with sufficient whitespace is a good thing because a busy page makes reading a difficult task but that’s doesn’t mean a site has sport a clinical look.

For the background, the good, old Transisted logo was used again to begin establishing a single recognizable image to associated the site with. The logo was set to ~25% in Photoshop so that it wouldn’t interfere with content on the page and then uploaded to the /img/ folder on static.transisted.com. Getting the image to show in the background amounted to a little tweak to the CSS rule for the <body> tag. Here's the rule as it is now with the added background attributes in bold:

body {
    background:$bgcolor url('http://static.transisted.com/img/logo_med.gif') no-repeat scroll 120% -235px;
    margin:0;
    color:$textcolor;
    font:x-small Georgia Serif;
    font-size/* */:/**/small;
    font-size: /**/small;
    text-align: center;
}

Nothing spectacular but little by little, the blog starts to differentiate.

Block Quotes

I ran across a nice styling of the <blockquote> tag in the template TicTac Blue while trying out different stock templates. Even though Minima Stretch was the final choice for the blog the block quote style still found its way into the blog. First, the CSS rule for the <blockquote> tag was lifted from the TicTac Blue template and copied to this blog's. Here's the rule:

blockquote {
    margin: 0 0 0 30px;
    padding: 10px 0 0 20px;
    font-size: 88%;
    line-height: 1.5em;
    color: #666;
    background: url(http://www.blogblog.com/tictac_blue/quotes.gif) no-repeat top left;
}

Notice how the image URL in the rule is to some other server? This image was copied and uploaded to the /img/ folder of static.transisted.com so that the image is being hosted on our dime and not someone else's. Without any changes to the <blockquote> tag, here's what it looks like:

Cowardice asks the question, 'Is it safe?' Expediency asks the question, 'Is it politic?' But conscience asks the question, 'Is it right?' And there comes a time when one must take a position that is neither safe, nor politic, nor popular but because conscience tells one it is right. - Martin Luther King jr.

The quote text needed to stand out from the regular content more so some tweaking was in order. This came in the form of some indentation and moving the quote text a little below and the to the right of the quote image:

.post-body blockquote {
    background: transparent url('http://static.transisted.com/img/quotes.gif') no-repeat scroll left top;
color:#666666; font-size:110%; line-height:1.5em; margin:-2pt 0pt 0pt 5px; padding:19px 0px 10px 32px; }

Here's the final result:

I am therefore, precisely speaking, only a thinking thing, that is, a mind (mens sive animus), understanding, or reason, terms whose signification was before unknown to me. I am, however, a real thing, and really existent; but what thing? The answer was, a thinking thing. - Rene Descartes

Tweaking Code Prettify

Finally, there are some changes to the source code formatting. Looking back on the last article, it became obvious that the source code blocks needed to stand apart from the article text more. This, again, was a trivial tweak to the template CSS. A rule was added that targets <pre> tags that have the class prettyprint. The post-body class was also added to the selector to make the rule more specific than the rule defined in prettify.css (rule styles are only applied if they have a more specific selector than a previous rule that matched an element). Here's the CSS rule as formatted source code so you can see what the rule style looks like:

.post-body pre.prettyprint {
    background-color:#FBFBFB;
    border:1px dotted #888888;
    margin-left:2em;
    margin-right:2em;
    padding-left:5px;
}

There's a lot more that had been identified for styling but overdoing a design (this holds true for software too) is usually worse than being conservative or even downright minimalistic. Anymore changes will need to have a good reason behind them before getting applied.

Next up will probably be advertising. The Google AdSense account was finally approved and at almost the same time I got an invite to ScribeFire's QuickAds system!

Tuesday, July 8, 2008

Source Code Formatting

While writing an article describing how to change the blog appearance through editing of the template CSS, a small problem became apparent: there's no good way to display formatted code snippets with the default Blogger editor (or external editors for that matter). Luckily this problem had been encountered before when setting up a WordPress installation and there were two fantastic solutions that turned up.

GeSHi
This library parses source code and outputs HTML, producing colored, formatted code with line numbers. It's written in PHP, which makes for a nice fit with WordPress, which was also authored in PHP.

Google Code Prettify
This is a JavaScript library that also parses, formats, and colors source code. It doesn't support as many languages as GeSHi but it does cover the more common ones and since it's JavaScript the rendering is done client side.

Blogger is hosted by Google, which means there is no way to hook GeSHi into the server side article rendering. This left Code Prettify as the only choice for code formatting on this blog.

Side note: The Code Prettifier is an actual lexer/parser written in JavaScript. While working on TripDub, one of my FireFox plugins (embedded, threaded web server implemented in JavaScript as XPCom components), I was looking into repurposing Code Prettifier for translating other languages, such as PHP, into JavaScript. That was until I ran across JS/CC, a parser and lexical analyzer generator written in JavaScript! It uses a BNF-ish grammar spec to generate a JavaScript library that can parse and execute another language. Stay tuned, I'll be covering both JS/CC and TripDub in future posts.

Hooking In Code Prettify

The first thing to do is download the latest release, unpack it, and upload it to the static content server. The files on static.transisted.com are organized by a simple directory hierarchy starting with the top-level folders /img/, /css/, and /js/. It's not that useful right now but as more content is added it will become essential to keeping that content maintainable. So now there are two new files on the server:

  • /css/prettify.css
  • /js/prettify.js

Next, these two files need to be referenced in the blog template. This is done by adding the following two lines inside the <head> tag:

<link href='http://static.transisted.com/css/prettify.css' rel='stylesheet' type='text/css'/>
<script src='http://static.transisted.com/js/prettify.js' type='text/javascript'/>

There is a function in prettify.js named prettyPrint() that scans for code sections to "prettify". This needs to be called after any code to be formatted so the best place to add it is just before the close body tag </body>:

  <script langauge='JavaScript' type='text/javascript'>
    prettyPrint();
  </script>
</body>

Side note: Google provides a service called AJAX Libraries API that provides distributed hosting for a number of popular JavaScript libraries such as jQuery and Prototype. While Code Prettifier is a Google product, it is not available through this service (yet?). So hosting of the code has to be handled through static.transisted.com.

The other option is to call prettyPrint() in the body onload event handler but assigning actions to the onload event can wait until jQuery is hooked into the blog (to avoid clobbering any handler that might already be assigned to the event).

Finally, we need some code to format! To get Code Prettify to see the source code it must be put inside a <pre> or <code> tag and have the CSS class prettyprint. For example, this CSS:

<pre class="prettyprint">
  #header {
    margin: 5px 5px 0;
    padding: 15px 20px .25em;
    line-height: 1.2em;
    text-transform: uppercase;
  }
</pre>

then becomes:

#header {
  margin: 5px 5px 0;
  padding: 15px 20px .25em;
  line-height: 1.2em;
  text-transform: uppercase;
}

Here's some perl:

#!/usr/bin/perl -w
use strict;
use LWP::Simple;
use Mail::Sendmail;

my $email = 'test@example.com';
my $sleep = 15;

And here's C#:

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace CDub.LogicEngine {
  public class Engine {
    protected string _id;
  }
}

Pretty simple, no?

Hosting Additional Content

Now that there are images and JavaScript that need to be referenced in the blog pages there needs to be somewhere to host the content. Yes, there is the integrated Flickr hosting but that will only cover images. This was easily solved by creating the hosted subdomain static.transisted.com under my DreamHost account.

This content can now be referenced from the content server like so:

<link href='http://static.transisted.com/img/favicon.ico' rel='shortcut icon'/>

That's it!