About Us

Bulletpoint StarImulus® is a technology focused design + interactive agency.

In addition to our client services we also have a few products in the works. Our office is always filled with chatter and this blog is an outlet for our creative energy, rants and ideas.

Podium

Stacks!
Imulus built a task management solution that finally works for teams. It's a life saver, learn more at usestacks.com.

Featured Project

Category: web development

Sep21

ClickTime API Wrappers for Ruby and JavaScript

For a few internal projects at the Imulus office, we’ve been collecting timesheet data from the tracking software we use, ClickTime. Lucky for us, they offer an API with full access to all of our data. Unfortunately, however, it’s a SOAP API.

SOAP can be a bear, so we’ve rolled some code to help alleviate the pain of working with it:
a Ruby wrapper and a JavaScript wrapper. Both are open source, and we hope they make your life easier. Below are some examples of how to use them.

Ruby

The Ruby wrapper (ruby-clicktime) comes in the form of a single file with one class, ClickTime.

Requirements

ruby-clicktime uses Savon, so be sure to install that first:

$ gem install savon

Usage

The ClickTime class has two methods:

ClickTime#actions will return a list of all actions available to the ClickTime SOAP API

clicktime.actions  # un_sync_all, get_sync_id, set_sync_id, ...

ClickTime#exec will execute an API call and return a hash of results

clicktime.exec :api_action, {params}

Example

First, create an instance of the ClickTime class:

require 'clicktime'

clicktime = ClickTime.new :key => 'api-key', :password => 'password'

The GetEmployeeList and GetClientList API methods, as defined in the ClickTime API docs:

<GetEmployeeList xmlns="http://clicktime.com/webservices/2.2/">
	<UserID>string</UserID>
	<ActiveOnly>boolean</ActiveOnly>
</GetEmployeeList>

<GetClientList xmlns="http://clicktime.com/webservices/2.2/">
	<UserID>string</UserID>
</GetClientList>

To execute these queries, you would call the following:

employees = clicktime.exec :get_employee_list,
    {"UserID" => 'your-user-id', "ActiveOnly" => 'true'}
clients = clicktime.exec :get_client_list, {"UserID" => 'your-user-id'}

Notice the action is passed as a snake_case symbol from the list of available actions. (clicktime.actions to list them)

JavaScript

The JavaScript wrapper is a CommonJS module, ready for use in your Node.js project via npm.

Installation

In your project:

$ npm install clicktime

And in your script:

var ClickTime = require('clicktime');

Example

First, create an instance of the ClickTime object:

var clicktime = new ClickTime({
  key: 'your-api-key',
  password: 'your-api-password'
});

The GetEmployeeList API method, as defined in the ClickTime API docs:

<GetEmployeeList xmlns="http://clicktime.com/webservices/2.2/">
  <UserID>string</UserID>
  <ActiveOnly>boolean</ActiveOnly>
</GetEmployeeList>

To execute this query you would call the following:

clicktime.exec('GetEmployeeList', {
    UserID: 'some-user-id',
    ActiveOnly: true
  }, function(response){ // your callback function
    console.log(response);
  }
);

Reference

Source code:
ruby-clicktime on GitHub
node-clicktime on GitHub

ClickTime SOAP API Documentation:
http://app.clicktime.com/documentation/webservices/2_2/WebServicesDocumentation_2_2.asp

Jun18

CoffeeScript: Namespaces, Modules and Inheritance

First, some JavaScript background.

Skip to the good stuff

Here at Imulus, we like to namespace our JavaScript by wrapping our classes in static modules. We accomplish this by simply creating an object literal with a variety of members: classes (constructors), constants, variables and static methods.

Here is a pared down example of a simple module:

var Application = {           // the module, a static wrapper

 FXSPEED : 500,               // a constant (sort of)

 user : {                     // a nested static object
   id : 123
 },

 toggle : function(){ ... },  // a static method

 Interface : function(){      // a class

   this.initialize = function(){
     this.active = true;
     this.build();
     return this;
   }

   this.build = function(){
     ...
   }

   this.doSomething = function(){
     return "did something";
   }

   return this.initialize();
 }  

}

The benefits of this technique are obvious; it allows us to have loosely-coupled, modular code that is nicely organized, available without instantiation and protects the global namespace from pollution.

