Monthly Archive for August, 2008

Open or Create a file in Terminal to Coda

I have recently started using Coda by Panic (the people who make Transmit). I have to say I really like it. I have been a die hard BBEdit fan for years and was hesitant to make the switch. However, a co-worker was talking up Coda and mentioned that it had auto-complete – a feature that has been sorely lacking from BBEdit.

The switch turned out to be fairly painless. One feature that I really missed from BBEdit was the ability to create or open files from the command line simply by invoking the following

$: bbedit -c myFileToOpen

Sadly, Coda didn’t appear to have the same functionality. I contacted the Coda team, they liked the idea and planned to look into it, but I am way too impatient to wait. In the meantime, I decided to write my own little bash script that I named ‘coda’

#! /bin/bash 
if [ "$1" = "" ]; then
	echo "Please specify a file to open or create"
	exit 0
else
	for ARG in $*
		do
    	            touch -a $ARG && open -a Coda $ARG 
		done
	exit 0
fi

By using touch, I am able to create a file if it doesn’t exist. I pass the ‘a’ argument, but not the ‘m’ argument so the timestamp doesn’t change for already existing files. After touch works its magic, the open command opens the file in Coda. I am running a for loop over the list of arguments in order to allow a list of files or a wildcard as well as a single file to be passed into the script. Sweetness! I threw this little script in my bin folder and set it to executable using chmod +x. Using the script looks like this

$: coda myFileToOpenOrCreate
$: coda *.txt

Daffodil Shop Launches

For almost a year now I have been speaking with my godmother about doing a website where she can sell her crafts. And I happy to announce the site launched on Sunday. Check out daffodilshop.com.

We have yet to really drive any traffic into the site, but I think it turned out well. The site uses a great Wordpress plugin I found called WP e-Commerce. It integrates with Google Checkout as well as PayPal, making the job a snap.

Digg Widget, A Lightweight, DOM Friendly JavaScript Alternative

The website I have been working with, Asylum.com, recently expressed interest in adding a Digg Most Popular widget to their site. Asylum.com asked me to apply some CSS to resolve the display issues they were having. After I spent a little while investigating the HTML markup in the standard Digg widget, I decided it wouldn’t be in Asylum’s best interest to use it in it’s current form.

While the widget is well done, it used a few techniques that are frowned upon at AOL. The most disconcerting issue was the use of document.write(). If you are familiar with JavaScript, then you are aware that document.write() causes issues on a few levels. First off, document.write() blocks while it is working. This blocking prevents other items on the page, such as CSS or images, from loading while the write occurs. Additionally, elements and text created via document.write() are not added to the DOM ( Document Object Model ) and cannot be manipulated in the same way. I envisioned code that was more friendly to both the page load and the DOM.

In addition to document.write(), the Digg Widget was calling in the entire jQuery framework. This seemed like overkill. I didn’t want to include an entire library just to create this widget.

The Digg API lives on the Digg server, I couldn’t use classic Ajax because of the same origin policy. However, Digg provides JSONP (JavaScript Object Notation with Padding). This allows you to wrap the JSON with a callback function that will be executed once the script loads. To use JSONP, you have to dynamically create a script tag and assign the Digg API url to the src attribute. Most modern browsers support dynamic creation of script tags, it would look as follows.

var s = document.createElement( "script" );
s.setAttribute('src', apiURLAndArguements );
s.setAttribute( 'type', 'text/javascript' );
var h = document.getElementsByTagName( 'head' );
h[0].appendChild( s );

The Asylum team asked that the Digg widget have both the most popular articles and the upcoming articles contained within the widget. Since I didn’t want to write the same code twice, I sought an Object Oriented, self-contained widget that could use the same JavaScript blueprint to use both calls.

The biggest obstacle to creating this was JavaScript scope. If I instantiated an object to contain the Digg data, I would lose scope the moment the callback function was triggered. The callback would be called in the scope of the window and not the scope of the object that first created the script tag.

The Digg API further complicated this because it does not allow periods, square brackets or curly brackets in the name of the callback function. I spent some time researching JavaScript inheritance and closures hoping they would provide the resolution I needed.

In the end, I used a combination of JavaScript closure and JavaScript function pointers to provide the solution. The key lay within providing the callback function a correlation to the original object. Since Digg doesn’t allow periods and square brackets in the name of the callback function, I couldn’t create a simple global array with a reference to the object. Instead, I had to generate a function name appended with a random string that would live in the global scope. The function interior would look as follows.

var method = this; // a reference to the calling object
function wrapperFunc( obj )
{
    method.returnDataHandler( obj ); // the function to be triggered within the original calling function
}
var rand = Math.ceil( Math.random() * 100000000000 );
window['DiggAsylumCallback' + rand] = wrapperFunc; // store this pointer in the global scope
var urlBase = "http://digg.com/tools/services?type=javascript&callback=DiggAsylumCallback"+rand+"&endPoint="+ finalEndPoint +"&domain="+ yourDomain +"&sort=digg_count-desc&count=" + numberDisplayed
return urlBase;

Once the callback function triggers, it stores the JSON inside the original calling function and the prototype methods can be called in the correct scope. Here is a look at how the object is triggered.

var popular = new diggAsylum( 5, "asylum.com", "/stories/popular", "diggDivId", true, "desc" );

The diggAsylum constructor signature looks as follows.

function diggAsylum( count, domain, endPoint, htmlId, showDesc, sortType ) { .... }

Get the complete JavaScript file here, see it in action here, get a zip file of the CSS, JS and HTML here.