Application.active // true

Application.user.id // 123

var interface = new Application.Interface()
interface.doSomething() // 'did something'

In reality, however, one mammoth object literal in a single file is a lousy way to structure your code. Instead, what we do is organize module members into separate files in a logical fashion, å la Ruby. The module and all of its static members exist in a single file named after the module, and all of the module’s classes exist in a directory named after the module with each class file named after itself without the namespace. By using this structure, files are much easier to find because the naming convention mirrors the the module namespace.

The directory structure ends up looking like this:

|-- scripts
    |-- application.js
    |-- application
        |-- controller.js
        |-- data.js
        |-- interface.js

And the module above would be structured like this:

// scripts/application.js
// creates the wrapper module and contains all static members

var Application = Application || {
  FXSPEED : 500,
  user : {
    id : 123
  },
 toggle : function(){ ... },
}
// scripts/application/interface.js

Application.Interface = function(){
  this.initialize = function(){
    this.active = true;
    this.build();
    return this;
  }

  this.build = function(){
    ...
  }

  this.doSomething = function(){
    return "did something";
  }

  return this.initialize();
}
// scripts/application/controller.js

Application.Controller = function(){
  ...
}

You get the picture. This probably looks familiar to a Rubyist. Here’s the analog:

|-- lib
    |-- application.rb
    |-- application
        |-- interface.rb
# application.rb

module Application
 FXSPEED : 500,             

 def self.user
  { 'id' => 123 }
 end

 def self.toggle
  ...
 end
end
# application/interface.rb

module Application
  class Interface

    attr_accessor :active

    def initialize
      @active = true
      build
    end

    def build
      ...
    end

    def do_something
      'did something'
    end
  end
end

Snakes on a Train

By now it’s probably evident how much we obsess over code structure, organization and namespacing. While experimenting with CoffeeScript, this has been an ongoing concern.

This is the example from the CoffeeScript demo page:

class Animal
  constructor: (@name) ->

  move: (meters) ->
    alert @name + " moved " + meters + "m."

class Snake extends Animal
  move: ->
    alert "Slithering..."
    super 5

class Horse extends Animal
  move: ->
    alert "Galloping..."
    super 45

sam = new Snake "Sammy the Python"
tom = new Horse "Tommy the Palomino"

sam.move()
tom.move()

I love that Coffee has made dealing with prototypes much easier with the ‘class’ and ‘extends’ keywords. This is great, and by itself works like a charm for singular, somewhat global classes. However, for any application with a sizeable codebase this simply isn’t practical without ending up with insane class names.

The ideal solution would be to introduce a ‘module’ keyword similar to Ruby’s.

module Zoo
  class Animal
    constructor: (@name) ->

    move: (meters) ->
      alert @name + " moved " + meters + "m."

bob = new Zoo::Animal "Bob the Bird"
bob.move()

Other people agree. But there are a number of JS limitations that prevent this from being a viable solution in CoffeeScript.

The Really Good Stuff

By its own golden rule, CoffeeScript is: “It’s just JavaScript”. So, we can namespace our CoffeeScript classes in the same manner we organize our modules in vanilla JS.

Extending on the example above (ha-ha, get it?), I’ll demonstrate how to namespace your Coffee classes in a simple, elegant way.

Focusing only on the snakes for now, lets set up our basic classes.

class Animal
  constructor: (@name) ->

  move: (meters) ->
    console.log @name + " moved " + meters + "m."

class Snake extends Animal
  move: ->
    super 5

george = new Snake "George"
george.move() // George moved 5m

Now, we want to create ‘Forest’ and ‘Savanna’ modules that have a habitat and snakes of their own.

animal-diagram

Just like JavaScript, we could wrap all of the module members in an object literal:

Forest =
  habitat: "dense highland dotted with lakes and streams"
  Snake: class extends Snake
    move: ->
      super 10

george = new Forest.Snake "George"
george.move() // George moved 5m.

But we would run into the same problem when the codebase reaches any kind of scale: enormous, single-file object literals. So let’s introduce a new function for creating module members.

module = (name) ->
  global[name] = global[name] or {}

(Yes, I am aware that this is attaching the objects to the global namespace. This is what we want. It allows us to add members to the module later.)

Now we can use the ‘module’ function like this:

module 'Forest'

Forest.habitat = "dense highland dotted with lakes and streams"

Forest.Snake = class extends Snake
 move: ->
   super 10

george = new Forest.Snake "George"
george.move() // George moved 10m.

Pretty elegant, right? Additionally, by using the ‘module’ function we can now organize our code into multiple files:

module = (name) ->
  global[name] = global[name] or {}

# src/animals.coffee
class Animal
  constructor: (@name) ->

  move: (meters) ->
    console.log @name + " moved " + meters + "m."

class Snake extends Animal
  move: (meters) ->
    super meters

# src/forest/snake.coffee
module 'Forest'

Forest.habitat = "dense highland dotted with lakes and streams"

Forest.Snake = class extends Snake
  move: (meters)->
    @distance = meters || 5
    super @distance

# src/savanna/snake.coffee
module 'Savanna'

Savanna.habitat = "grassy woodland small or widely spaced trees"

Savanna.Snake = class extends Snake
  move: (meters)->
    @distance = meters || 10
    super @distance

george = new Forest.Snake "George"
george.move() // George moved 5m

scott = new Savanna.Snake "Scott"
scott.move() // Scott moved 10m

We can also extend standalone classes with module classes:

class Python extends Savanna.Snake
  constructor: ->
    super
    console.log "I am #{@name} the python."
    console.log "I live in the savanna,
    where it is #{Savanna.habitat}."

class Cobra extends Forest.Snake
  constructor: ->
    super
    console.log "I am #{@name} the cobra."
    console.log "I live in the Forest,
      where it is #{Forest.habitat}."

john = new Python "John"
// I am John the python.
// I live in the savanna,
// where it is grassy woodland small or widely spaced trees.

bruce = new Cobra "Bruce"
// I am Bruce the cobra.
// I live in the forest,
// where it is dense highland dotted with lakes and streams.

Jun13

Using AddThis widget in XSLT and Umbraco

addThisA frequent request now days is to provide social service integration into a website, especially one full of blog or article posts. There are a couple of pre-packaged services to help accomplish this. For instance, AddThis and ShareThis both provide a nice listing of social media sites and allow the user to quickly post the article they’re looking at.

My personal choice between the two services is AddThis as the setup and integration is easy. Now, while AddThis provides great out-of-the box support for single page social posts a listing of posts each with they’re own unique AddThis button is a bit harder to do. Here’s a quick example of the situation.

You have a page of 10 blog posts, each one needs its own AddThis button and when clicked that button needs to provide the unique Title and URL of that specific post. Therefore, you have to add a bit of hullabaloo to the AddThis div.

Instead of the standard code after each post:
<div class="addthis_toolbox addthis_default_style ">

You need this:
<div class="addthis_toolbox addthis_default_style " addthis:title="THE TITLE HERE" addthis:url="http://URLHERE.com">

After adding this each will have the ability to target a dedicated Title and URL even if there are multiple instances of AddThis code on a page.

The tricky part comes when you need to put this code into an XSLT script. For example, XSLT is Umbraco’s main source of generating macros and in this instance we’ll use it to output the above code (with a unique Title and URL) for each blog post. In most languages this wouldn’t be an issue but because of XSLT’s strict interpretation it won’t allow the usage of addthis:title and addthis:url.

The answer is fairly simple but not immediately obvious (at least not to me, or people answering this question when I googled it). We simply need to parse out the bulk of the AddThis code as standard XSLT text, leaving only the variables Title and URL as true XSLT:

<xsl:text disable-output-escaping="yes"><![CDATA[
<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style" addthis:title="]]></xsl:text>
    <xsl:value-of select="@nodeName"/>
<xsl:text disable-output-escaping="yes"><![CDATA[" addthis:url="http://solidfire.com]]></xsl:text>
    <xsl:value-of select="umbraco.library:NiceUrl(@id)"/>
<xsl:text disable-output-escaping="yes"><![CDATA[">
<a href="http://www.addthis.com/bookmark.php?v=#####" class="addthis_button_compact">Share</a>
</div>
<!-- AddThis Button END -->
]]></xsl:text>

In the above example you could remove the <xslt:value-of select="@nodeName"/> and replace it with whatever XSLT call you need to pull the unique title of that post. The example provided is simply the usage that works with Umbraco 4.5+

Apr15

Who is Imulus? Interview with Casey O’Hara: Front-End Developer

Rollover OriginalTell us about yourself. Why did you want to be a front end developer at Imulus?
Casey Patrick O'Hara. Yes, I'm Irish. I'm originally from New Hampshire, so I'm culturally predisposed to using New England jargon, not paying sales tax or wearing a seat belt, and Tom Brady fandom. For reasons I'm still not sure of, when I graduated high school I decided to move to the frozen, wind-swept plains of Ohio to go to school. In December I graduated from Bowling Green State University with a degree in Visual Communication Technology. During my academic novitiate, I fell in love with web design and development. I've slowly moved away from design and now I focus more on the programming side of things.

Finding Imulus was pure kismet. I interviewed with Bruce and Taylor a few months before I graduated and we totally hit it off. It seemed like a perfect fit doing exactly what I love. I knew I wanted to live in Colorado, so the move was a no-brainer.

Your nickname is "The Prototype." How did you come about this nickname?
At my first Imulus team meeting, George polled the room "Who is our best JavaScript programmer?" I patiently waited for someone else to answer, but I couldn't keep my love affair a secret; I involuntarily shouted "I kick ass." Apparently they didn't know how much I love JavaScript when I was hired, and it quickly became a joke I probably won't live down any time soon.

If Javascript was a woman, what would she look like? Don't be afraid to get a little PG-13.
Courtney Love. Battered, sloppy, and drunk enough to be dangerous. If you look past the puke on her dress, it’s easy to see a few gems in there. Once in a while she will spit in your face, but you know she didn’t mean it because deep down she’s probably a nice person.

What about your job do you like the most?
I like that Imulus moves so fast. At times it can be equally exciting and terrifying, but it’s rewarding to work on a team of super-smart, super-talented people with an “Okay, build it” philosophy because it affords us the freedom to explore and experiment with new technologies. Research and learning are not only encouraged but required. This means our workflow and development processes are constantly evolving and never stagnate.

Least?
We’re often so busy building awesome stuff that it can be hard to find time to just stop and reflect on how awesome what we’re building actually is. Does that make sense?

Do you live free or die?
Yes.

Would you rather be a pirate or a dinosaur?
Definitely a pirate. As a pirate, it's professionally acceptable to get drunk and steal things every day. Plus, I've always wanted a cannon.

What do you like best about Colorado?
I've been here for a few months now and I'm still blown away by the landscape. I love driving up into the mountains aimlessly without a map or cell signal. I totally get off on that. The tech scene and entrepreneurial culture in Denver (and Boulder) is awesome. The weather and people are nice too. I still haven't been to Casa Bonita.

If you could have a dinner with anyone in the world or throughout history, who would you dine with?
I'd love to go out drinking with Charlie Sheen. Just once.

Describe the color blue to a blind person.
I fell for this trick once, except I was trying to describe what a square looks like. Before I got past explaining what a right angle is, I realized that my new blind friend had a saddle on his safety dog. I got too distracted imagining him riding the dog around his house that I never finished describing the square.

Dec30

Live Comparison of Website Stat Packages (Part 2 of 3)

The web analytic data is in, finally. In a continuation of the last post I’ve gathered the high-level results. I looked at Woopra, Reinvigorate, Quantcast and Google Analytics and here is the 5280 foot view looking at the results between October 1st, 2010 and November 30th, 2010.

  Visitors Unique Visitors Page Views Referrals
Google Analytics
*Visitors, Unique Visitors, Page Views, Visits Referrals
4,299 3,422 16,231 3,325

Woopra
*Visits, Visitors, Page Views, Visitors Referrals

5,342 4,322 16,219 2,666
Reinvigorate
*Visitors, NA, Page Views, NA
4,196 NA 16,529 NA

Quantcast
*
Global Visits, NA, Global Page Views, NA

10,750 NA 27,173 NA

I was surprised to see how similar the Page Views worked out, despite the variation in Visitors. I was disappointed that I couldn’t grab a range of date values out of Reinvigorate which explains the NA. Now that I’ve shared the high-level, please go ahead and dig deeper if you’d like. Here is the shared data for the 4 accounts for the month of December 2010.

In the next post I’ll follow-up with pros & cons on the 4 systems I’ve looked at.